Compare commits
143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64040f0407 | ||
|
|
0c1abdd507 | ||
|
|
53594e3343 | ||
|
|
c6c06b87c5 | ||
|
|
ae6eb5d72d | ||
|
|
bbce53fdf4 | ||
|
|
fdd7e60c1d | ||
|
|
3b9a489d5c | ||
|
|
de40ccb759 | ||
|
|
a04d584402 | ||
|
|
a14a6a798b | ||
|
|
636d329dba | ||
|
|
d1e97dac57 | ||
|
|
41fbca8f65 | ||
|
|
535b48e5b4 | ||
|
|
d3e8d35e5d | ||
|
|
da8073141e | ||
|
|
030665732a | ||
|
|
cc042dd77c | ||
|
|
773624769d | ||
|
|
0b1d0c74fe | ||
|
|
760d307478 | ||
|
|
084c2abfc2 | ||
|
|
df6b08024f | ||
|
|
25498695ef | ||
|
|
5c81179d60 | ||
|
|
58d150bb03 | ||
|
|
2b1951ea5f | ||
|
|
5a5089c413 | ||
|
|
dcd20e4b73 | ||
|
|
dfec1f3804 | ||
|
|
1fffe7f6e5 | ||
|
|
862a6cc82a | ||
|
|
068caaf09b | ||
|
|
93fb6d6016 | ||
|
|
28f0657bd7 | ||
|
|
8c53c2a057 | ||
|
|
6251fb2ef6 | ||
|
|
cba2b873b8 | ||
|
|
d7ee61f316 | ||
|
|
cf309f43a4 | ||
|
|
93acee778e | ||
|
|
c7f2f31c99 | ||
|
|
ebb8837d8a | ||
|
|
f04f185034 | ||
|
|
20de007d3b | ||
|
|
df01f6fe57 | ||
|
|
f9e6d7b09c | ||
|
|
f8000d999f | ||
|
|
0392d1a7f1 | ||
|
|
0be1f4beb9 | ||
|
|
87bba56a80 | ||
|
|
e5154533ae | ||
|
|
fd00c2fa4c | ||
|
|
3de07c30c6 | ||
|
|
0a84c78740 | ||
|
|
7f3f7a015b | ||
|
|
2899bd9234 | ||
|
|
90162b2eb5 | ||
|
|
a028abda65 | ||
|
|
b7ed99ab7f | ||
|
|
19bb15d006 | ||
|
|
4a005c6a3a | ||
|
|
be6f7bcfc8 | ||
|
|
84b827d652 | ||
|
|
dd12de7b88 | ||
|
|
8641892b46 | ||
|
|
ff109714f9 | ||
|
|
589f709fa2 | ||
|
|
920b2363d4 | ||
|
|
2aa245ca1a | ||
|
|
8305b9ac27 | ||
|
|
b774a66b0c | ||
|
|
4d35245fe8 | ||
|
|
3f24913762 | ||
|
|
a0fd62ad45 | ||
|
|
efd5e62703 | ||
|
|
c481a59e24 | ||
|
|
9f5eba3275 | ||
|
|
3f0d3131aa | ||
|
|
9d360f80c3 | ||
|
|
1d1a070b2b | ||
|
|
ebe0e43641 | ||
|
|
b99142d009 | ||
|
|
8077c440be | ||
|
|
64024101ba | ||
|
|
37a9445a64 | ||
|
|
33630d6893 | ||
|
|
242c21ce59 | ||
|
|
859d6dcde3 | ||
|
|
9df9b8d752 | ||
|
|
a64d61c9b5 | ||
|
|
128faba755 | ||
|
|
95c23dc344 | ||
|
|
c863d87724 | ||
|
|
56878d06ca | ||
|
|
c21b1806b6 | ||
|
|
34d9495e66 | ||
|
|
32e822fa10 | ||
|
|
5f9184f09d | ||
|
|
4b4d0895ae | ||
|
|
4c97a86de8 | ||
|
|
6f23d6544c | ||
|
|
304e1a0d46 | ||
|
|
1e4b9ad86a | ||
|
|
1ba0f7c7c0 | ||
|
|
0eb35c5edc | ||
|
|
a6970eba81 | ||
|
|
fac7dde5f3 | ||
|
|
e9ef11f2fb | ||
|
|
068768fc05 | ||
|
|
a00e9e1a68 | ||
|
|
22a3b07fe5 | ||
|
|
27959b7d29 | ||
|
|
b8e49674bb | ||
|
|
5a1d277dc6 | ||
|
|
2534601116 | ||
|
|
5426a0e5fb | ||
|
|
41e91410e7 | ||
|
|
3be3be8e9d | ||
|
|
1e7deebd23 | ||
|
|
a3aef0de31 | ||
|
|
8933a03c3b | ||
|
|
a8df9892c2 | ||
|
|
6414f94bd0 | ||
|
|
7fb4c9ba00 | ||
|
|
a7fe421661 | ||
|
|
4cecbc4d5e | ||
|
|
829fcbf468 | ||
|
|
00d0f778d2 | ||
|
|
22c35b7e99 | ||
|
|
87fa236d1e | ||
|
|
158f2d33ae | ||
|
|
e55be5ca03 | ||
|
|
b3413535f7 | ||
|
|
21cabe1d92 | ||
|
|
c6a30b1905 | ||
|
|
9fa702fde7 | ||
|
|
9bd2b80949 | ||
|
|
0e91003a68 | ||
|
|
e42f69cc2e | ||
|
|
f6045a5c4f | ||
|
|
d3240c9db5 |
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -8,30 +8,27 @@ assignees: ''
|
||||
---
|
||||
|
||||
<!--
|
||||
- Describe the bug in a short but concise way.
|
||||
- If you have a screenshot or screen recording of the bug, link them at
|
||||
the end of this issue.
|
||||
- Please search existing bug reports to avoid creating duplicates.
|
||||
- Thank you for your help in making FlorisBoard better!
|
||||
Thank you for your help in making FlorisBoard better!
|
||||
|
||||
Guide to a good bug-report:
|
||||
• Please search existing bug/crash reports reports to avoid creating duplicates.
|
||||
• Give your bug report a good name (no generics like "Error" or "Crash"), so others can easily identify the topic of your issue.
|
||||
• Describe the bug in a short but concise way.
|
||||
• If you have a screenshot or screen recording of the bug, link them at the end of this issue.
|
||||
• Also make sure to fill out the environment information. This info is valuable when trying to fix your described bug.
|
||||
-->
|
||||
|
||||
#### Short description
|
||||
Describe the bug in a short but concise way.
|
||||
|
||||
#### Steps to reproduce
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
1. Go to '…'
|
||||
2. Click on '…'
|
||||
3. Scroll down to '…'
|
||||
4. See error
|
||||
|
||||
#### Environment information
|
||||
- FlorisBoard Version: <!-- e.g. 0.3.6 -->
|
||||
- FlorisBoard Version: <!-- e.g. 0.X.X -->
|
||||
- Install Source: <!-- Google PlayStore/F-Droid/GitHub/? -->
|
||||
- Device: <!-- e.g. OnePlus 7T -->
|
||||
- Android version, ROM: <!-- e.g. 10, Stock -->
|
||||
|
||||
<!-- (remove this line if you paste a log)
|
||||
```
|
||||
If applicable, paste the captured debug log here.
|
||||
```
|
||||
(remove this line if you paste a log) -->
|
||||
- Android: <!-- e.g. 10, Stock -->
|
||||
|
||||
28
.github/ISSUE_TEMPLATE/crash_report.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/crash_report.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: Crash report
|
||||
about: Create a report with a generated crash log attached to help FlorisBoard improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Thank you for your help in making FlorisBoard better!
|
||||
|
||||
Guide to a good crash-report:
|
||||
• Please search existing bug/crash reports to avoid creating duplicates.
|
||||
• Give your crash report a good name (no generics like "Error" or "Crash"), so others can easily identify the topic of your issue.
|
||||
• Describe what you were doing what could've led to the crash and whether the crash is random or reproducible.
|
||||
-->
|
||||
|
||||
#### Short description
|
||||
Describe what you were doing that could've led to the crash.
|
||||
|
||||
#### Steps to reproduce
|
||||
1. Go to '…'
|
||||
2. Click on '…'
|
||||
3. Scroll down to '…'
|
||||
4. See crash
|
||||
|
||||
<!-- Paste the generated crash log below -->
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -39,4 +39,7 @@ captures/
|
||||
|
||||
# Keystore files
|
||||
*.jks
|
||||
crowdin.properties
|
||||
crowdin.properties
|
||||
|
||||
# AndroidX Room schema JSONs
|
||||
/app/schemas/
|
||||
|
||||
29
README.md
29
README.md
@@ -1,7 +1,7 @@
|
||||
<img align="left" width="80" height="80"
|
||||
src="fastlane/metadata/android/en-US/images/icon.png" alt="App icon">
|
||||
|
||||
# FlorisBoard [](https://crowdin.florisboard.patrickgold.dev) 
|
||||
# FlorisBoard [](https://crowdin.florisboard.patrickgold.dev) [](https://matrix.to/#/#florisboard:matrix.org) 
|
||||
|
||||
**FlorisBoard** is a free and open-source keyboard for Android 6.0+
|
||||
devices. It aims at being modern, user-friendly and customizable while
|
||||
@@ -74,8 +74,8 @@ milestones, please refer to the [Feature roadmap](#feature-roadmap).
|
||||
|
||||
### Layouts
|
||||
* [x] Latin character layouts (QWERTY, QWERTZ, AZERTY, Swiss, Spanish, Norwegian, Swedish/Finnish, Icelandic, Danish,
|
||||
Hungarian, Croatian, Polish, Romanian, Colemak, Dvorak, Turkish-Q, Turkish-F, ...)
|
||||
* [x] Non-latin character layouts (Arabic, Persian, Kurdish, Greek, Russian (JCUKEN))
|
||||
Hungarian, Croatian, Polish, Romanian, Colemak, Dvorak, Turkish-Q, Turkish-F, and more...)
|
||||
* [x] Non-latin character layouts (Arabic, Persian, Kurdish, Greek, Russian (JCUKEN), and more...)
|
||||
* [x] Adapt to situation in app (password, url, text, etc. )
|
||||
* [x] Special character layout(s)
|
||||
* [x] Numeric layout
|
||||
@@ -93,6 +93,7 @@ milestones, please refer to the [Feature roadmap](#feature-roadmap).
|
||||
* [x] Subtype selection (language/layout)
|
||||
* [x] Keyboard behaviour preferences
|
||||
* [x] Gesture preferences
|
||||
* [x] User dictionary manager (system and internal)
|
||||
|
||||
### Other useful features
|
||||
* [x] One-handed mode
|
||||
@@ -100,6 +101,8 @@ milestones, please refer to the [Feature roadmap](#feature-roadmap).
|
||||
* [x] Clipboard manager/history
|
||||
* [x] Integrated number row / symbols in character layouts
|
||||
* [x] Gesture support
|
||||
* [x] Full support for the system user dictionary (shared dictionary
|
||||
between all keyboards) and a private, internal user dictionary
|
||||
* [x] Full integration in IME service list of Android (xml/method)
|
||||
(integration is internal-only, because Android's default subtype
|
||||
implementation not really allows for dynamic language/layout
|
||||
@@ -131,13 +134,14 @@ close as possible.
|
||||
- Next-word suggestions by training language models. Data collected here is stored locally and never leaves
|
||||
the user's device.
|
||||
|
||||
- Module C: Extension packs (base implementation with [#162])
|
||||
- Module C: Extension packs (Implemented with [#162], reworked several times and still not stable)
|
||||
- Ability to load dictionaries (and later potentially other cool
|
||||
features too) only if needed to keep the core APK size small
|
||||
- Currently unclear how exactly this will work, but this is definitely
|
||||
a must-have feature
|
||||
- A full implementation may come only in v0.5.0
|
||||
|
||||
- Module D: Glide typing
|
||||
- Module D: Glide typing (Implemented with [#544])
|
||||
- Swiping over the characters will automatically convert this to a word
|
||||
- Possibly also add improvements based on the Flow keyboard
|
||||
|
||||
@@ -151,9 +155,11 @@ close as possible.
|
||||
- Theme import/export
|
||||
|
||||
### [v0.5.0](https://github.com/florisboard/florisboard/milestone/5)
|
||||
There's no exact roadmap yet but it is planned that the media part of
|
||||
FlorisBoard (emojis, emoticons, kaomoji) gets a rework. Also as an extension
|
||||
(requires v0.4.0/Module C) GIF support is planned.
|
||||
There's no exact roadmap yet, but these are the most important points:
|
||||
- Full layout customization in runtime
|
||||
- Extensive rework and customization of the media input (emojis, emoticons, kaomoji)
|
||||
- Better Smartbar customization
|
||||
- As an extension GIF support
|
||||
|
||||
### > v0.5.0
|
||||
This is completely open as of now and will gather planned features as time
|
||||
@@ -166,6 +172,7 @@ Backlog (currently not assigned to any milestone):
|
||||
[#91]: https://github.com/florisboard/florisboard/pull/91
|
||||
[#162]: https://github.com/florisboard/florisboard/pull/162
|
||||
[#329]: https://github.com/florisboard/florisboard/pull/329
|
||||
[#544]: https://github.com/florisboard/florisboard/pull/544
|
||||
|
||||
## Contributing
|
||||
Wanna contribute to FlorisBoard? That's great to hear! There are lots of
|
||||
@@ -183,8 +190,8 @@ to get more information on this topic.
|
||||
by [google](https://github.com/google)
|
||||
* [Google Material icons](https://github.com/google/material-design-icons) by
|
||||
[google](https://github.com/google)
|
||||
* [Moshi JSON library](https://github.com/square/moshi) by
|
||||
[square](https://github.com/square)
|
||||
* [KotlinX serialization library](https://github.com/Kotlin/kotlinx.serialization) by
|
||||
[Kotlin](https://github.com/Kotlin)
|
||||
* [ColorPicker preference](https://github.com/jaredrummler/ColorPicker) by
|
||||
[Jared Rummler](https://github.com/jaredrummler)
|
||||
* [Timber](https://github.com/JakeWharton/timber) by
|
||||
@@ -194,7 +201,7 @@ to get more information on this topic.
|
||||
|
||||
## Usage notes for included binary dictionary files
|
||||
All binary dictionaries included within this project in
|
||||
(this)[app/src/main/assets/ime/dict) asset folder are built from various
|
||||
(this)[app/src/main/assets/ime/dict] asset folder are built from various
|
||||
sources, as stated below.
|
||||
|
||||
### Source 1: [wordfreq library by LuminosoInsight](https://github.com/LuminosoInsight/wordfreq):
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
plugins {
|
||||
id("com.android.application") version "4.1.2"
|
||||
kotlin("android") version "1.4.30"
|
||||
kotlin("kapt") version "1.4.30"
|
||||
id("com.android.application") version "4.2.0"
|
||||
kotlin("android") version "1.5.0"
|
||||
kotlin("kapt") version "1.5.0"
|
||||
kotlin("plugin.serialization") version "1.5.0"
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -16,17 +17,27 @@ android {
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
freeCompilerArgs = listOf("-Xallow-result-return-type") // enables use of kotlin.Result
|
||||
freeCompilerArgs = listOf("-Xallow-result-return-type", "-Xopt-in=kotlin.RequiresOptIn")
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "dev.patrickgold.florisboard"
|
||||
minSdkVersion(23)
|
||||
targetSdkVersion(30)
|
||||
versionCode(35)
|
||||
versionName("0.3.10")
|
||||
versionCode(43)
|
||||
versionName("0.3.12")
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments += mapOf(
|
||||
Pair("room.schemaLocation", "$projectDir/schemas"),
|
||||
Pair("room.incremental", "true"),
|
||||
Pair("room.expandProjection", "true")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
@@ -83,11 +94,10 @@ dependencies {
|
||||
implementation("androidx.preference", "preference-ktx", "1.1.1")
|
||||
implementation("androidx.constraintlayout", "constraintlayout", "2.0.4")
|
||||
implementation("androidx.lifecycle", "lifecycle-service", "2.2.0")
|
||||
implementation("com.google.android", "flexbox", "2.0.1") // requires jcenter as of version 2.0.1
|
||||
implementation("com.squareup.moshi", "moshi-kotlin", "1.11.0")
|
||||
implementation("com.squareup.moshi", "moshi-adapters", "1.11.0")
|
||||
implementation("com.google.android", "flexbox", "2.0.1")
|
||||
implementation("com.google.android.material", "material", "1.3.0")
|
||||
implementation("org.jetbrains.kotlinx", "kotlinx-coroutines-android", "1.4.2")
|
||||
implementation("org.jetbrains.kotlinx", "kotlinx-serialization-json", "1.1.0")
|
||||
implementation("com.jaredrummler", "colorpicker", "1.1.0")
|
||||
implementation("com.jakewharton.timber", "timber", "4.7.1")
|
||||
implementation("com.nambimobile.widgets", "expandable-fab", "1.0.2")
|
||||
|
||||
@@ -66,6 +66,13 @@
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<!-- User Dictionary Manager Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.settings.UdmActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__title"
|
||||
android:theme="@style/SettingsTheme"/>
|
||||
|
||||
<!-- Theme Selector Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.settings.ThemeManagerActivity"
|
||||
|
||||
@@ -489,6 +489,14 @@
|
||||
"characters": "jcuken_russian"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1351,
|
||||
"languageTag": "uk",
|
||||
"currencySet": "ukrainian_hryvnia",
|
||||
"preferred": {
|
||||
"characters": "jcuken_ukrainian"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1401,
|
||||
"languageTag": "el",
|
||||
@@ -572,6 +580,14 @@
|
||||
"characters": "kurdish_kurmanci"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2501,
|
||||
"languageTag": "ca",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "catalan"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2601,
|
||||
"languageTag": "IPA-IPA",
|
||||
@@ -581,6 +597,22 @@
|
||||
"symbols": "ipa",
|
||||
"symbols2": "ipa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2701,
|
||||
"languageTag": "sk",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwertz"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2801,
|
||||
"languageTag": "cs",
|
||||
"currencySet": "euro",
|
||||
"preferred": {
|
||||
"characters": "qwertz"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
[
|
||||
{ "code": 1584, "label": "ذ" },
|
||||
{ "code": 1569, "label": "ء" },
|
||||
{ "code": 65157, "label": "ﺅ" },
|
||||
{ "code": 1572, "label": "ؤ" },
|
||||
{ "code": 1585, "label": "ر" },
|
||||
{ "code": 1609, "label": "ى" },
|
||||
{ "code": 1577, "label": "ة" },
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" }
|
||||
],
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
],
|
||||
[
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "code": 39, "label": "'", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 8218, "label": "‚" },
|
||||
|
||||
@@ -6,38 +6,38 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 119, "label": "w" }
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 231, "label": "ç" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
],
|
||||
[
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 113, "label": "q", "popup": {
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 8218, "label": "‚" },
|
||||
{ "code": 8216, "label": "‘" },
|
||||
@@ -46,9 +46,9 @@
|
||||
{ "code": 8250, "label": "›" }
|
||||
]
|
||||
} },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 102, "label": "f" }
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,42 +6,42 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 1099, "label": "ы" },
|
||||
{ "code": 1091, "label": "у" },
|
||||
{ "code": 1077, "label": "е" },
|
||||
{ "code": 1080, "label": "и" },
|
||||
{ "code": 1096, "label": "ш" },
|
||||
{ "code": 1097, "label": "щ" },
|
||||
{ "code": 1082, "label": "к" },
|
||||
{ "code": 1089, "label": "с" },
|
||||
{ "code": 1076, "label": "д" },
|
||||
{ "code": 1079, "label": "з" },
|
||||
{ "code": 1094, "label": "ц" }
|
||||
{ "$": "auto_text_key", "code": 1099, "label": "ы" },
|
||||
{ "$": "auto_text_key", "code": 1091, "label": "у" },
|
||||
{ "$": "auto_text_key", "code": 1077, "label": "е" },
|
||||
{ "$": "auto_text_key", "code": 1080, "label": "и" },
|
||||
{ "$": "auto_text_key", "code": 1096, "label": "ш" },
|
||||
{ "$": "auto_text_key", "code": 1097, "label": "щ" },
|
||||
{ "$": "auto_text_key", "code": 1082, "label": "к" },
|
||||
{ "$": "auto_text_key", "code": 1089, "label": "с" },
|
||||
{ "$": "auto_text_key", "code": 1076, "label": "д" },
|
||||
{ "$": "auto_text_key", "code": 1079, "label": "з" },
|
||||
{ "$": "auto_text_key", "code": 1094, "label": "ц" }
|
||||
],
|
||||
[
|
||||
{ "code": 1100, "label": "ь" },
|
||||
{ "code": 1103, "label": "я" },
|
||||
{ "code": 1072, "label": "а" },
|
||||
{ "code": 1086, "label": "о" },
|
||||
{ "code": 1078, "label": "ж" },
|
||||
{ "code": 1075, "label": "г" },
|
||||
{ "code": 1090, "label": "т" },
|
||||
{ "code": 1085, "label": "н" },
|
||||
{ "code": 1074, "label": "в" },
|
||||
{ "code": 1084, "label": "м" },
|
||||
{ "code": 1095, "label": "ч" }
|
||||
{ "$": "auto_text_key", "code": 1100, "label": "ь" },
|
||||
{ "$": "auto_text_key", "code": 1103, "label": "я" },
|
||||
{ "$": "auto_text_key", "code": 1072, "label": "а" },
|
||||
{ "$": "auto_text_key", "code": 1086, "label": "о" },
|
||||
{ "$": "auto_text_key", "code": 1078, "label": "ж" },
|
||||
{ "$": "auto_text_key", "code": 1075, "label": "г" },
|
||||
{ "$": "auto_text_key", "code": 1090, "label": "т" },
|
||||
{ "$": "auto_text_key", "code": 1085, "label": "н" },
|
||||
{ "$": "auto_text_key", "code": 1074, "label": "в" },
|
||||
{ "$": "auto_text_key", "code": 1084, "label": "м" },
|
||||
{ "$": "auto_text_key", "code": 1095, "label": "ч" }
|
||||
],
|
||||
[
|
||||
{ "code": 1102, "label": "ю" },
|
||||
{ "code": 1081, "label": "й" },
|
||||
{ "code": 1098, "label": "ъ" },
|
||||
{ "code": 1101, "label": "э" },
|
||||
{ "code": 1092, "label": "ф" },
|
||||
{ "code": 1093, "label": "х" },
|
||||
{ "code": 1087, "label": "п" },
|
||||
{ "code": 1088, "label": "р" },
|
||||
{ "code": 1083, "label": "л" },
|
||||
{ "code": 1073, "label": "б" }
|
||||
{ "$": "auto_text_key", "code": 1102, "label": "ю" },
|
||||
{ "$": "auto_text_key", "code": 1081, "label": "й" },
|
||||
{ "$": "auto_text_key", "code": 1098, "label": "ъ" },
|
||||
{ "$": "auto_text_key", "code": 1101, "label": "э" },
|
||||
{ "$": "auto_text_key", "code": 1092, "label": "ф" },
|
||||
{ "$": "auto_text_key", "code": 1093, "label": "х" },
|
||||
{ "$": "auto_text_key", "code": 1087, "label": "п" },
|
||||
{ "$": "auto_text_key", "code": 1088, "label": "р" },
|
||||
{ "$": "auto_text_key", "code": 1083, "label": "л" },
|
||||
{ "$": "auto_text_key", "code": 1073, "label": "б" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,40 +6,40 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 1103, "label": "я" },
|
||||
{ "code": 1074, "label": "в" },
|
||||
{ "code": 1077, "label": "е" },
|
||||
{ "code": 1088, "label": "р" },
|
||||
{ "code": 1090, "label": "т" },
|
||||
{ "code": 1098, "label": "ъ" },
|
||||
{ "code": 1091, "label": "у" },
|
||||
{ "code": 1080, "label": "и" },
|
||||
{ "code": 1086, "label": "о" },
|
||||
{ "code": 1087, "label": "п" },
|
||||
{ "code": 1095, "label": "ч" }
|
||||
{ "$": "auto_text_key", "code": 1103, "label": "я" },
|
||||
{ "$": "auto_text_key", "code": 1074, "label": "в" },
|
||||
{ "$": "auto_text_key", "code": 1077, "label": "е" },
|
||||
{ "$": "auto_text_key", "code": 1088, "label": "р" },
|
||||
{ "$": "auto_text_key", "code": 1090, "label": "т" },
|
||||
{ "$": "auto_text_key", "code": 1098, "label": "ъ" },
|
||||
{ "$": "auto_text_key", "code": 1091, "label": "у" },
|
||||
{ "$": "auto_text_key", "code": 1080, "label": "и" },
|
||||
{ "$": "auto_text_key", "code": 1086, "label": "о" },
|
||||
{ "$": "auto_text_key", "code": 1087, "label": "п" },
|
||||
{ "$": "auto_text_key", "code": 1095, "label": "ч" }
|
||||
],
|
||||
[
|
||||
{ "code": 1072, "label": "а" },
|
||||
{ "code": 1089, "label": "с" },
|
||||
{ "code": 1076, "label": "д" },
|
||||
{ "code": 1092, "label": "ф" },
|
||||
{ "code": 1075, "label": "г" },
|
||||
{ "code": 1093, "label": "х" },
|
||||
{ "code": 1081, "label": "й" },
|
||||
{ "code": 1082, "label": "к" },
|
||||
{ "code": 1083, "label": "л" },
|
||||
{ "code": 1096, "label": "ш" },
|
||||
{ "code": 1097, "label": "щ" }
|
||||
{ "$": "auto_text_key", "code": 1072, "label": "а" },
|
||||
{ "$": "auto_text_key", "code": 1089, "label": "с" },
|
||||
{ "$": "auto_text_key", "code": 1076, "label": "д" },
|
||||
{ "$": "auto_text_key", "code": 1092, "label": "ф" },
|
||||
{ "$": "auto_text_key", "code": 1075, "label": "г" },
|
||||
{ "$": "auto_text_key", "code": 1093, "label": "х" },
|
||||
{ "$": "auto_text_key", "code": 1081, "label": "й" },
|
||||
{ "$": "auto_text_key", "code": 1082, "label": "к" },
|
||||
{ "$": "auto_text_key", "code": 1083, "label": "л" },
|
||||
{ "$": "auto_text_key", "code": 1096, "label": "ш" },
|
||||
{ "$": "auto_text_key", "code": 1097, "label": "щ" }
|
||||
],
|
||||
[
|
||||
{ "code": 1079, "label": "з" },
|
||||
{ "code": 1100, "label": "ь" },
|
||||
{ "code": 1094, "label": "ц" },
|
||||
{ "code": 1078, "label": "ж" },
|
||||
{ "code": 1073, "label": "б" },
|
||||
{ "code": 1085, "label": "н" },
|
||||
{ "code": 1084, "label": "м" },
|
||||
{ "code": 1102, "label": "ю" }
|
||||
{ "$": "auto_text_key", "code": 1079, "label": "з" },
|
||||
{ "$": "auto_text_key", "code": 1100, "label": "ь" },
|
||||
{ "$": "auto_text_key", "code": 1094, "label": "ц" },
|
||||
{ "$": "auto_text_key", "code": 1078, "label": "ж" },
|
||||
{ "$": "auto_text_key", "code": 1073, "label": "б" },
|
||||
{ "$": "auto_text_key", "code": 1085, "label": "н" },
|
||||
{ "$": "auto_text_key", "code": 1084, "label": "м" },
|
||||
{ "$": "auto_text_key", "code": 1102, "label": "ю" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,39 +6,39 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 232, "label": "è" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
42
app/src/main/assets/ime/text/characters/catalan.json
Normal file
42
app/src/main/assets/ime/text/characters/catalan.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "catalan",
|
||||
"label": "Catalan (QWERTY)",
|
||||
"authors": [ "mikelloc" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
44
app/src/main/assets/ime/text/characters/catalan_accents.json
Normal file
44
app/src/main/assets/ime/text/characters/catalan_accents.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "catalan_accents",
|
||||
"label": "Catalan (Accents)",
|
||||
"authors": [ "mikelloc" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 768, "label": "◌̀" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 769, "label": "◌́" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -6,41 +6,48 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 59, "label": ";", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 58, "label": ":" }
|
||||
]
|
||||
}, "shift": { "code": 58, "label": ":" } }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 59, "label": ";", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 58, "label": ":" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 58, "label": ":", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 59, "label": ";" }
|
||||
]
|
||||
} }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,39 +6,39 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 229, "label": "å" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 248, "label": "ø" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,59 +7,78 @@
|
||||
"modifier": "dvorak",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 64, "label": "@", "groupId": 101, "variation": "email_address" },
|
||||
{ "code": 39, "label": "'", "groupId": 101, "variation": "normal", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 34, "label": "\"" }
|
||||
]
|
||||
}, "shift": { "code": 34, "label": "\"" } },
|
||||
{ "code": 39, "label": "'", "groupId": 101, "variation": "password", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 34, "label": "\"" }
|
||||
]
|
||||
}, "shift": { "code": 34, "label": "\"" } },
|
||||
{ "code": 47, "label": "/", "groupId": 101, "variation": "uri" },
|
||||
{ "code": 44, "label": ",", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 60, "label": "<" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}, "shift": { "code": 60, "label": "<" } },
|
||||
{ "code": 46, "label": ".", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 62, "label": ">" }
|
||||
]
|
||||
}, "shift": { "code": 62, "label": ">" } },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 108, "label": "l" }
|
||||
{ "$": "variation_selector",
|
||||
"default": { "$": "case_selector",
|
||||
"lower": { "code": 39, "label": "'", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 34, "label": "\"" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 34, "label": "\"", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 39, "label": "'"}
|
||||
]
|
||||
} }
|
||||
},
|
||||
"email": { "code": 64, "label": "@" },
|
||||
"uri": { "code": 47, "label": "/" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 44, "label": ",", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 60, "label": "<" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 60, "label": "<", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 44, "label": "," },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 46, "label": ".", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 62, "label": ">" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 62, "label": ">", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 46, "label": "." }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 115, "label": "s" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" }
|
||||
],
|
||||
[
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 118, "label": "v" }
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,45 +6,45 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 349, "label": "ŝ", "popup": {
|
||||
"main": { "code": 113, "label": "q" }
|
||||
{ "$": "auto_text_key", "code": 349, "label": "ŝ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 113, "label": "q" }
|
||||
} },
|
||||
{ "code": 285, "label": "ĝ", "popup": {
|
||||
"main": { "code": 119, "label": "w" }
|
||||
{ "$": "auto_text_key", "code": 285, "label": "ĝ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 119, "label": "w" }
|
||||
} },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 365, "label": "ŭ", "popup": {
|
||||
"main": { "code": 121, "label": "y" }
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 365, "label": "ŭ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 121, "label": "y" }
|
||||
} },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" }
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 309, "label": "ĵ" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 309, "label": "ĵ" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 265, "label": "ĉ", "popup": {
|
||||
"main": { "code": 120, "label": "x" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 265, "label": "ĉ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 120, "label": "x" }
|
||||
} },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,46 +6,46 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 349, "label": "ŝ", "popup": {
|
||||
"main": { "code": 113, "label": "q" }
|
||||
{ "$": "auto_text_key", "code": 349, "label": "ŝ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 113, "label": "q" }
|
||||
} },
|
||||
{ "code": 285, "label": "ĝ", "popup": {
|
||||
"main": { "code": 119, "label": "w" }
|
||||
{ "$": "auto_text_key", "code": 285, "label": "ĝ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 119, "label": "w" }
|
||||
} },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 365, "label": "ŭ", "popup": {
|
||||
"main": { "code": 121, "label": "y" }
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 365, "label": "ŭ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 121, "label": "y" }
|
||||
} },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" }
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 309, "label": "ĵ" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 309, "label": "ĵ" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 265, "label": "ĉ", "popup": {
|
||||
"main": { "code": 120, "label": "x" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 265, "label": "ĉ", "popup": {
|
||||
"main": { "$": "auto_text_key", "code": 120, "label": "x" }
|
||||
} },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 293, "label": "ĥ" }
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 293, "label": "ĥ" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"all": {
|
||||
"и": {
|
||||
"relevant": [
|
||||
{ "code": 1117, "label": "ѝ" }
|
||||
{ "$": "auto_text_key", "code": 1117, "label": "ѝ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
115
app/src/main/assets/ime/text/characters/extended_popups/ca.json
Normal file
115
app/src/main/assets/ime/text/characters/extended_popups/ca.json
Normal file
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "ca",
|
||||
"authors": [ "mikelloc" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 261, "label": "ą" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 170, "label": "ª" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"main": { "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"main": { "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"main": { "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 320, "label": "ŀ" },
|
||||
{ "$": "auto_text_key", "code": 183, "label": "·" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 186, "label": "º" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".cat" },
|
||||
{ "code": -255, "label": ".es" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
115
app/src/main/assets/ime/text/characters/extended_popups/cs.json
Normal file
115
app/src/main/assets/ime/text/characters/extended_popups/cs.json
Normal file
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "cs",
|
||||
"authors": [ "stefan-misik" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 283, "label": "ě" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" }
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 345, "label": "ř" },
|
||||
{ "$": "auto_text_key", "code": 341, "label": "ŕ" }
|
||||
]
|
||||
},
|
||||
"t": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 357, "label": "ť" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 367, "label": "ů" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" }
|
||||
]
|
||||
},
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 271, "label": "ď" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 318, "label": "ľ" },
|
||||
{ "$": "auto_text_key", "code": 314, "label": "ĺ" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 328, "label": "ň" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".cz" },
|
||||
{ "code": -255, "label": ".eu" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,95 +6,95 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"relevant": [
|
||||
{ "code": 240, "label": "ð" }
|
||||
{ "$": "auto_text_key", "code": 240, "label": "ð" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 234, "label": "ê" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "code": 322, "label": "ł" }
|
||||
{ "$": "auto_text_key", "code": 322, "label": "ł" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 223, "label": "ß" },
|
||||
{ "code": 347, "label": "ś" },
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 249, "label": "ù" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 253, "label": "ý" },
|
||||
{ "code": 255, "label": "ÿ" }
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" },
|
||||
{ "$": "auto_text_key", "code": 255, "label": "ÿ" }
|
||||
]
|
||||
},
|
||||
"æ": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"ø": {
|
||||
"relevant": [
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -5,72 +5,72 @@
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "code": 228, "label": "ä" },
|
||||
"main": { "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
"relevant": [
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 225, "label": "á" }
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" }
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 239, "label": "ï" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 299, "label": "ī" }
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "code": 246, "label": "ö" },
|
||||
"main": { "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
"relevant": [
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" }
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"main": { "code": 223, "label": "ß" },
|
||||
"main": { "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
"relevant": [
|
||||
{ "code": 353, "label": "š" },
|
||||
{ "code": 347, "label": "ś" }
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" },
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "code": 252, "label": "ü" },
|
||||
"main": { "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 250, "label": "ú" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,41 +6,41 @@
|
||||
"all": {
|
||||
"α": {
|
||||
"relevant": [
|
||||
{ "code": 940, "label": "ά" }
|
||||
{ "$": "auto_text_key", "code": 940, "label": "ά" }
|
||||
]
|
||||
},
|
||||
"ε": {
|
||||
"relevant": [
|
||||
{ "code": 941, "label": "έ" }
|
||||
{ "$": "auto_text_key", "code": 941, "label": "έ" }
|
||||
]
|
||||
},
|
||||
"η": {
|
||||
"relevant": [
|
||||
{ "code": 942, "label": "ή" }
|
||||
{ "$": "auto_text_key", "code": 942, "label": "ή" }
|
||||
]
|
||||
},
|
||||
"ι": {
|
||||
"relevant": [
|
||||
{ "code": 912, "label": "ΐ" },
|
||||
{ "code": 970, "label": "ϊ" },
|
||||
{ "code": 943, "label": "ί" }
|
||||
{ "$": "auto_text_key", "code": 912, "label": "ΐ" },
|
||||
{ "$": "auto_text_key", "code": 970, "label": "ϊ" },
|
||||
{ "$": "auto_text_key", "code": 943, "label": "ί" }
|
||||
]
|
||||
},
|
||||
"ο": {
|
||||
"relevant": [
|
||||
{ "code": 972, "label": "ό" }
|
||||
{ "$": "auto_text_key", "code": 972, "label": "ό" }
|
||||
]
|
||||
},
|
||||
"υ": {
|
||||
"relevant": [
|
||||
{ "code": 944, "label": "ΰ" },
|
||||
{ "code": 971, "label": "ϋ" },
|
||||
{ "code": 973, "label": "ύ" }
|
||||
{ "$": "auto_text_key", "code": 944, "label": "ΰ" },
|
||||
{ "$": "auto_text_key", "code": 971, "label": "ϋ" },
|
||||
{ "$": "auto_text_key", "code": 973, "label": "ύ" }
|
||||
]
|
||||
},
|
||||
"ω": {
|
||||
"relevant": [
|
||||
{ "code": 974, "label": "ώ" }
|
||||
{ "$": "auto_text_key", "code": 974, "label": "ώ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,69 +6,69 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" }
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" }
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 239, "label": "ï" },
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 299, "label": "ī" }
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 244, "label": "ô" }
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 223, "label": "ß" }
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 249, "label": "ù" }
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,52 +6,52 @@
|
||||
"all": {
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 265, "label": "ĉ" }
|
||||
{ "$": "auto_text_key", "code": 265, "label": "ĉ" }
|
||||
]
|
||||
},
|
||||
"g": {
|
||||
"relevant": [
|
||||
{ "code": 285, "label": "ĝ" }
|
||||
{ "$": "auto_text_key", "code": 285, "label": "ĝ" }
|
||||
]
|
||||
},
|
||||
"h": {
|
||||
"relevant": [
|
||||
{ "code": 293, "label": "ĥ" }
|
||||
{ "$": "auto_text_key", "code": 293, "label": "ĥ" }
|
||||
]
|
||||
},
|
||||
"j": {
|
||||
"relevant": [
|
||||
{ "code": 309, "label": "ĵ" }
|
||||
{ "$": "auto_text_key", "code": 309, "label": "ĵ" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 349, "label": "ŝ" }
|
||||
{ "$": "auto_text_key", "code": 349, "label": "ŝ" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 365, "label": "ŭ" }
|
||||
{ "$": "auto_text_key", "code": 365, "label": "ŭ" }
|
||||
]
|
||||
},
|
||||
"q": {
|
||||
"relevant": [
|
||||
{ "code": 349, "label": "ŝ" }
|
||||
{ "$": "auto_text_key", "code": 349, "label": "ŝ" }
|
||||
]
|
||||
},
|
||||
"w": {
|
||||
"relevant": [
|
||||
{ "code": 285, "label": "ĝ" }
|
||||
{ "$": "auto_text_key", "code": 285, "label": "ĝ" }
|
||||
]
|
||||
},
|
||||
"x": {
|
||||
"relevant": [
|
||||
{ "code": 265, "label": "ĉ" }
|
||||
{ "$": "auto_text_key", "code": 265, "label": "ĉ" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 365, "label": "ŭ" }
|
||||
{ "$": "auto_text_key", "code": 365, "label": "ŭ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -5,78 +5,78 @@
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "code": 225, "label": "á" },
|
||||
"main": { "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
"relevant": [
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 261, "label": "ą" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 170, "label": "ª" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" }
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 261, "label": "ą" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 170, "label": "ª" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 231, "label": "ç" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"main": { "code": 233, "label": "é" },
|
||||
"main": { "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
"relevant": [
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 234, "label": "ê" }
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"main": { "code": 237, "label": "í" },
|
||||
"main": { "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
"relevant": [
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "code": 243, "label": "ó" },
|
||||
"main": { "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
"relevant": [
|
||||
{ "code": 186, "label": "º" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 242, "label": "ò" }
|
||||
{ "$": "auto_text_key", "code": 186, "label": "º" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 223, "label": "ß" }
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "code": 250, "label": "ú" },
|
||||
"main": { "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 251, "label": "û" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,80 +6,80 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 234, "label": "ê" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 248, "label": "ø" }
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 353, "label": "š" },
|
||||
{ "code": 223, "label": "ß" },
|
||||
{ "code": 347, "label": "ś" }
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" },
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 249, "label": "ù" }
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "code": 382, "label": "ž" },
|
||||
{ "code": 380, "label": "ż" },
|
||||
{ "code": 378, "label": "ź" }
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" },
|
||||
{ "$": "auto_text_key", "code": 380, "label": "ż" },
|
||||
{ "$": "auto_text_key", "code": 378, "label": "ź" }
|
||||
]
|
||||
},
|
||||
"ä": {
|
||||
"relevant": [
|
||||
{ "code": 230, "label": "æ" }
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" }
|
||||
]
|
||||
},
|
||||
"ö": {
|
||||
"relevant": [
|
||||
{ "code": 248, "label": "ø" }
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -5,101 +5,101 @@
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "code": 225, "label": "á" },
|
||||
"main": { "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
"relevant": [
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 234, "label": "ê" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"main": { "code": 237, "label": "í" },
|
||||
"main": { "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
"relevant": [
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "code": 322, "label": "ł" }
|
||||
{ "$": "auto_text_key", "code": 322, "label": "ł" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "code": 243, "label": "ó" },
|
||||
"main": { "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
"relevant": [
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"t": {
|
||||
"relevant": [
|
||||
{ "code": 254, "label": "þ" }
|
||||
{ "$": "auto_text_key", "code": 254, "label": "þ" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 223, "label": "ß" },
|
||||
{ "code": 347, "label": "ś" },
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "code": 250, "label": "ú" },
|
||||
"main": { "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 249, "label": "ù" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"main": { "code": 253, "label": "ý" },
|
||||
"main": { "$": "auto_text_key", "code": 253, "label": "ý" },
|
||||
"relevant": [
|
||||
{ "code": 255, "label": "ÿ" }
|
||||
{ "$": "auto_text_key", "code": 255, "label": "ÿ" }
|
||||
]
|
||||
},
|
||||
"æ": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"ð": {
|
||||
"relevant": [
|
||||
{ "code": 254, "label": "þ" }
|
||||
{ "$": "auto_text_key", "code": 254, "label": "þ" }
|
||||
]
|
||||
},
|
||||
"ø": {
|
||||
"relevant": [
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -5,84 +5,84 @@
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
"relevant": [
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 170, "label": "ª" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 170, "label": "ª" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"main": { "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" },
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"main": { "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" }
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"main": { "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
"relevant": [
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
"relevant": [
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 186, "label": "º" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 339, "label": "œ" }
|
||||
{ "$": "auto_text_key", "code": 186, "label": "º" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 223, "label": "ß" },
|
||||
{ "code": 353, "label": "š" },
|
||||
{ "code": 347, "label": "ś" }
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" },
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
"relevant": [
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 250, "label": "ú" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 255, "label": "ÿ" }
|
||||
{ "$": "auto_text_key", "code": 255, "label": "ÿ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,23 +6,23 @@
|
||||
"all": {
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"relevant": [
|
||||
{ "code": 273, "label": "đ" }
|
||||
{ "$": "auto_text_key", "code": 273, "label": "đ" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "code": 382, "label": "ž" }
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,31 +6,31 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 225, "label": "á" }
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 237, "label": "í" }
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 337, "label": "ő" }
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 337, "label": "ő" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 369, "label": "ű" }
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 369, "label": "ű" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,72 +6,72 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 229, "label": "å" }
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"relevant": [
|
||||
{ "code": 240, "label": "ð" }
|
||||
{ "$": "auto_text_key", "code": 240, "label": "ð" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 234, "label": "ê" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"t": {
|
||||
"relevant": [
|
||||
{ "code": 254, "label": "þ" }
|
||||
{ "$": "auto_text_key", "code": 254, "label": "þ" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 249, "label": "ù" }
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 253, "label": "ý" },
|
||||
{ "code": 255, "label": "ÿ" }
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" },
|
||||
{ "$": "auto_text_key", "code": 255, "label": "ÿ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -5,65 +5,66 @@
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "code": 224, "label": "à" },
|
||||
"main": { "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
"relevant": [
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 170, "label": "ª" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 230, "label": "æ" }
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 170, "label": "ª" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"main": { "code": 232, "label": "è" },
|
||||
"main": { "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
"relevant": [
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 235, "label": "ë" }
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 601, "label": "ə" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"main": { "code": 236, "label": "ì" },
|
||||
"main": { "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
"relevant": [
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 239, "label": "ï" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 237, "label": "í" }
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "code": 242, "label": "ò" },
|
||||
"main": { "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
"relevant": [
|
||||
{ "code": 186, "label": "º" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 243, "label": "ó" }
|
||||
{ "$": "auto_text_key", "code": 186, "label": "º" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "code": 249, "label": "ù" },
|
||||
"main": { "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 252, "label": "ü" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,94 +6,91 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"main": { "code": 231, "label": "ç" },
|
||||
"main": { "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
"relevant": [
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 265, "label": "ĉ" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 265, "label": "ĉ" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" }
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"main": { "code": 345, "label": "ř" }
|
||||
"main": { "$": "auto_text_key", "code": 345, "label": "ř" }
|
||||
|
||||
},
|
||||
"g": {
|
||||
"main": { "code": 285, "label": "ĝ" }
|
||||
|
||||
|
||||
"main": { "$": "auto_text_key", "code": 285, "label": "ĝ" }
|
||||
},
|
||||
"h": {
|
||||
"main": { "code": 293, "label": "ĥ" }
|
||||
}
|
||||
},
|
||||
"main": { "$": "auto_text_key", "code": 293, "label": "ĥ" }
|
||||
},
|
||||
"j": {
|
||||
"main": { "code": 309, "label": "ĵ" }
|
||||
"main": { "$": "auto_text_key", "code": 309, "label": "ĵ" }
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 328, "label": "ň" },
|
||||
{ "code": 241, "label": "ñ" }
|
||||
{ "$": "auto_text_key", "code": 328, "label": "ň" },
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "code": 246, "label": "ö" },
|
||||
"main": { "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
"relevant": [
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 244, "label": "ô" }
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"main": { "code": 219, "label": "ș" },
|
||||
"main": { "$": "auto_text_key", "code": 219, "label": "ș" },
|
||||
"relevant": [
|
||||
{ "code": 347, "label": "ś" },
|
||||
{ "code": 349, "label": "ŝ" },
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" },
|
||||
{ "$": "auto_text_key", "code": 349, "label": "ŝ" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "code": 251, "label": "û" },
|
||||
"main": { "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 252, "label": "ü" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 253, "label": "ý" }
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "code": 382, "label": "ž" }
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
@@ -130,3 +127,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,68 +6,68 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 257, "label": "ā" }
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 269, "label": "č" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 8364, "label": "€" }
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 8364, "label": "€" }
|
||||
]
|
||||
},
|
||||
"g": {
|
||||
"relevant": [
|
||||
{ "code": 291, "label": "ģ" }
|
||||
{ "$": "auto_text_key", "code": 291, "label": "ģ" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 299, "label": "ī" }
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" }
|
||||
]
|
||||
},
|
||||
"k": {
|
||||
"relevant": [
|
||||
{ "code": 311, "label": "ķ" }
|
||||
{ "$": "auto_text_key", "code": 311, "label": "ķ" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "code": 316, "label": "ļ" }
|
||||
{ "$": "auto_text_key", "code": 316, "label": "ļ" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 326, "label": "ņ" }
|
||||
{ "$": "auto_text_key", "code": 326, "label": "ņ" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 333, "label": "ō" }
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" }
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"relevant": [
|
||||
{ "code": 343, "label": "ŗ" }
|
||||
{ "$": "auto_text_key", "code": 343, "label": "ŗ" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "code": 382, "label": "ž" }
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,61 +6,61 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" }
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 250, "label": "ú" }
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" }
|
||||
]
|
||||
},
|
||||
"æ": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"ø": {
|
||||
"relevant": [
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,71 +6,71 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 257, "label": "ā" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 257, "label": "ā" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" }
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 236, "label": "ì" }
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 250, "label": "ú" }
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 7923, "label": "ỳ" }
|
||||
{ "$": "auto_text_key", "code": 7923, "label": "ỳ" }
|
||||
]
|
||||
},
|
||||
"æ": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"ø": {
|
||||
"relevant": [
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,49 +6,49 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 261, "label": "ą" },
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 261, "label": "ą" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 281, "label": "ę" }
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "code": 322, "label": "ł" }
|
||||
{ "$": "auto_text_key", "code": 322, "label": "ł" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 243, "label": "ó" }
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 347, "label": "ś" }
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" }
|
||||
]
|
||||
},
|
||||
"x": {
|
||||
"relevant": [
|
||||
{ "code": 378, "label": "ź" }
|
||||
{ "$": "auto_text_key", "code": 378, "label": "ź" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "code": 378, "label": "ź" },
|
||||
{ "code": 380, "label": "ż" }
|
||||
{ "$": "auto_text_key", "code": 378, "label": "ź" },
|
||||
{ "$": "auto_text_key", "code": 380, "label": "ż" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,70 +6,70 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 170, "label": "ª" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 226, "label": "â" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 170, "label": "ª" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 231, "label": "ç" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 281, "label": "ę" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 232, "label": "è" }
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 239, "label": "ï" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 237, "label": "í" }
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 186, "label": "º" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 243, "label": "ó" }
|
||||
{ "$": "auto_text_key", "code": 186, "label": "º" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 251, "label": "û" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 250, "label": "ú" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,70 +6,70 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 170, "label": "ª" },
|
||||
{ "code": 225, "label": "á" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 226, "label": "â" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 170, "label": "ª" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" },
|
||||
{ "code": 263, "label": "ć" },
|
||||
{ "code": 269, "label": "č" }
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" },
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 279, "label": "ė" },
|
||||
{ "code": 275, "label": "ē" },
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 281, "label": "ę" }
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 279, "label": "ė" },
|
||||
{ "$": "auto_text_key", "code": 275, "label": "ē" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 239, "label": "ï" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 238, "label": "î" }
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 241, "label": "ñ" },
|
||||
{ "code": 324, "label": "ń" }
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 186, "label": "º" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 245, "label": "õ" }
|
||||
{ "$": "auto_text_key", "code": 186, "label": "º" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 251, "label": "û" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -5,19 +5,19 @@
|
||||
"mapping": {
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "code": 259, "label": "ă" },
|
||||
"main": { "$": "auto_text_key", "code": 259, "label": "ă" },
|
||||
"relevant": [
|
||||
{ "code": 226, "label": "â" }
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"main": { "code": 238, "label": "î" }
|
||||
"main": { "$": "auto_text_key", "code": 238, "label": "î" }
|
||||
},
|
||||
"s": {
|
||||
"main": {"code": 537, "label": "ș"}
|
||||
"main": { "$": "auto_text_key", "code": 537, "label": "ș" }
|
||||
},
|
||||
"t": {
|
||||
"main": {"code": 539, "label": "ț"}
|
||||
"main": { "$": "auto_text_key", "code": 539, "label": "ț" }
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "ru",
|
||||
"authors": [ "williamtheaker" ],
|
||||
"authors": [ "williamtheaker", "33kk" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"е": {
|
||||
"relevant": [
|
||||
{ "code": 1105, "label": "ё" }
|
||||
{ "$": "auto_text_key", "code": 1105, "label": "ё" }
|
||||
]
|
||||
},
|
||||
"ь": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1098, "label": "ъ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
116
app/src/main/assets/ime/text/characters/extended_popups/sk.json
Normal file
116
app/src/main/assets/ime/text/characters/extended_popups/sk.json
Normal file
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "sk",
|
||||
"authors": [ "stefan-misik", "majso" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 283, "label": "ě" }
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 341, "label": "ŕ" },
|
||||
{ "$": "auto_text_key", "code": 345, "label": "ř" }
|
||||
]
|
||||
},
|
||||
"t": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 357, "label": "ť" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 367, "label": "ů" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" }
|
||||
]
|
||||
},
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 271, "label": "ď" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 318, "label": "ľ" },
|
||||
{ "$": "auto_text_key", "code": 314, "label": "ĺ" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 328, "label": "ň" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".sk" },
|
||||
{ "code": -255, "label": ".eu" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,22 @@
|
||||
"all": {
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"relevant": [
|
||||
{ "code": 273, "label": "đ" }
|
||||
{ "$": "auto_text_key", "code": 273, "label": "đ" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"main": { "code": 382, "label": "ž" }
|
||||
"main": { "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
|
||||
@@ -6,122 +6,122 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 224, "label": "à" },
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 261, "label": "ą" },
|
||||
{ "code": 227, "label": "ã" },
|
||||
{ "code": 229, "label": "å" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 225, "label": "á" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" },
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 261, "label": "ą" },
|
||||
{ "$": "auto_text_key", "code": 227, "label": "ã" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" },
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"relevant": [
|
||||
{ "code": 240, "label": "ð" },
|
||||
{ "code": 271, "label": "ď" }
|
||||
{ "$": "auto_text_key", "code": 240, "label": "ð" },
|
||||
{ "$": "auto_text_key", "code": 271, "label": "ď" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 232, "label": "è" },
|
||||
{ "code": 235, "label": "ë" },
|
||||
{ "code": 281, "label": "ę" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" },
|
||||
{ "$": "auto_text_key", "code": 235, "label": "ë" },
|
||||
{ "$": "auto_text_key", "code": 281, "label": "ę" }
|
||||
]
|
||||
},
|
||||
"i": {
|
||||
"relevant": [
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 239, "label": "ï" },
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 236, "label": "ì" }
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" }
|
||||
]
|
||||
},
|
||||
"l": {
|
||||
"relevant": [
|
||||
{ "code": 322, "label": "ł" }
|
||||
{ "$": "auto_text_key", "code": 322, "label": "ł" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 324, "label": "ń" },
|
||||
{ "code": 328, "label": "ň" },
|
||||
{ "code": 241, "label": "ñ" }
|
||||
{ "$": "auto_text_key", "code": 324, "label": "ń" },
|
||||
{ "$": "auto_text_key", "code": 328, "label": "ň" },
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"relevant": [
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 244, "label": "ô" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 248, "label": "ø" }
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" }
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"relevant": [
|
||||
{ "code": 345, "label": "ř" }
|
||||
{ "$": "auto_text_key", "code": 345, "label": "ř" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"relevant": [
|
||||
{ "code": 347, "label": "ś" },
|
||||
{ "code": 353, "label": "š" },
|
||||
{ "code": 351, "label": "ş" },
|
||||
{ "code": 223, "label": "ß" }
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" },
|
||||
{ "$": "auto_text_key", "code": 351, "label": "ş" },
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" }
|
||||
]
|
||||
},
|
||||
"t": {
|
||||
"relevant": [
|
||||
{ "code": 357, "label": "ť" },
|
||||
{ "code": 254, "label": "þ" }
|
||||
{ "$": "auto_text_key", "code": 357, "label": "ť" },
|
||||
{ "$": "auto_text_key", "code": 254, "label": "þ" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 251, "label": "û" }
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 253, "label": "ý" },
|
||||
{ "code": 255, "label": "ÿ" }
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" },
|
||||
{ "$": "auto_text_key", "code": 255, "label": "ÿ" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "code": 378, "label": "ź" },
|
||||
{ "code": 380, "label": "ż" },
|
||||
{ "code": 382, "label": "ž" }
|
||||
{ "$": "auto_text_key", "code": 378, "label": "ź" },
|
||||
{ "$": "auto_text_key", "code": 380, "label": "ż" },
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
},
|
||||
"ä": {
|
||||
"relevant": [
|
||||
{ "code": 230, "label": "æ" }
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" }
|
||||
]
|
||||
},
|
||||
"ö": {
|
||||
"relevant": [
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 339, "label": "œ" }
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -6,93 +6,93 @@
|
||||
"all": {
|
||||
"a": {
|
||||
"relevant": [
|
||||
{ "code": 226, "label": "â" },
|
||||
{ "code": 228, "label": "ä" },
|
||||
{ "code": 225, "label": "á" }
|
||||
{ "$": "auto_text_key", "code": 226, "label": "â" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"main": { "code": 231, "label": "ç" },
|
||||
"main": { "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
"relevant": [
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" },
|
||||
{ "code": 601, "label": "ə" },
|
||||
{ "code": 234, "label": "ê" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 601, "label": "ə" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" }
|
||||
]
|
||||
},
|
||||
"g": {
|
||||
"main": { "code": 287, "label": "ğ" }
|
||||
"main": { "$": "auto_text_key", "code": 287, "label": "ğ" }
|
||||
},
|
||||
"i": {
|
||||
"main": { "code": 305, "label": "ı" },
|
||||
"main": { "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
"relevant": [
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"ı": {
|
||||
"main": { "code": 105, "label": "i" },
|
||||
"main": { "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
"relevant": [
|
||||
{ "code": 303, "label": "į" },
|
||||
{ "code": 236, "label": "ì" },
|
||||
{ "code": 237, "label": "í" },
|
||||
{ "code": 299, "label": "ī" },
|
||||
{ "code": 238, "label": "î" },
|
||||
{ "code": 239, "label": "ï" }
|
||||
{ "$": "auto_text_key", "code": 303, "label": "į" },
|
||||
{ "$": "auto_text_key", "code": 236, "label": "ì" },
|
||||
{ "$": "auto_text_key", "code": 237, "label": "í" },
|
||||
{ "$": "auto_text_key", "code": 299, "label": "ī" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" },
|
||||
{ "$": "auto_text_key", "code": 239, "label": "ï" }
|
||||
]
|
||||
},
|
||||
"n": {
|
||||
"relevant": [
|
||||
{ "code": 328, "label": "ň" },
|
||||
{ "code": 241, "label": "ñ" }
|
||||
{ "$": "auto_text_key", "code": 328, "label": "ň" },
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "code": 246, "label": "ö" },
|
||||
"main": { "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
"relevant": [
|
||||
{ "code": 333, "label": "ō" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 243, "label": "ó" },
|
||||
{ "code": 245, "label": "õ" },
|
||||
{ "code": 242, "label": "ò" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 244, "label": "ô" }
|
||||
{ "$": "auto_text_key", "code": 333, "label": "ō" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 243, "label": "ó" },
|
||||
{ "$": "auto_text_key", "code": 245, "label": "õ" },
|
||||
{ "$": "auto_text_key", "code": 242, "label": "ò" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 244, "label": "ô" }
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"main": { "code": 351, "label": "ş" },
|
||||
"main": { "$": "auto_text_key", "code": 351, "label": "ş" },
|
||||
"relevant": [
|
||||
{ "code": 347, "label": "ś" },
|
||||
{ "code": 223, "label": "ß" },
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 347, "label": "ś" },
|
||||
{ "$": "auto_text_key", "code": 223, "label": "ß" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"main": { "code": 252, "label": "ü" },
|
||||
"main": { "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
"relevant": [
|
||||
{ "code": 363, "label": "ū" },
|
||||
{ "code": 249, "label": "ù" },
|
||||
{ "code": 250, "label": "ú" },
|
||||
{ "code": 251, "label": "û" }
|
||||
{ "$": "auto_text_key", "code": 363, "label": "ū" },
|
||||
{ "$": "auto_text_key", "code": 249, "label": "ù" },
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"y": {
|
||||
"relevant": [
|
||||
{ "code": 253, "label": "ý" }
|
||||
{ "$": "auto_text_key", "code": 253, "label": "ý" }
|
||||
]
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "code": 382, "label": "ž" }
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"type": "characters/extended_popups",
|
||||
"name": "uk",
|
||||
"authors": [ "williamtheaker", "33kk" ],
|
||||
"mapping": {
|
||||
"all": {
|
||||
"і": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1111, "label": "ї" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".ua" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,39 +6,39 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 240, "label": "ð" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 240, "label": "ð" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 248, "label": "ø" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,41 +6,43 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 252, "label": "ü" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
],
|
||||
[
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 223, "label": "ß", "popup": {
|
||||
}, "shift": { "code": 7838, "label": "ẞ" } }
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 223, "label": "ß" },
|
||||
"upper": { "code": 7838, "label": "ẞ" }
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 894, "label": ";" },
|
||||
{ "code": 962, "label": "ς" },
|
||||
{ "code": 949, "label": "ε" },
|
||||
{ "code": 961, "label": "ρ" },
|
||||
{ "code": 964, "label": "τ" },
|
||||
{ "code": 965, "label": "υ" },
|
||||
{ "code": 952, "label": "θ" },
|
||||
{ "code": 953, "label": "ι" },
|
||||
{ "code": 959, "label": "ο" },
|
||||
{ "code": 960, "label": "π" }
|
||||
{ "$": "auto_text_key", "code": 894, "label": ";" },
|
||||
{ "$": "auto_text_key", "code": 962, "label": "ς" },
|
||||
{ "$": "auto_text_key", "code": 949, "label": "ε" },
|
||||
{ "$": "auto_text_key", "code": 961, "label": "ρ" },
|
||||
{ "$": "auto_text_key", "code": 964, "label": "τ" },
|
||||
{ "$": "auto_text_key", "code": 965, "label": "υ" },
|
||||
{ "$": "auto_text_key", "code": 952, "label": "θ" },
|
||||
{ "$": "auto_text_key", "code": 953, "label": "ι" },
|
||||
{ "$": "auto_text_key", "code": 959, "label": "ο" },
|
||||
{ "$": "auto_text_key", "code": 960, "label": "π" }
|
||||
],
|
||||
[
|
||||
{ "code": 945, "label": "α" },
|
||||
{ "code": 963, "label": "σ" },
|
||||
{ "code": 948, "label": "δ" },
|
||||
{ "code": 966, "label": "φ" },
|
||||
{ "code": 947, "label": "γ" },
|
||||
{ "code": 951, "label": "η" },
|
||||
{ "code": 958, "label": "ξ" },
|
||||
{ "code": 954, "label": "κ" },
|
||||
{ "code": 955, "label": "λ" }
|
||||
{ "$": "auto_text_key", "code": 945, "label": "α" },
|
||||
{ "$": "auto_text_key", "code": 963, "label": "σ" },
|
||||
{ "$": "auto_text_key", "code": 948, "label": "δ" },
|
||||
{ "$": "auto_text_key", "code": 966, "label": "φ" },
|
||||
{ "$": "auto_text_key", "code": 947, "label": "γ" },
|
||||
{ "$": "auto_text_key", "code": 951, "label": "η" },
|
||||
{ "$": "auto_text_key", "code": 958, "label": "ξ" },
|
||||
{ "$": "auto_text_key", "code": 954, "label": "κ" },
|
||||
{ "$": "auto_text_key", "code": 955, "label": "λ" }
|
||||
],
|
||||
[
|
||||
{ "code": 950, "label": "ζ" },
|
||||
{ "code": 967, "label": "χ" },
|
||||
{ "code": 968, "label": "ψ" },
|
||||
{ "code": 969, "label": "ω" },
|
||||
{ "code": 946, "label": "β" },
|
||||
{ "code": 957, "label": "ν" },
|
||||
{ "code": 956, "label": "μ" }
|
||||
{ "$": "auto_text_key", "code": 950, "label": "ζ" },
|
||||
{ "$": "auto_text_key", "code": 967, "label": "χ" },
|
||||
{ "$": "auto_text_key", "code": 968, "label": "ψ" },
|
||||
{ "$": "auto_text_key", "code": 969, "label": "ω" },
|
||||
{ "$": "auto_text_key", "code": 946, "label": "β" },
|
||||
{ "$": "auto_text_key", "code": 957, "label": "ν" },
|
||||
{ "$": "auto_text_key", "code": 956, "label": "μ" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,41 +1,45 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "hungarian",
|
||||
"label": "Hungarian (QWERTZ)",
|
||||
"authors": [ "zoli111, gabik65" ],
|
||||
"label": "Hungarian",
|
||||
"authors": [ "zoli111, gabik65", "patrickgold" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 225, "label": "á" }
|
||||
],
|
||||
[
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,40 +6,40 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 240, "label": "ð" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 240, "label": "ð" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 254, "label": "þ" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 254, "label": "þ" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,281 +2,279 @@
|
||||
"type": "characters",
|
||||
"name": "ipa",
|
||||
"label": "International Phonetic Alphabet",
|
||||
"authors": [
|
||||
"Huy-Ngo"
|
||||
],
|
||||
"authors": [ "Huy-Ngo" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{
|
||||
"code": 113, "label": "q"
|
||||
"$": "auto_text_key", "code": 113, "label": "q"
|
||||
},
|
||||
{
|
||||
"code": 119, "label": "w",
|
||||
"$": "auto_text_key", "code": 119, "label": "w",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 695, "label": "◌ʷ" },
|
||||
{ "code": 653, "label": "ʍ" }
|
||||
{ "$": "auto_text_key", "code": 695, "label": "◌ʷ" },
|
||||
{ "$": "auto_text_key", "code": 653, "label": "ʍ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 101, "label": "e",
|
||||
"$": "auto_text_key", "code": 101, "label": "e",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 600, "label": "ɘ" },
|
||||
{ "code": 604, "label": "ɜ" },
|
||||
{ "code": 601, "label": "ə" },
|
||||
{ "code": 602, "label": "ɚ" },
|
||||
{ "code": 7498, "label": "◌ᵊ" },
|
||||
{ "code": 603, "label": "ɛ" }
|
||||
{ "$": "auto_text_key", "code": 600, "label": "ɘ" },
|
||||
{ "$": "auto_text_key", "code": 604, "label": "ɜ" },
|
||||
{ "$": "auto_text_key", "code": 601, "label": "ə" },
|
||||
{ "$": "auto_text_key", "code": 602, "label": "ɚ" },
|
||||
{ "$": "auto_text_key", "code": 7498, "label": "◌ᵊ" },
|
||||
{ "$": "auto_text_key", "code": 603, "label": "ɛ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 114, "label": "r",
|
||||
"$": "auto_text_key", "code": 114, "label": "r",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 637, "label": "ɽ" },
|
||||
{ "code": 633, "label": "ɹ" },
|
||||
{ "code": 638, "label": "ɾ" },
|
||||
{ "code": 635, "label": "ɻ" },
|
||||
{ "code": 641, "label": "ʁ" },
|
||||
{ "code": 734, "label": "◌˞" },
|
||||
{ "code": 640, "label": "ʀ" }
|
||||
{ "$": "auto_text_key", "code": 637, "label": "ɽ" },
|
||||
{ "$": "auto_text_key", "code": 633, "label": "ɹ" },
|
||||
{ "$": "auto_text_key", "code": 638, "label": "ɾ" },
|
||||
{ "$": "auto_text_key", "code": 635, "label": "ɻ" },
|
||||
{ "$": "auto_text_key", "code": 641, "label": "ʁ" },
|
||||
{ "$": "auto_text_key", "code": 734, "label": "◌˞" },
|
||||
{ "$": "auto_text_key", "code": 640, "label": "ʀ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 116, "label": "t",
|
||||
"$": "auto_text_key", "code": 116, "label": "t",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 648, "label": "ʈ" },
|
||||
{ "code": 7615, "label": "◌ᶿ" },
|
||||
{ "code": 952, "label": "θ" }
|
||||
{ "$": "auto_text_key", "code": 648, "label": "ʈ" },
|
||||
{ "$": "auto_text_key", "code": 7615, "label": "◌ᶿ" },
|
||||
{ "$": "auto_text_key", "code": 952, "label": "θ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 121, "label": "y",
|
||||
"$": "auto_text_key", "code": 121, "label": "y",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 612, "label": "ɤ" },
|
||||
{ "code": 655, "label": "ʏ" }
|
||||
{ "$": "auto_text_key", "code": 612, "label": "ɤ" },
|
||||
{ "$": "auto_text_key", "code": 655, "label": "ʏ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 117, "label": "u",
|
||||
"$": "auto_text_key", "code": 117, "label": "u",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 7551, "label": "ᵿ" },
|
||||
{ "code": 649, "label": "ʉ" },
|
||||
{ "code": 650, "label": "ʊ" }
|
||||
{ "$": "auto_text_key", "code": 7551, "label": "ᵿ" },
|
||||
{ "$": "auto_text_key", "code": 649, "label": "ʉ" },
|
||||
{ "$": "auto_text_key", "code": 650, "label": "ʊ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 105, "label": "i",
|
||||
"$": "auto_text_key", "code": 105, "label": "i",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 7574, "label": "ᵻ" },
|
||||
{ "code": 616, "label": "ɨ" },
|
||||
{ "code": 618, "label": "ɪ" }
|
||||
{ "$": "auto_text_key", "code": 7574, "label": "ᵻ" },
|
||||
{ "$": "auto_text_key", "code": 616, "label": "ɨ" },
|
||||
{ "$": "auto_text_key", "code": 618, "label": "ɪ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 111, "label": "o",
|
||||
"$": "auto_text_key", "code": 111, "label": "o",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 664, "label": "ʘ" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 606, "label": "ɞ" },
|
||||
{ "code": 339, "label": "œ" },
|
||||
{ "code": 629, "label": "ɵ" },
|
||||
{ "code": 630, "label": "ɶ" },
|
||||
{ "code": 596, "label": "ɔ" }
|
||||
{ "$": "auto_text_key", "code": 664, "label": "ʘ" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 606, "label": "ɞ" },
|
||||
{ "$": "auto_text_key", "code": 339, "label": "œ" },
|
||||
{ "$": "auto_text_key", "code": 629, "label": "ɵ" },
|
||||
{ "$": "auto_text_key", "code": 630, "label": "ɶ" },
|
||||
{ "$": "auto_text_key", "code": 596, "label": "ɔ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 112, "label": "p"
|
||||
"$": "auto_text_key", "code": 112, "label": "p"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"code": 97, "label": "a",
|
||||
"$": "auto_text_key", "code": 97, "label": "a",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 230, "label": "æ" },
|
||||
{ "code": 594, "label": "ɒ" },
|
||||
{ "code": 592, "label": "ɐ" },
|
||||
{ "code": 593, "label": "ɑ" }
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" },
|
||||
{ "$": "auto_text_key", "code": 594, "label": "ɒ" },
|
||||
{ "$": "auto_text_key", "code": 592, "label": "ɐ" },
|
||||
{ "$": "auto_text_key", "code": 593, "label": "ɑ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 115, "label": "s",
|
||||
"$": "auto_text_key", "code": 115, "label": "s",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 642, "label": "ʂ" },
|
||||
{ "code": 597, "label": "ɕ" },
|
||||
{ "code": 643, "label": "ʃ" }
|
||||
{ "$": "auto_text_key", "code": 642, "label": "ʂ" },
|
||||
{ "$": "auto_text_key", "code": 597, "label": "ɕ" },
|
||||
{ "$": "auto_text_key", "code": 643, "label": "ʃ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 100, "label": "d",
|
||||
"$": "auto_text_key", "code": 100, "label": "d",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 598, "label": "ɖ" },
|
||||
{ "code": 599, "label": "ɗ" },
|
||||
{ "code": 240, "label": "ð" }
|
||||
{ "$": "auto_text_key", "code": 598, "label": "ɖ" },
|
||||
{ "$": "auto_text_key", "code": 599, "label": "ɗ" },
|
||||
{ "$": "auto_text_key", "code": 240, "label": "ð" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 102, "label": "f",
|
||||
"$": "auto_text_key", "code": 102, "label": "f",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 632, "label": "ɸ" }
|
||||
{ "$": "auto_text_key", "code": 632, "label": "ɸ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 609, "label": "ɡ",
|
||||
"$": "auto_text_key", "code": 609, "label": "ɡ",
|
||||
"popup": {
|
||||
"main": { "code": 103, "label": "g" },
|
||||
"main": { "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
"relevant": [
|
||||
{ "code": 608, "label": "ɠ" },
|
||||
{ "code": 610, "label": "ɢ" },
|
||||
{ "code": 667, "label": "ʛ" },
|
||||
{ "code": 667, "label": "ʛ" },
|
||||
{ "code": 736, "label": "◌ˠ" },
|
||||
{ "code": 611, "label": "ɣ" }
|
||||
{ "$": "auto_text_key", "code": 608, "label": "ɠ" },
|
||||
{ "$": "auto_text_key", "code": 610, "label": "ɢ" },
|
||||
{ "$": "auto_text_key", "code": 667, "label": "ʛ" },
|
||||
{ "$": "auto_text_key", "code": 667, "label": "ʛ" },
|
||||
{ "$": "auto_text_key", "code": 736, "label": "◌ˠ" },
|
||||
{ "$": "auto_text_key", "code": 611, "label": "ɣ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 104, "label": "h",
|
||||
"$": "auto_text_key", "code": 104, "label": "h",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 614, "label": "ɦ" },
|
||||
{ "code": 615, "label": "ɧ" },
|
||||
{ "code": 295, "label": "ħ" },
|
||||
{ "code": 613, "label": "ɥ" },
|
||||
{ "code": 688, "label": "◌ʰ" },
|
||||
{ "code": 668, "label": "ʜ" }
|
||||
{ "$": "auto_text_key", "code": 614, "label": "ɦ" },
|
||||
{ "$": "auto_text_key", "code": 615, "label": "ɧ" },
|
||||
{ "$": "auto_text_key", "code": 295, "label": "ħ" },
|
||||
{ "$": "auto_text_key", "code": 613, "label": "ɥ" },
|
||||
{ "$": "auto_text_key", "code": 688, "label": "◌ʰ" },
|
||||
{ "$": "auto_text_key", "code": 668, "label": "ʜ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 106, "label": "j",
|
||||
"$": "auto_text_key", "code": 106, "label": "j",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 668, "label": "ʝ" },
|
||||
{ "code": 607, "label": "ɟ" },
|
||||
{ "code": 690, "label": "◌ʲ" },
|
||||
{ "code": 664, "label": "ʄ" }
|
||||
{ "$": "auto_text_key", "code": 668, "label": "ʝ" },
|
||||
{ "$": "auto_text_key", "code": 607, "label": "ɟ" },
|
||||
{ "$": "auto_text_key", "code": 690, "label": "◌ʲ" },
|
||||
{ "$": "auto_text_key", "code": 664, "label": "ʄ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 107, "label": "k"
|
||||
"$": "auto_text_key", "code": 107, "label": "k"
|
||||
},
|
||||
{
|
||||
"code": 108, "label": "l",
|
||||
"$": "auto_text_key", "code": 108, "label": "l",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 620, "label": "ɬ" },
|
||||
{ "code": 634, "label": "ɺ" },
|
||||
{ "code": 671, "label": "ʟ" },
|
||||
{ "code": 654, "label": "ʎ" },
|
||||
{ "code": 737, "label": "◌ˡ" },
|
||||
{ "code": 622, "label": "ɮ" }
|
||||
{ "$": "auto_text_key", "code": 620, "label": "ɬ" },
|
||||
{ "$": "auto_text_key", "code": 634, "label": "ɺ" },
|
||||
{ "$": "auto_text_key", "code": 671, "label": "ʟ" },
|
||||
{ "$": "auto_text_key", "code": 654, "label": "ʎ" },
|
||||
{ "$": "auto_text_key", "code": 737, "label": "◌ˡ" },
|
||||
{ "$": "auto_text_key", "code": 622, "label": "ɮ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 660, "label": "ʔ",
|
||||
"$": "auto_text_key", "code": 660, "label": "ʔ",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 661, "label": "ʕ" },
|
||||
{ "code": 674, "label": "ʢ" },
|
||||
{ "code": 740, "label": "◌ˤ" },
|
||||
{ "code": 673, "label": "ʡ" }
|
||||
{ "$": "auto_text_key", "code": 661, "label": "ʕ" },
|
||||
{ "$": "auto_text_key", "code": 674, "label": "ʢ" },
|
||||
{ "$": "auto_text_key", "code": 740, "label": "◌ˤ" },
|
||||
{ "$": "auto_text_key", "code": 673, "label": "ʡ" }
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"code": 122, "label": "z",
|
||||
"$": "auto_text_key", "code": 122, "label": "z",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 656, "label": "ʐ" },
|
||||
{ "code": 657, "label": "ʑ" },
|
||||
{ "code": 658, "label": "ʒ" }
|
||||
{ "$": "auto_text_key", "code": 656, "label": "ʐ" },
|
||||
{ "$": "auto_text_key", "code": 657, "label": "ʑ" },
|
||||
{ "$": "auto_text_key", "code": 658, "label": "ʒ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 120, "label": "x",
|
||||
"$": "auto_text_key", "code": 120, "label": "x",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 739, "label": "◌ˣ" },
|
||||
{ "code": 967, "label": "χ" }
|
||||
{ "$": "auto_text_key", "code": 739, "label": "◌ˣ" },
|
||||
{ "$": "auto_text_key", "code": 967, "label": "χ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 99, "label": "c",
|
||||
"$": "auto_text_key", "code": 99, "label": "c",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 231, "label": "ç" }
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 118, "label": "v",
|
||||
"$": "auto_text_key", "code": 118, "label": "v",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 651, "label": "ʋ" },
|
||||
{ "code": 652, "label": "ʌ" }
|
||||
{ "$": "auto_text_key", "code": 651, "label": "ʋ" },
|
||||
{ "$": "auto_text_key", "code": 652, "label": "ʌ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 98, "label": "b",
|
||||
"$": "auto_text_key", "code": 98, "label": "b",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 595, "label": "ɓ" },
|
||||
{ "code": 665, "label": "ʙ" },
|
||||
{ "code": 946, "label": "β" }
|
||||
{ "$": "auto_text_key", "code": 595, "label": "ɓ" },
|
||||
{ "$": "auto_text_key", "code": 665, "label": "ʙ" },
|
||||
{ "$": "auto_text_key", "code": 946, "label": "β" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 110, "label": "n",
|
||||
"$": "auto_text_key", "code": 110, "label": "n",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 626, "label": "ɲ" },
|
||||
{ "code": 627, "label": "ɳ" },
|
||||
{ "code": 628, "label": "ɴ" },
|
||||
{ "code": 8319, "label": "◌ⁿ" },
|
||||
{ "code": 771, "label": "◌̃" },
|
||||
{ "code": 631, "label": "ŋ" }
|
||||
{ "$": "auto_text_key", "code": 626, "label": "ɲ" },
|
||||
{ "$": "auto_text_key", "code": 627, "label": "ɳ" },
|
||||
{ "$": "auto_text_key", "code": 628, "label": "ɴ" },
|
||||
{ "$": "auto_text_key", "code": 8319, "label": "◌ⁿ" },
|
||||
{ "$": "auto_text_key", "code": 771, "label": "◌̃" },
|
||||
{ "$": "auto_text_key", "code": 631, "label": "ŋ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": 109, "label": "m",
|
||||
"$": "auto_text_key", "code": 109, "label": "m",
|
||||
"popup": {
|
||||
"relevant": [
|
||||
{ "code": 625, "label": "ɱ" },
|
||||
{ "code": 624, "label": "ɰ" },
|
||||
{ "code": 623, "label": "ɯ" }
|
||||
{ "$": "auto_text_key", "code": 625, "label": "ɱ" },
|
||||
{ "$": "auto_text_key", "code": 624, "label": "ɰ" },
|
||||
{ "$": "auto_text_key", "code": 623, "label": "ɯ" }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,42 +6,41 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 1081, "label": "й" },
|
||||
{ "code": 1094, "label": "ц" },
|
||||
{ "code": 1091, "label": "у" },
|
||||
{ "code": 1082, "label": "к" },
|
||||
{ "code": 1077, "label": "е" },
|
||||
{ "code": 1085, "label": "н" },
|
||||
{ "code": 1075, "label": "г" },
|
||||
{ "code": 1096, "label": "ш" },
|
||||
{ "code": 1097, "label": "щ" },
|
||||
{ "code": 1079, "label": "з" },
|
||||
{ "code": 1093, "label": "х" },
|
||||
{ "code": 1098, "label": "ъ" }
|
||||
{ "$": "auto_text_key", "code": 1081, "label": "й" },
|
||||
{ "$": "auto_text_key", "code": 1094, "label": "ц" },
|
||||
{ "$": "auto_text_key", "code": 1091, "label": "у" },
|
||||
{ "$": "auto_text_key", "code": 1082, "label": "к" },
|
||||
{ "$": "auto_text_key", "code": 1077, "label": "е" },
|
||||
{ "$": "auto_text_key", "code": 1085, "label": "н" },
|
||||
{ "$": "auto_text_key", "code": 1075, "label": "г" },
|
||||
{ "$": "auto_text_key", "code": 1096, "label": "ш" },
|
||||
{ "$": "auto_text_key", "code": 1097, "label": "щ" },
|
||||
{ "$": "auto_text_key", "code": 1079, "label": "з" },
|
||||
{ "$": "auto_text_key", "code": 1093, "label": "х" }
|
||||
],
|
||||
[
|
||||
{ "code": 1092 , "label": "ф" },
|
||||
{ "code": 1099 , "label": "ы" },
|
||||
{ "code": 1074 , "label": "в" },
|
||||
{ "code": 1072 , "label": "а" },
|
||||
{ "code": 1087 , "label": "п" },
|
||||
{ "code": 1088 , "label": "р" },
|
||||
{ "code": 1086 , "label": "о" },
|
||||
{ "code": 1083 , "label": "л" },
|
||||
{ "code": 1076 , "label": "д" },
|
||||
{ "code": 1078 , "label": "ж" },
|
||||
{ "code": 1101 , "label": "э" }
|
||||
{ "$": "auto_text_key", "code": 1092 , "label": "ф" },
|
||||
{ "$": "auto_text_key", "code": 1099 , "label": "ы" },
|
||||
{ "$": "auto_text_key", "code": 1074 , "label": "в" },
|
||||
{ "$": "auto_text_key", "code": 1072 , "label": "а" },
|
||||
{ "$": "auto_text_key", "code": 1087 , "label": "п" },
|
||||
{ "$": "auto_text_key", "code": 1088 , "label": "р" },
|
||||
{ "$": "auto_text_key", "code": 1086 , "label": "о" },
|
||||
{ "$": "auto_text_key", "code": 1083 , "label": "л" },
|
||||
{ "$": "auto_text_key", "code": 1076 , "label": "д" },
|
||||
{ "$": "auto_text_key", "code": 1078 , "label": "ж" },
|
||||
{ "$": "auto_text_key", "code": 1101 , "label": "э" }
|
||||
],
|
||||
[
|
||||
{ "code": 1103 , "label": "я" },
|
||||
{ "code": 1095 , "label": "ч" },
|
||||
{ "code": 1089 , "label": "с" },
|
||||
{ "code": 1084 , "label": "м" },
|
||||
{ "code": 1080 , "label": "и" },
|
||||
{ "code": 1090 , "label": "т" },
|
||||
{ "code": 1100 , "label": "ь" },
|
||||
{ "code": 1073 , "label": "б" },
|
||||
{ "code": 1102 , "label": "ю" }
|
||||
{ "$": "auto_text_key", "code": 1103 , "label": "я" },
|
||||
{ "$": "auto_text_key", "code": 1095 , "label": "ч" },
|
||||
{ "$": "auto_text_key", "code": 1089 , "label": "с" },
|
||||
{ "$": "auto_text_key", "code": 1084 , "label": "м" },
|
||||
{ "$": "auto_text_key", "code": 1080 , "label": "и" },
|
||||
{ "$": "auto_text_key", "code": 1090 , "label": "т" },
|
||||
{ "$": "auto_text_key", "code": 1100 , "label": "ь" },
|
||||
{ "$": "auto_text_key", "code": 1073 , "label": "б" },
|
||||
{ "$": "auto_text_key", "code": 1102 , "label": "ю" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"type": "characters",
|
||||
"name": "jcuken_ukrainian",
|
||||
"label": "Ukrainian (JCUKEN)",
|
||||
"authors": [ "williamtheaker", "33kk" ],
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1081, "label": "й" },
|
||||
{ "$": "auto_text_key", "code": 1094, "label": "ц" },
|
||||
{ "$": "auto_text_key", "code": 1091, "label": "у" },
|
||||
{ "$": "auto_text_key", "code": 1082, "label": "к" },
|
||||
{ "$": "auto_text_key", "code": 1077, "label": "е" },
|
||||
{ "$": "auto_text_key", "code": 1085, "label": "н" },
|
||||
{ "$": "auto_text_key", "code": 1075, "label": "г" },
|
||||
{ "$": "auto_text_key", "code": 1096, "label": "ш" },
|
||||
{ "$": "auto_text_key", "code": 1097, "label": "щ" },
|
||||
{ "$": "auto_text_key", "code": 1079, "label": "з" },
|
||||
{ "$": "auto_text_key", "code": 1093, "label": "х" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1092 , "label": "ф" },
|
||||
{ "$": "auto_text_key", "code": 1110 , "label": "і" },
|
||||
{ "$": "auto_text_key", "code": 1074 , "label": "в" },
|
||||
{ "$": "auto_text_key", "code": 1072 , "label": "а" },
|
||||
{ "$": "auto_text_key", "code": 1087 , "label": "п" },
|
||||
{ "$": "auto_text_key", "code": 1088 , "label": "р" },
|
||||
{ "$": "auto_text_key", "code": 1086 , "label": "о" },
|
||||
{ "$": "auto_text_key", "code": 1083 , "label": "л" },
|
||||
{ "$": "auto_text_key", "code": 1076 , "label": "д" },
|
||||
{ "$": "auto_text_key", "code": 1078 , "label": "ж" },
|
||||
{ "$": "auto_text_key", "code": 1108 , "label": "є" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1103 , "label": "я" },
|
||||
{ "$": "auto_text_key", "code": 1095 , "label": "ч" },
|
||||
{ "$": "auto_text_key", "code": 1089 , "label": "с" },
|
||||
{ "$": "auto_text_key", "code": 1084 , "label": "м" },
|
||||
{ "$": "auto_text_key", "code": 1080 , "label": "и" },
|
||||
{ "$": "auto_text_key", "code": 1090 , "label": "т" },
|
||||
{ "$": "auto_text_key", "code": 1100 , "label": "ь" },
|
||||
{ "$": "auto_text_key", "code": 1073 , "label": "б" },
|
||||
{ "$": "auto_text_key", "code": 1102 , "label": "ю" }
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -6,41 +6,41 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 305, "label": "ı" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 251, "label": "û" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 234, "label": "ê" },
|
||||
{ "code": 238, "label": "î" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 231, "label": "ç" },
|
||||
{ "code": 351, "label": "ş" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 351, "label": "ş" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,17 +12,15 @@
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 64, "label": "@", "groupId": 1, "variation": "email_address" },
|
||||
{ "code": 44, "label": ",", "groupId": 1, "variation": "normal" },
|
||||
{ "code": 44, "label": ",", "groupId": 1, "variation": "password" },
|
||||
{ "code": 47, "label": "/", "groupId": 1, "variation": "uri" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 44, "label": ",", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "email_address" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "normal" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "password" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "uri" },
|
||||
{ "code": 46, "label": ".", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -11,17 +11,15 @@
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 64, "label": "@", "groupId": 1, "variation": "email_address" },
|
||||
{ "code": 1548, "label": "،", "groupId": 1, "variation": "normal" },
|
||||
{ "code": 1548, "label": "،", "groupId": 1, "variation": "password" },
|
||||
{ "code": 47, "label": "/", "groupId": 1, "variation": "uri" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 1548, "label": "،", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "email_address" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "normal" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "password" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "uri" },
|
||||
{ "code": 46, "label": ".", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -12,14 +12,11 @@
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 113, "label": "q", "groupId": 1 },
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q", "groupId": 1 },
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 122, "label": "z", "groupId": 2, "variation": "email_address" },
|
||||
{ "code": 122, "label": "z", "groupId": 2, "variation": "normal" },
|
||||
{ "code": 122, "label": "z", "groupId": 2, "variation": "password" },
|
||||
{ "code": 122, "label": "z", "groupId": 2, "variation": "uri" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -11,17 +11,15 @@
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 64, "label": "@", "groupId": 1, "variation": "email_address" },
|
||||
{ "code": 44, "label": ",", "groupId": 1, "variation": "normal" },
|
||||
{ "code": 44, "label": ",", "groupId": 1, "variation": "password" },
|
||||
{ "code": 47, "label": "/", "groupId": 1, "variation": "uri" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 44, "label": ",", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "email_address" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "normal" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "password" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "uri" },
|
||||
{ "code": 46, "label": ".", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -11,17 +11,16 @@
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 64, "label": "@", "groupId": 1, "variation": "email_address" },
|
||||
{ "code": 1567, "label": "؟", "groupId": 1, "variation": "normal" },
|
||||
{ "code": 1548, "label": "،", "groupId": 1, "variation": "password" },
|
||||
{ "code": 47, "label": "/", "groupId": 1, "variation": "uri" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 1567, "label": "؟", "groupId": 1 },
|
||||
"password": { "code": 1548, "label": "،", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 32, "label": " " },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "email_address" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "normal" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "password" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "uri" },
|
||||
{ "code": 46, "label": ".", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -11,21 +11,17 @@
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": 64, "label": "@", "groupId": 1, "variation": "email_address" },
|
||||
{ "code": 1548, "label": "،", "groupId": 1, "variation": "normal" },
|
||||
{ "code": 1548, "label": "،", "groupId": 1, "variation": "password" },
|
||||
{ "code": 47, "label": "/", "groupId": 1, "variation": "uri" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 1548, "label": "،", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": -210, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -213, "label": "switch_to_media_context", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 8204, "label": "half_space", "variation": "normal" },
|
||||
{ "code": 8204, "label": "half_space", "variation": "password" },
|
||||
{ "code": 1600, "label": "kashida", "variation": "normal" },
|
||||
{ "code": 1600, "label": "kashida", "variation": "password" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "email_address" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "normal" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "password" },
|
||||
{ "code": 46, "label": ".", "groupId": 2, "variation": "uri" },
|
||||
{ "code": 8204, "label": "half_space" },
|
||||
{ "code": 1600, "label": "kashida" },
|
||||
{ "code": 46, "label": ".", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -6,39 +6,39 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 229, "label": "å" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 248, "label": "ø" },
|
||||
{ "code": 230, "label": "æ" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 248, "label": "ø" },
|
||||
{ "$": "auto_text_key", "code": 230, "label": "æ" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" }
|
||||
],
|
||||
[
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,40 +6,40 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 1113, "label": "љ" },
|
||||
{ "code": 1114, "label": "њ" },
|
||||
{ "code": 1077, "label": "е" },
|
||||
{ "code": 1088, "label": "р" },
|
||||
{ "code": 1090, "label": "т" },
|
||||
{ "code": 1079, "label": "з" },
|
||||
{ "code": 1091, "label": "у" },
|
||||
{ "code": 1080, "label": "и" },
|
||||
{ "code": 1086, "label": "о" },
|
||||
{ "code": 1087, "label": "п" },
|
||||
{ "code": 1096, "label": "ш" }
|
||||
{ "$": "auto_text_key", "code": 1113, "label": "љ" },
|
||||
{ "$": "auto_text_key", "code": 1114, "label": "њ" },
|
||||
{ "$": "auto_text_key", "code": 1077, "label": "е" },
|
||||
{ "$": "auto_text_key", "code": 1088, "label": "р" },
|
||||
{ "$": "auto_text_key", "code": 1090, "label": "т" },
|
||||
{ "$": "auto_text_key", "code": 1079, "label": "з" },
|
||||
{ "$": "auto_text_key", "code": 1091, "label": "у" },
|
||||
{ "$": "auto_text_key", "code": 1080, "label": "и" },
|
||||
{ "$": "auto_text_key", "code": 1086, "label": "о" },
|
||||
{ "$": "auto_text_key", "code": 1087, "label": "п" },
|
||||
{ "$": "auto_text_key", "code": 1096, "label": "ш" }
|
||||
],
|
||||
[
|
||||
{ "code": 1072, "label": "а" },
|
||||
{ "code": 1089, "label": "с" },
|
||||
{ "code": 1076, "label": "д" },
|
||||
{ "code": 1092, "label": "ф" },
|
||||
{ "code": 1075, "label": "г" },
|
||||
{ "code": 1093, "label": "х" },
|
||||
{ "code": 1112, "label": "ј" },
|
||||
{ "code": 1082, "label": "к" },
|
||||
{ "code": 1083, "label": "л" },
|
||||
{ "code": 1095, "label": "ч" },
|
||||
{ "code": 1115, "label": "ћ" }
|
||||
{ "$": "auto_text_key", "code": 1072, "label": "а" },
|
||||
{ "$": "auto_text_key", "code": 1089, "label": "с" },
|
||||
{ "$": "auto_text_key", "code": 1076, "label": "д" },
|
||||
{ "$": "auto_text_key", "code": 1092, "label": "ф" },
|
||||
{ "$": "auto_text_key", "code": 1075, "label": "г" },
|
||||
{ "$": "auto_text_key", "code": 1093, "label": "х" },
|
||||
{ "$": "auto_text_key", "code": 1112, "label": "ј" },
|
||||
{ "$": "auto_text_key", "code": 1082, "label": "к" },
|
||||
{ "$": "auto_text_key", "code": 1083, "label": "л" },
|
||||
{ "$": "auto_text_key", "code": 1095, "label": "ч" },
|
||||
{ "$": "auto_text_key", "code": 1115, "label": "ћ" }
|
||||
],
|
||||
[
|
||||
{ "code": 1119, "label": "џ" },
|
||||
{ "code": 1094, "label": "ц" },
|
||||
{ "code": 1074, "label": "в" },
|
||||
{ "code": 1073, "label": "б" },
|
||||
{ "code": 1085, "label": "н" },
|
||||
{ "code": 1084, "label": "м" },
|
||||
{ "code": 1106, "label": "ђ" },
|
||||
{ "code": 1078, "label": "ж" }
|
||||
{ "$": "auto_text_key", "code": 1119, "label": "џ" },
|
||||
{ "$": "auto_text_key", "code": 1094, "label": "ц" },
|
||||
{ "$": "auto_text_key", "code": 1074, "label": "в" },
|
||||
{ "$": "auto_text_key", "code": 1073, "label": "б" },
|
||||
{ "$": "auto_text_key", "code": 1085, "label": "н" },
|
||||
{ "$": "auto_text_key", "code": 1084, "label": "м" },
|
||||
{ "$": "auto_text_key", "code": 1106, "label": "ђ" },
|
||||
{ "$": "auto_text_key", "code": 1078, "label": "ж" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,41 +6,41 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 353, "label": "š" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 353, "label": "š" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 269, "label": "č" },
|
||||
{ "code": 263, "label": "ć" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 269, "label": "č" },
|
||||
{ "$": "auto_text_key", "code": 263, "label": "ć" }
|
||||
],
|
||||
[
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 273, "label": "đ" },
|
||||
{ "code": 382, "label": "ž" }
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 273, "label": "đ" },
|
||||
{ "$": "auto_text_key", "code": 382, "label": "ž" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,37 +6,37 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 241, "label": "ñ" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,39 +6,39 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 229, "label": "å" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 229, "label": "å" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,51 +6,51 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 232, "label": "è", "popup": {
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 252, "label": "ü" }
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
]
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 233, "label": "é", "popup": {
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 246, "label": "ö" }
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
]
|
||||
} },
|
||||
{ "code": 224, "label": "à", "popup": {
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 228, "label": "ä" }
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
]
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,51 +6,51 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 252, "label": "ü", "popup": {
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 232, "label": "è" }
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" }
|
||||
]
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 246, "label": "ö", "popup": {
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" }
|
||||
]
|
||||
} },
|
||||
{ "code": 228, "label": "ä", "popup": {
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
]
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,51 +6,51 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 252, "label": "ü", "popup": {
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 232, "label": "è" }
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" }
|
||||
]
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 246, "label": "ö", "popup": {
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 233, "label": "é" }
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" }
|
||||
]
|
||||
} },
|
||||
{ "code": 228, "label": "ä", "popup": {
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 224, "label": "à" }
|
||||
{ "$": "auto_text_key", "code": 224, "label": "à" }
|
||||
]
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" }
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,42 +6,42 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 287, "label": "ğ" },
|
||||
{ "code": 305, "label": "ı" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" }
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 287, "label": "ğ" },
|
||||
{ "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" }
|
||||
],
|
||||
[
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 105, "label": "i" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 252, "label": "ü" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 351, "label": "ş" }
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 351, "label": "ş" }
|
||||
],
|
||||
[
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 231, "label": "ç" },
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 120, "label": "x" }
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,42 +6,42 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 305, "label": "ı" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 287, "label": "ğ" },
|
||||
{ "code": 252, "label": "ü" }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 305, "label": "ı" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 287, "label": "ğ" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" },
|
||||
{ "code": 351, "label": "ş" },
|
||||
{ "code": 105, "label": "i" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 351, "label": "ş" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 246, "label": "ö" },
|
||||
{ "code": 231, "label": "ç" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,41 +6,48 @@
|
||||
"direction": "ltr",
|
||||
"arrangement": [
|
||||
[
|
||||
{ "code": 113, "label": "q" },
|
||||
{ "code": 100, "label": "d" },
|
||||
{ "code": 114, "label": "r" },
|
||||
{ "code": 119, "label": "w" },
|
||||
{ "code": 98, "label": "b" },
|
||||
{ "code": 106, "label": "j" },
|
||||
{ "code": 102, "label": "f" },
|
||||
{ "code": 117, "label": "u" },
|
||||
{ "code": 112, "label": "p" },
|
||||
{ "code": 59, "label": ";", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 58, "label": ":" }
|
||||
]
|
||||
}, "shift": { "code": 58, "label": ":" } }
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 59, "label": ";", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 58, "label": ":" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 58, "label": ":", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 59, "label": ";" }
|
||||
]
|
||||
} }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "code": 97, "label": "a" },
|
||||
{ "code": 115, "label": "s" },
|
||||
{ "code": 104, "label": "h" },
|
||||
{ "code": 116, "label": "t" },
|
||||
{ "code": 103, "label": "g" },
|
||||
{ "code": 121, "label": "y" },
|
||||
{ "code": 110, "label": "n" },
|
||||
{ "code": 101, "label": "e" },
|
||||
{ "code": 111, "label": "o" },
|
||||
{ "code": 105, "label": "i" }
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" }
|
||||
],
|
||||
[
|
||||
{ "code": 122, "label": "z" },
|
||||
{ "code": 120, "label": "x" },
|
||||
{ "code": 109, "label": "m" },
|
||||
{ "code": 99, "label": "c" },
|
||||
{ "code": 118, "label": "v" },
|
||||
{ "code": 107, "label": "k" },
|
||||
{ "code": 108, "label": "l" }
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
15
app/src/main/assets/ime/text/symbols-with-space.json
Normal file
15
app/src/main/assets/ime/text/symbols-with-space.json
Normal file
@@ -0,0 +1,15 @@
|
||||
[
|
||||
")",
|
||||
"}",
|
||||
"]",
|
||||
">",
|
||||
|
||||
"&",
|
||||
|
||||
".",
|
||||
",",
|
||||
"?",
|
||||
"!",
|
||||
";",
|
||||
":"
|
||||
]
|
||||
@@ -503,24 +503,6 @@ SOFTWARE.
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>kotlin-result</h3>
|
||||
<span>Copyright (c) 2017-2020 Michael Bull (https://www.michael-bull.com)</span>
|
||||
<pre>
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Material Icons</h3>
|
||||
<span>Copyright 2018 Google LLC</span>
|
||||
<pre>
|
||||
@@ -729,24 +711,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Moshi</h3>
|
||||
<span>Copyright 2015 Square, Inc.</span>
|
||||
<pre>
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Timber</h3>
|
||||
<span>Copyright 2013 Jake Wharton</span>
|
||||
<pre>
|
||||
|
||||
@@ -16,39 +16,96 @@
|
||||
|
||||
package dev.patrickgold.florisboard.crashutility
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.*
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import dev.patrickgold.florisboard.BuildConfig
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.databinding.CrashDialogBinding
|
||||
import dev.patrickgold.florisboard.debug.*
|
||||
import dev.patrickgold.florisboard.ime.core.Preferences
|
||||
|
||||
class CrashDialogActivity : AppCompatActivity() {
|
||||
private lateinit var binding: CrashDialogBinding
|
||||
private var stacktrace: String = ""
|
||||
private var stacktraces: List<CrashUtility.Stacktrace> = listOf()
|
||||
private var errorReport: StringBuilder = StringBuilder()
|
||||
private var prefs: Preferences? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = CrashDialogBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
stacktrace = CrashUtility.getUnhandledStacktrace(this)
|
||||
binding.stacktrace.text = stacktrace
|
||||
// We secure the PrefHelper usage here because the PrefHelper could potentially be the
|
||||
// source of the crash, thus making the crash dialog unusable if not wrapped.
|
||||
try {
|
||||
prefs = Preferences.default()
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
|
||||
stacktraces = CrashUtility.getUnhandledStacktraces(this)
|
||||
errorReport.apply {
|
||||
appendLine("#### Environment information")
|
||||
appendLine("- FlorisBoard Version: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
|
||||
appendLine("- Device: ${getDeviceName()}")
|
||||
appendLine("- Android: ${getAndroidVersion()}")
|
||||
appendLine()
|
||||
appendLine("#### Features enabled")
|
||||
appendLine("```kt")
|
||||
val prefs = prefs
|
||||
if (prefs != null) {
|
||||
try {
|
||||
appendLine("smartbar = ${prefs.smartbar.enabled}")
|
||||
appendLine("suggestions = ${prefs.suggestion.enabled}")
|
||||
appendLine("suggestions_clipboard = ${prefs.suggestion.clipboardContentEnabled}")
|
||||
appendLine("suggestions_next_word = ${prefs.suggestion.usePrevWords}")
|
||||
appendLine("glide = ${prefs.glide.enabled}")
|
||||
appendLine("clipboard_internal = ${prefs.clipboard.enableInternal}")
|
||||
appendLine("clipboard_history = ${prefs.clipboard.enableHistory}")
|
||||
} catch (_: Exception) {
|
||||
appendLine("error: Exception was thrown while retrieving preferences, instance not null.")
|
||||
}
|
||||
} else {
|
||||
appendLine("error: Failed to fetch preferences: PrefHelper instance was null!")
|
||||
}
|
||||
appendLine("```")
|
||||
appendLine()
|
||||
if (stacktraces.isNotEmpty()) {
|
||||
appendLine("#### Attached stacktrace files")
|
||||
stacktraces.forEach {
|
||||
generateCollapsibleStacktrace(this, it)
|
||||
}
|
||||
} else {
|
||||
flogWarning(LogTopic.CRASH_UTILITY) {
|
||||
"Stacktrace file list is empty."
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.stacktrace.text = errorReport
|
||||
|
||||
binding.reportInstructions.text =
|
||||
binding.reportInstructions.text.toString().format(
|
||||
resources.getString(R.string.crash_dialog__bug_report_template)
|
||||
)
|
||||
|
||||
binding.copyToClipboard.setOnClickListener {
|
||||
val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE)
|
||||
if (clipboardManager != null && clipboardManager is ClipboardManager) {
|
||||
clipboardManager.setPrimaryClip(ClipData.newPlainText(stacktrace, stacktrace))
|
||||
val toastMessage: String = if (clipboardManager != null && clipboardManager is ClipboardManager) {
|
||||
clipboardManager.setPrimaryClip(ClipData.newPlainText(errorReport, errorReport))
|
||||
resources.getString(R.string.crash_dialog__copy_to_clipboard_success)
|
||||
} else {
|
||||
resources.getString(R.string.crash_dialog__copy_to_clipboard_failure)
|
||||
}
|
||||
Toast.makeText(this, toastMessage, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
binding.openBugReportForm.setOnClickListener {
|
||||
val browserIntent = Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(resources.getString(R.string.florisboard__issue_tracker_new_issue_url))
|
||||
Uri.parse(resources.getString(R.string.florisboard__issue_tracker_url))
|
||||
)
|
||||
startActivity(browserIntent)
|
||||
}
|
||||
@@ -57,4 +114,39 @@ class CrashDialogActivity : AppCompatActivity() {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rules for collapsible markdown on GitHub:
|
||||
* https://gist.github.com/pierrejoubert73/902cc94d79424356a8d20be2b382e1ab
|
||||
*/
|
||||
private fun generateCollapsibleStacktrace(sb: StringBuilder, stacktrace: CrashUtility.Stacktrace) {
|
||||
sb.apply {
|
||||
appendLine("<details>")
|
||||
appendLine("<summary>${stacktrace.name}</summary>")
|
||||
appendLine()
|
||||
appendLine("```")
|
||||
appendLine(stacktrace.details)
|
||||
appendLine("```")
|
||||
appendLine("</details>")
|
||||
appendLine()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDeviceName(): String {
|
||||
val manufacturer = Build.MANUFACTURER
|
||||
val model = Build.MODEL
|
||||
return if (model.lowercase().startsWith(manufacturer.lowercase())) {
|
||||
model.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
|
||||
} else {
|
||||
"${manufacturer.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }} $model"
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAndroidVersion(): String {
|
||||
val fields = Build.VERSION_CODES::class.java.fields
|
||||
var codeName: String? = null
|
||||
fields.filter { it.getInt(Build.VERSION_CODES::class) == Build.VERSION.SDK_INT }
|
||||
.forEach { codeName = it.name }
|
||||
return codeName?.let { "${Build.VERSION.RELEASE} (cn=$it sdk=${Build.VERSION.SDK_INT})" } ?: "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,10 @@ import android.os.Bundle
|
||||
import android.os.Process
|
||||
import android.util.Log
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import dev.patrickgold.florisboard.BuildConfig
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.debug.*
|
||||
import dev.patrickgold.florisboard.ime.core.FlorisBoard
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.system.exitProcess
|
||||
@@ -46,7 +47,7 @@ abstract class CrashUtility private constructor() {
|
||||
private const val SHARED_PREFS_FILE = "crash_utility"
|
||||
private const val SHARED_PREFS_LAST_CRASH_TIMESTAMP = "last_crash_timestamp"
|
||||
|
||||
private const val NOTIFICATION_CHANNEL_ID = "dev.patrickgold.florisboard.crashutility"
|
||||
private const val NOTIFICATION_CHANNEL_ID = "${BuildConfig.APPLICATION_ID}.crashutility"
|
||||
private const val NOTIFICATION_ID = 0xFBAD0100
|
||||
|
||||
private const val UNHANDLED_STACKTRACE_FILE_EXT = "stacktrace"
|
||||
@@ -63,14 +64,16 @@ abstract class CrashUtility private constructor() {
|
||||
*/
|
||||
fun install(context: Context?): Boolean {
|
||||
if (context == null) {
|
||||
Timber.e(
|
||||
"install($context): Can't install crash handler with a null Context object, doing nothing!"
|
||||
)
|
||||
flogError(LogTopic.CRASH_UTILITY) {
|
||||
"Can't install crash handler with a null Context object, doing nothing!"
|
||||
}
|
||||
return false
|
||||
}
|
||||
val oldHandler = Thread.getDefaultUncaughtExceptionHandler()
|
||||
if (oldHandler is UncaughtExceptionHandler) {
|
||||
Timber.i("install($context): Crash handler is already installed, doing nothing!")
|
||||
flogInfo(LogTopic.CRASH_UTILITY) {
|
||||
"Crash handler is already installed, doing nothing!"
|
||||
}
|
||||
} else {
|
||||
val application = context.applicationContext
|
||||
if (application != null && application is Application) {
|
||||
@@ -82,18 +85,18 @@ abstract class CrashUtility private constructor() {
|
||||
application.filesDir.absolutePath
|
||||
)
|
||||
)
|
||||
Timber.i(
|
||||
"install($context): Successfully installed crash handler for this application!"
|
||||
)
|
||||
flogInfo(LogTopic.CRASH_UTILITY) {
|
||||
"Successfully installed crash handler for this application!"
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
Timber.e(
|
||||
"install($context): Failed to install crash handler, probably due to missing runtime permission 'setDefaultUncaughtExceptionHandler':\n$e"
|
||||
)
|
||||
flogError(LogTopic.CRASH_UTILITY) {
|
||||
"Failed to install crash handler, probably due to missing runtime permission 'setDefaultUncaughtExceptionHandler':\n$e"
|
||||
}
|
||||
return false
|
||||
} catch (e: Exception) {
|
||||
Timber.e(
|
||||
"install($context): Failed to install crash handler due to an unspecified error:\n$e"
|
||||
)
|
||||
flogError(LogTopic.CRASH_UTILITY) {
|
||||
"Failed to install crash handler due to an unspecified error:\n$e"
|
||||
}
|
||||
return false
|
||||
}
|
||||
application.registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
||||
@@ -126,19 +129,19 @@ abstract class CrashUtility private constructor() {
|
||||
)
|
||||
notificationManager.createNotificationChannel(notificationChannel)
|
||||
}
|
||||
Timber.i(
|
||||
"install($context): Successfully created crash handler notification channel!"
|
||||
)
|
||||
flogInfo(LogTopic.CRASH_UTILITY) {
|
||||
"Successfully created crash handler notification channel!"
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(
|
||||
"install($context): Failed to create crash handler notification channel due to an unspecified error:\n$e"
|
||||
)
|
||||
flogError(LogTopic.CRASH_UTILITY) {
|
||||
"Failed to create crash handler notification channel due to an unspecified error:\n$e"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.e(
|
||||
"install($context): Can't install crash handler with a null Application object, doing nothing!"
|
||||
)
|
||||
flogError(LogTopic.CRASH_UTILITY) {
|
||||
"Can't install crash handler with a null Application object, doing nothing!"
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -150,24 +153,24 @@ abstract class CrashUtility private constructor() {
|
||||
*
|
||||
* @param context The current package context. If null is supplied, this function returns
|
||||
* an empty string.
|
||||
* @return All unhandled stacktrace files or an empty string.
|
||||
* @return All unhandled stacktrace files or an empty list.
|
||||
*/
|
||||
fun getUnhandledStacktrace(context: Context?): String {
|
||||
context ?: return ""
|
||||
val retString: StringBuilder = StringBuilder()
|
||||
fun getUnhandledStacktraces(context: Context?): List<Stacktrace> {
|
||||
context ?: return listOf()
|
||||
val retList = mutableListOf<Stacktrace>()
|
||||
val ustDir = getUstDir(context)
|
||||
if (ustDir.isDirectory) {
|
||||
(ustDir.listFiles { pathname ->
|
||||
pathname.name.endsWith(".$UNHANDLED_STACKTRACE_FILE_EXT")
|
||||
})?.forEach { file ->
|
||||
val newLine = System.lineSeparator()
|
||||
Timber.i("Reading unhandled stacktrace: ${file.name}")
|
||||
retString.append("~~~ ${file.name} ~~~$newLine$newLine")
|
||||
retString.append(readFile(file))
|
||||
flogInfo(LogTopic.CRASH_UTILITY) {
|
||||
"Reading unhandled stacktrace: ${file.name}"
|
||||
}
|
||||
retList.add(Stacktrace(file.name, readFile(file)))
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
return retString.toString()
|
||||
return retList.toList()
|
||||
}
|
||||
|
||||
fun hasUnhandledStacktraceFiles(context: Context): Boolean {
|
||||
@@ -338,6 +341,14 @@ abstract class CrashUtility private constructor() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple stacktrace data class capable of holding a [name] and the [details] of a stacktrace.
|
||||
*/
|
||||
data class Stacktrace(
|
||||
val name: String,
|
||||
val details: String
|
||||
)
|
||||
|
||||
/**
|
||||
* Custom UncaughtExceptionHandler, which writes the captured stacktrace of the crash to the
|
||||
* internal storage, pushes a crash notification and kills the current process.
|
||||
@@ -348,7 +359,9 @@ abstract class CrashUtility private constructor() {
|
||||
private val path: String
|
||||
) : Thread.UncaughtExceptionHandler {
|
||||
override fun uncaughtException(thread: Thread?, throwable: Throwable?) {
|
||||
Timber.e("Detected application crash, executing custom crash handler.")
|
||||
flogInfo(LogTopic.CRASH_UTILITY) {
|
||||
"Detected application crash, executing custom crash handler."
|
||||
}
|
||||
thread ?: return
|
||||
throwable ?: return
|
||||
val timestamp = System.currentTimeMillis()
|
||||
|
||||
366
app/src/main/java/dev/patrickgold/florisboard/debug/Flog.kt
Normal file
366
app/src/main/java/dev/patrickgold/florisboard/debug/Flog.kt
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalContracts::class)
|
||||
|
||||
package dev.patrickgold.florisboard.debug
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
/** Type alias for a flog topic Integer. */
|
||||
typealias FlogTopic = UInt
|
||||
|
||||
/** Type alias for a flog level Integer. */
|
||||
typealias FlogLevel = UInt
|
||||
|
||||
/** Type alias for a flog output Integer. */
|
||||
typealias FlogOutput = UInt
|
||||
|
||||
/**
|
||||
* Logs an error message returned by [block] together with the automatically retrieved
|
||||
* calling class and method name either to the console or to a log file. The class name
|
||||
* is used for the tag, the method name prepended to the message.
|
||||
*
|
||||
* This method automatically evaluates if logging is enabled and calls [block] only
|
||||
* if a log message should be generated.
|
||||
*
|
||||
* Optionally a [topic] can also be specified to allow to only partially enable
|
||||
* debug messages across the codebase. The passed [topic] is compared with the
|
||||
* currently active [Flog.flogTopics] variable and only if at least 1 topic match
|
||||
* is found, [block] will be called and a log message written.
|
||||
*
|
||||
* @param topic The topic of this message. To specify multiple topics, use the binary
|
||||
* OR operator. Defaults to [Flog.TOPIC_OTHER].
|
||||
* @param block The lambda expression to evaluate the message which is appended to the
|
||||
* method name. Is called only if logging is enabled and the topics match. Must return
|
||||
* a [String]. If this argument is omitted, only the calling method name will be used
|
||||
* as the log message.
|
||||
*/
|
||||
inline fun flogError(topic: FlogTopic = Flog.TOPIC_OTHER, block: () -> String = { "" }) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (Flog.checkShouldFlog(topic, Flog.LEVEL_ERROR)) {
|
||||
Flog.log(Flog.LEVEL_ERROR, block())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a warning message returned by [block] together with the automatically retrieved
|
||||
* calling class and method name either to the console or to a log file. The class name
|
||||
* is used for the tag, the method name prepended to the message.
|
||||
*
|
||||
* This method automatically evaluates if logging is enabled and calls [block] only
|
||||
* if a log message should be generated.
|
||||
*
|
||||
* Optionally a [topic] can also be specified to allow to only partially enable
|
||||
* debug messages across the codebase. The passed [topic] is compared with the
|
||||
* currently active [Flog.flogTopics] variable and only if at least 1 topic match
|
||||
* is found, [block] will be called and a log message written.
|
||||
*
|
||||
* @param topic The topic of this message. To specify multiple topics, use the binary
|
||||
* OR operator. Defaults to [Flog.TOPIC_OTHER].
|
||||
* @param block The lambda expression to evaluate the message which is appended to the
|
||||
* method name. Is called only if logging is enabled and the topics match. Must return
|
||||
* a [String]. If this argument is omitted, only the calling method name will be used
|
||||
* as the log message.
|
||||
*/
|
||||
inline fun flogWarning(topic: FlogTopic = Flog.TOPIC_OTHER, block: () -> String = { "" }) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (Flog.checkShouldFlog(topic, Flog.LEVEL_WARNING)) {
|
||||
Flog.log(Flog.LEVEL_WARNING, block())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a info message returned by [block] together with the automatically retrieved
|
||||
* calling class and method name either to the console or to a log file. The class name
|
||||
* is used for the tag, the method name prepended to the message.
|
||||
*
|
||||
* This method automatically evaluates if logging is enabled and calls [block] only
|
||||
* if a log message should be generated.
|
||||
*
|
||||
* Optionally a [topic] can also be specified to allow to only partially enable
|
||||
* debug messages across the codebase. The passed [topic] is compared with the
|
||||
* currently active [Flog.flogTopics] variable and only if at least 1 topic match
|
||||
* is found, [block] will be called and a log message written.
|
||||
*
|
||||
* @param topic The topic of this message. To specify multiple topics, use the binary
|
||||
* OR operator. Defaults to [Flog.TOPIC_OTHER].
|
||||
* @param block The lambda expression to evaluate the message which is appended to the
|
||||
* method name. Is called only if logging is enabled and the topics match. Must return
|
||||
* a [String]. If this argument is omitted, only the calling method name will be used
|
||||
* as the log message.
|
||||
*/
|
||||
inline fun flogInfo(topic: FlogTopic = Flog.TOPIC_OTHER, block: () -> String = { "" }) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (Flog.checkShouldFlog(topic, Flog.LEVEL_INFO)) {
|
||||
Flog.log(Flog.LEVEL_INFO, block())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a debug message returned by [block] together with the automatically retrieved
|
||||
* calling class and method name either to the console or to a log file. The class name
|
||||
* is used for the tag, the method name prepended to the message.
|
||||
*
|
||||
* This method automatically evaluates if logging is enabled and calls [block] only
|
||||
* if a log message should be generated.
|
||||
*
|
||||
* Optionally a [topic] can also be specified to allow to only partially enable
|
||||
* debug messages across the codebase. The passed [topic] is compared with the
|
||||
* currently active [Flog.flogTopics] variable and only if at least 1 topic match
|
||||
* is found, [block] will be called and a log message written.
|
||||
*
|
||||
* @param topic The topic of this message. To specify multiple topics, use the binary
|
||||
* OR operator. Defaults to [Flog.TOPIC_OTHER].
|
||||
* @param block The lambda expression to evaluate the message which is appended to the
|
||||
* method name. Is called only if logging is enabled and the topics match. Must return
|
||||
* a [String]. If this argument is omitted, only the calling method name will be used
|
||||
* as the log message.
|
||||
*/
|
||||
inline fun flogDebug(topic: FlogTopic = Flog.TOPIC_OTHER, block: () -> String = { "" }) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (Flog.checkShouldFlog(topic, Flog.LEVEL_DEBUG)) {
|
||||
Flog.log(Flog.LEVEL_DEBUG, block())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a wtf message returned by [block] together with the automatically retrieved
|
||||
* calling class and method name either to the console or to a log file. The class name
|
||||
* is used for the tag, the method name prepended to the message.
|
||||
*
|
||||
* This method automatically evaluates if logging is enabled and calls [block] only
|
||||
* if a log message should be generated.
|
||||
*
|
||||
* Optionally a [topic] can also be specified to allow to only partially enable
|
||||
* debug messages across the codebase. The passed [topic] is compared with the
|
||||
* currently active [Flog.flogTopics] variable and only if at least 1 topic match
|
||||
* is found, [block] will be called and a log message written.
|
||||
*
|
||||
* @param topic The topic of this message. To specify multiple topics, use the binary
|
||||
* OR operator. Defaults to [Flog.TOPIC_OTHER].
|
||||
* @param block The lambda expression to evaluate the message which is appended to the
|
||||
* method name. Is called only if logging is enabled and the topics match. Must return
|
||||
* a [String]. If this argument is omitted, only the calling method name will be used
|
||||
* as the log message.
|
||||
*/
|
||||
inline fun flogWtf(topic: FlogTopic = Flog.TOPIC_OTHER, block: () -> String = { "" }) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (Flog.checkShouldFlog(topic, Flog.LEVEL_WTF)) {
|
||||
Flog.log(Flog.LEVEL_WTF, block())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to evaluate if a bit flag is set in an integer value.
|
||||
*
|
||||
* @param flag The flag to check if it is set.
|
||||
*
|
||||
* @return True if the flag is set, false otherwise.
|
||||
*/
|
||||
private infix fun UInt.isSet(flag: UInt): Boolean {
|
||||
return (this and flag) == flag
|
||||
}
|
||||
|
||||
/**
|
||||
* Main helper object for FlorisBoard logging (=Flog). Manages the enabled
|
||||
* state and the active topics. Provides relevant helper functions for the
|
||||
* flog methods to properly work.
|
||||
*
|
||||
* This helper object uses some parts of the Timber library to assist in
|
||||
* logging. In particular:
|
||||
* - [createTag] (converted to Kotlin, renamed from "createStackElementTag",
|
||||
* removed manual tagging).
|
||||
* - [getStacktraceElement] (converted to Kotlin, renamed from "getTag",
|
||||
* method now returns stack trace element).
|
||||
* - [log] (only the [OUTPUT_CONSOLE] part, converted to Kotlin).
|
||||
* Timber is licensed under the Apache 2.0 license, see the repo here:
|
||||
* https://github.com/JakeWharton/timber
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
object Flog {
|
||||
const val TOPIC_NONE: FlogTopic = UInt.MIN_VALUE
|
||||
const val TOPIC_OTHER: FlogTopic = 0x80000000u
|
||||
const val TOPIC_ALL: FlogTopic = UInt.MAX_VALUE
|
||||
|
||||
const val LEVEL_NONE: FlogLevel = UInt.MIN_VALUE
|
||||
const val LEVEL_ERROR: FlogLevel = 0x01u
|
||||
const val LEVEL_WARNING: FlogLevel = 0x02u
|
||||
const val LEVEL_INFO: FlogLevel = 0x04u
|
||||
const val LEVEL_DEBUG: FlogLevel = 0x08u
|
||||
const val LEVEL_WTF: FlogLevel = 0x10u
|
||||
const val LEVEL_ALL: FlogLevel = UInt.MAX_VALUE
|
||||
|
||||
const val OUTPUT_CONSOLE: FlogOutput = 0x01u
|
||||
const val OUTPUT_FILE: FlogOutput = 0x02u
|
||||
|
||||
/** The relevant call stack element is always on the 4th position, thus 4-1=3. */
|
||||
private const val CALL_STACK_INDEX: Int = 3
|
||||
|
||||
/** The maximum log length limit. */
|
||||
private const val MAX_LOG_LENGTH: Int = 4000
|
||||
|
||||
/** The maximum tag length limit. */
|
||||
private const val MAX_TAG_LENGTH: Int = 23
|
||||
|
||||
private var applicationContext: WeakReference<Context> = WeakReference(null)
|
||||
private var isFloggingEnabled: Boolean = false
|
||||
private var flogTopics: FlogTopic = TOPIC_NONE
|
||||
private var flogLevels: FlogLevel = LEVEL_NONE
|
||||
private var flogOutputs: FlogOutput = OUTPUT_CONSOLE
|
||||
|
||||
/**
|
||||
* Installs the flog utility for given [applicationContext] and sets the relevant
|
||||
* configuration variables based on the given config values.
|
||||
*
|
||||
* @param applicationContext The application context, used for file logging. The context
|
||||
* will be wrapped in a [WeakReference] to prevent memory leaks.
|
||||
* @param isFloggingEnabled If logging is enabled. If this value is false, all calls to
|
||||
* the flog methods will be ignored and no logs will be written, regardless of the topics
|
||||
* and levels set.
|
||||
* @param flogTopics The enabled topics for this installation. Use [TOPIC_ALL] to enable
|
||||
* all topics. If this value is [TOPIC_NONE], this essentially disables all logging.
|
||||
* @param flogLevels The enabled levels for this installation. Use [LEVEL_ALL] to enable
|
||||
* all levels. If this value is [LEVEL_NONE], this essentially disables all logging.
|
||||
* @param flogOutputs The enabled outputs for this installation. Use either [OUTPUT_CONSOLE]
|
||||
* for logging to Logcat or [OUTPUT_FILE] to a logging file.
|
||||
*/
|
||||
fun install(
|
||||
applicationContext: Context,
|
||||
isFloggingEnabled: Boolean,
|
||||
flogTopics: FlogTopic,
|
||||
flogLevels: FlogLevel,
|
||||
flogOutputs: FlogOutput
|
||||
) {
|
||||
this.applicationContext = WeakReference(applicationContext)
|
||||
this.isFloggingEnabled = isFloggingEnabled
|
||||
this.flogTopics = flogTopics
|
||||
this.flogLevels = flogLevels
|
||||
this.flogOutputs = flogOutputs
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a log message should be evaluated by checking [isFloggingEnabled] and
|
||||
* by matching the given [topic] and [level] values with the configured settings.
|
||||
*
|
||||
* @param topic The topic(s) to check for.
|
||||
* @param level The level(s) to check for.
|
||||
*
|
||||
* @return True if a log message should be evaluated, false otherwise.
|
||||
*/
|
||||
fun checkShouldFlog(topic: FlogTopic, level: FlogLevel): Boolean {
|
||||
return isFloggingEnabled && (flogTopics isSet topic) && (flogLevels isSet level)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the tag which should be used for the message from the `element`.
|
||||
*/
|
||||
private fun createTag(element: StackTraceElement): String {
|
||||
var tag = element.className
|
||||
tag = tag.substring(tag.lastIndexOf('.') + 1)
|
||||
// Tag length limit was removed in API 24.
|
||||
return if (tag.length <= MAX_TAG_LENGTH || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
tag
|
||||
} else {
|
||||
tag.substring(0, MAX_TAG_LENGTH)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMessage(element: StackTraceElement, msg: String): String {
|
||||
return StringBuilder().run {
|
||||
append(element.methodName)
|
||||
append('(')
|
||||
append(')')
|
||||
if (msg.isNotBlank()) {
|
||||
append(' ')
|
||||
append('-')
|
||||
append(' ')
|
||||
append(msg)
|
||||
}
|
||||
toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStacktraceElement(): StackTraceElement {
|
||||
val stackTrace = Throwable().stackTrace
|
||||
check(stackTrace.size > CALL_STACK_INDEX) {
|
||||
"Synthetic stacktrace didn't have enough elements: are you using proguard?"
|
||||
}
|
||||
return stackTrace[CALL_STACK_INDEX]
|
||||
}
|
||||
|
||||
fun log(level: FlogLevel, msg: String) {
|
||||
when {
|
||||
flogOutputs isSet OUTPUT_CONSOLE -> {
|
||||
if (msg.length < MAX_LOG_LENGTH) {
|
||||
androidLog(level, msg)
|
||||
} else {
|
||||
// Split by line, then ensure each line can fit into Log's maximum length.
|
||||
var i = 0
|
||||
val length: Int = msg.length
|
||||
while (i < length) {
|
||||
var newline: Int = msg.indexOf('\n', i)
|
||||
newline = if (newline != -1) newline else length
|
||||
do {
|
||||
val end = newline.coerceAtMost(i + MAX_LOG_LENGTH)
|
||||
val part: String = msg.substring(i, end)
|
||||
androidLog(level, part)
|
||||
i = end
|
||||
} while (i < newline)
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
flogOutputs isSet OUTPUT_FILE -> {
|
||||
fileLog(level, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun androidLog(level: FlogLevel, msg: String) {
|
||||
val ste = getStacktraceElement()
|
||||
val tag = createTag(ste)
|
||||
val message = createMessage(ste, msg)
|
||||
when {
|
||||
level isSet LEVEL_ERROR -> Log.e(tag, message)
|
||||
level isSet LEVEL_WARNING -> Log.w(tag, message)
|
||||
level isSet LEVEL_INFO -> Log.i(tag, message)
|
||||
level isSet LEVEL_DEBUG -> Log.d(tag, message)
|
||||
level isSet LEVEL_WTF -> Log.wtf(tag, message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fileLog(level: FlogLevel, msg: String) {
|
||||
val context = applicationContext.get() ?: return
|
||||
// TODO: introduce file logging here for runtime debug logging
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.patrickgold.florisboard.debug
|
||||
|
||||
/**
|
||||
* This object holds all custom log topics for the [Flog] utility.
|
||||
*
|
||||
* _Contributors:_ if you add a new feature which is relatively large, you can
|
||||
* add a new topic here, just make sure it is a 2^n value and does not
|
||||
* exceed the maximum value of [FlogTopic].
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate", "Unused")
|
||||
object LogTopic {
|
||||
const val NONE: FlogTopic = Flog.TOPIC_NONE
|
||||
const val OTHER: FlogTopic = Flog.TOPIC_OTHER
|
||||
const val ALL: FlogTopic = Flog.TOPIC_ALL
|
||||
|
||||
const val IMS_EVENTS: FlogTopic = 1u
|
||||
const val KEY_EVENTS: FlogTopic = 2u
|
||||
|
||||
const val SUBTYPE_MANAGER: FlogTopic = 4u
|
||||
const val LAYOUT_MANAGER: FlogTopic = 8u
|
||||
const val TEXT_KEYBOARD_VIEW: FlogTopic = 16u
|
||||
const val GESTURES: FlogTopic = 32u
|
||||
|
||||
const val GLIDE: FlogTopic = 512u
|
||||
const val CLIPBOARD: FlogTopic = 1024u
|
||||
const val CRASH_UTILITY: FlogTopic = 2048u
|
||||
}
|
||||
@@ -97,7 +97,7 @@ class ClipboardHistoryItemAdapter(
|
||||
viewHolder.imgView.visibility = GONE
|
||||
// For very large images, this can take a bit
|
||||
FlorisClipboardManager.getInstance().executor.execute {
|
||||
val resolver = FlorisBoard.getInstance().context.contentResolver
|
||||
val resolver = FlorisBoard.getInstance().contentResolver
|
||||
val inputStream = resolver.openInputStream(uri!!)
|
||||
|
||||
val drawable = Drawable.createFromStream(inputStream, "clipboard URI")
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package dev.patrickgold.florisboard.ime.clip
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
@@ -15,7 +13,7 @@ import dev.patrickgold.florisboard.ime.core.FlorisBoard
|
||||
import dev.patrickgold.florisboard.ime.core.InputKeyEvent
|
||||
import dev.patrickgold.florisboard.ime.core.InputView
|
||||
import dev.patrickgold.florisboard.ime.text.key.KeyCode
|
||||
import dev.patrickgold.florisboard.ime.text.key.KeyData
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.BasicTextKeyData
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.math.pow
|
||||
|
||||
@@ -23,10 +21,9 @@ import kotlin.math.pow
|
||||
* Handles the clipboard view and allows for communication between UI and logic.
|
||||
*/
|
||||
class ClipboardInputManager private constructor() : CoroutineScope by MainScope(),
|
||||
FlorisBoard.EventListener{
|
||||
FlorisBoard.EventListener {
|
||||
|
||||
private val florisboard = FlorisBoard.getInstance()
|
||||
private var repeatedKeyPressHandler: Handler? = null
|
||||
private var recyclerView: RecyclerView? = null
|
||||
private var adapter: ClipboardHistoryItemAdapter? = null
|
||||
|
||||
@@ -46,52 +43,41 @@ class ClipboardInputManager private constructor() : CoroutineScope by MainScope(
|
||||
florisboard.addEventListener(this)
|
||||
}
|
||||
|
||||
override fun onCreateInputView() {
|
||||
super.onCreateInputView()
|
||||
repeatedKeyPressHandler = Handler(florisboard.context.mainLooper)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new input view has been registered. Used to initialize all media-relevant
|
||||
* views and layouts.
|
||||
*/
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onRegisterInputView(inputView: InputView) {
|
||||
inputView.findViewById<ImageButton>(R.id.back_to_keyboard_button)
|
||||
.setOnTouchListener { view, event -> onButtonPressEvent(view, event) }
|
||||
|
||||
launch(Dispatchers.Default) {
|
||||
inputView.findViewById<ImageButton>(R.id.clear_clipboard_history)
|
||||
.setOnTouchListener { view, event -> onButtonPressEvent(view, event) }
|
||||
|
||||
inputView.findViewById<ImageButton>(R.id.back_to_keyboard_button)
|
||||
.setOnTouchListener { view, event -> onButtonPressEvent(view, event) }
|
||||
recyclerView = inputView.findViewById(R.id.clipboard_history_items)
|
||||
|
||||
inputView.findViewById<ImageButton>(R.id.clear_clipboard_history)
|
||||
.setOnTouchListener { view, event -> onButtonPressEvent(view, event) }
|
||||
|
||||
recyclerView = inputView.findViewById(R.id.clipboard_history_items)
|
||||
|
||||
if (BuildConfig.DEBUG && adapter == null) {
|
||||
error("initClipboard() not called")
|
||||
}
|
||||
|
||||
recyclerView!!.adapter = adapter
|
||||
val manager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||
recyclerView!!.layoutManager = manager
|
||||
if (BuildConfig.DEBUG && adapter == null) {
|
||||
error("initClipboard() not called")
|
||||
}
|
||||
|
||||
recyclerView!!.adapter = adapter
|
||||
val manager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||
recyclerView!!.layoutManager = manager
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean-up of resources and stopping all coroutines.
|
||||
*/
|
||||
override fun onDestroy() {
|
||||
|
||||
cancel()
|
||||
instance = null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a reference to the [ClipboardHistoryView]
|
||||
*/
|
||||
fun getClipboardHistoryView() : ClipboardHistoryView{
|
||||
fun getClipboardHistoryView(): ClipboardHistoryView {
|
||||
return FlorisBoard.getInstance().inputView?.mainViewFlipper?.getChildAt(2) as ClipboardHistoryView
|
||||
}
|
||||
|
||||
@@ -144,13 +130,14 @@ class ClipboardInputManager private constructor() : CoroutineScope by MainScope(
|
||||
* Handles clicks on the back to keyboard button.
|
||||
*/
|
||||
private fun onButtonPressEvent(view: View, event: MotionEvent?): Boolean {
|
||||
|
||||
event ?: return false
|
||||
|
||||
val data = when (view.id) {
|
||||
R.id.back_to_keyboard_button -> KeyData(code = KeyCode.SWITCH_TO_TEXT_CONTEXT)
|
||||
R.id.clear_clipboard_history -> KeyData(code = KeyCode.CLEAR_CLIPBOARD_HISTORY)
|
||||
R.id.back_to_keyboard_button -> BasicTextKeyData(code = KeyCode.SWITCH_TO_TEXT_CONTEXT)
|
||||
R.id.clear_clipboard_history -> BasicTextKeyData(code = KeyCode.CLEAR_CLIPBOARD_HISTORY)
|
||||
else -> null
|
||||
}!!
|
||||
} ?: return false
|
||||
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
florisboard.keyPressVibrate()
|
||||
@@ -176,7 +163,7 @@ class ClipboardInputManager private constructor() : CoroutineScope by MainScope(
|
||||
* @param pins The pins to link to
|
||||
*/
|
||||
fun initClipboard(dataSet: ArrayDeque<FlorisClipboardManager.TimedClipData>, pins: ArrayDeque<ClipboardItem>) {
|
||||
this.adapter = ClipboardHistoryItemAdapter(dataSet = dataSet, pins= pins)
|
||||
this.adapter = ClipboardHistoryItemAdapter(dataSet = dataSet, pins = pins)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +176,7 @@ class ClipboardInputManager private constructor() : CoroutineScope by MainScope(
|
||||
fun clearClipboardWithAnimation(start: Int, size: Int): Long {
|
||||
// list of views to animate
|
||||
val views = arrayListOf<View>()
|
||||
for(i in 0 until size){
|
||||
for (i in 0 until size) {
|
||||
recyclerView?.findViewHolderForLayoutPosition(i + start)?.let {
|
||||
views.add(it.itemView)
|
||||
}
|
||||
@@ -205,14 +192,13 @@ class ClipboardInputManager private constructor() : CoroutineScope by MainScope(
|
||||
}
|
||||
|
||||
// a little while later we reset the views so they can be reused.
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
launch(Dispatchers.Main) {
|
||||
delay(450 + delay)
|
||||
for (view in views) {
|
||||
view.translationX = 0f
|
||||
}
|
||||
}, 450 + delay)
|
||||
}
|
||||
|
||||
return 280 + delay
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import dev.patrickgold.florisboard.ime.clip.provider.*
|
||||
import dev.patrickgold.florisboard.ime.core.FlorisBoard
|
||||
import dev.patrickgold.florisboard.ime.core.PrefHelper
|
||||
import dev.patrickgold.florisboard.ime.core.Preferences
|
||||
import dev.patrickgold.florisboard.util.cancelAll
|
||||
import dev.patrickgold.florisboard.util.postAtScheduledRate
|
||||
import timber.log.Timber
|
||||
@@ -38,7 +38,6 @@ import kotlin.collections.ArrayDeque
|
||||
* [ClipboardPopupView] is the view representing a popup displayed when long pressing on a clipboard history item.
|
||||
*/
|
||||
class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryClipChangedListener, Closeable {
|
||||
|
||||
private lateinit var pinsDao: PinnedClipboardItemDao
|
||||
lateinit var executor: ExecutorService
|
||||
|
||||
@@ -50,7 +49,7 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
private var onPrimaryClipChangedListeners: ArrayList<OnPrimaryClipChangedListener> = arrayListOf()
|
||||
private lateinit var systemClipboardManager: ClipboardManager
|
||||
private lateinit var handler: Handler
|
||||
private lateinit var prefHelper: PrefHelper
|
||||
private val prefs get() = Preferences.default()
|
||||
|
||||
data class TimedClipData(val data: ClipboardItem, val timeUTC: Long)
|
||||
|
||||
@@ -102,12 +101,11 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new item to the clipboard history (if enabled).
|
||||
*/
|
||||
fun updateHistory(newData: ClipboardItem) {
|
||||
val clipboardPrefs = prefHelper.clipboard
|
||||
val clipboardPrefs = prefs.clipboard
|
||||
|
||||
if (clipboardPrefs.enableHistory) {
|
||||
if (clipboardPrefs.limitHistorySize) {
|
||||
@@ -119,12 +117,10 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
ClipboardInputManager.getInstance().notifyItemRangeRemoved(history.size, numRemoved)
|
||||
}
|
||||
|
||||
|
||||
val timed = TimedClipData(newData, System.currentTimeMillis())
|
||||
history.addFirst(timed)
|
||||
ClipboardInputManager.getInstance().notifyItemInserted(pins.size)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,14 +133,14 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
* Changes current clipboard item. WITHOUT updating the history.
|
||||
*/
|
||||
fun changeCurrent(newData: ClipboardItem, closePrevious: Boolean) {
|
||||
if (prefHelper.clipboard.enableInternal) {
|
||||
if (prefs.clipboard.enableInternal) {
|
||||
if (closePrevious) current?.close()
|
||||
current = newData
|
||||
val isEqual = when (newData.type) {
|
||||
ItemType.TEXT -> newData.text == systemClipboardManager.primaryClip?.getItemAt(0)?.text
|
||||
ItemType.IMAGE -> newData.uri == systemClipboardManager.primaryClip?.getItemAt(0)?.uri
|
||||
}
|
||||
if (prefHelper.clipboard.syncToSystem && !isEqual)
|
||||
if (prefs.clipboard.syncToSystem && !isEqual)
|
||||
systemClipboardManager.setPrimaryClip(newData.toClipData())
|
||||
} else {
|
||||
shouldUpdateHistory = false
|
||||
@@ -153,7 +149,6 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
onPrimaryClipChangedListeners.forEach { it.onPrimaryClipChanged() }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change the current text on clipboard, update history (if enabled).
|
||||
*
|
||||
@@ -161,7 +156,7 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
fun addNewClip(newData: ClipboardItem) {
|
||||
updateHistory(newData)
|
||||
// If history is disabled, this new item will replace the old one and hence should be closed.
|
||||
changeCurrent(newData, !prefHelper.clipboard.enableHistory)
|
||||
changeCurrent(newData, !prefs.clipboard.enableHistory)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,7 +168,7 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
}
|
||||
|
||||
val primaryClip: ClipboardItem?
|
||||
get() = if (prefHelper.clipboard.enableInternal) {
|
||||
get() = if (prefs.clipboard.enableInternal) {
|
||||
current
|
||||
} else {
|
||||
systemClipboardManager.primaryClip?.let { ClipboardItem.fromClipData(it, false) }
|
||||
@@ -196,37 +191,37 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
*/
|
||||
override fun onPrimaryClipChanged() {
|
||||
// Run on async thread to avoid blocking.
|
||||
if (systemClipboardManager.primaryClip?.getItemAt(0)?.text == null &&
|
||||
systemClipboardManager.primaryClip?.getItemAt(0)?.uri == null) {
|
||||
val internalPrimaryClip = primaryClip
|
||||
val systemPrimaryClip = systemClipboardManager.primaryClip
|
||||
|
||||
if (systemPrimaryClip?.getItemAt(0)?.text == null &&
|
||||
systemPrimaryClip?.getItemAt(0)?.uri == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val isEqual = when (primaryClip?.type) {
|
||||
ItemType.TEXT -> primaryClip?.text == systemClipboardManager.primaryClip?.getItemAt(0)?.text
|
||||
ItemType.IMAGE -> primaryClip?.uri == systemClipboardManager.primaryClip?.getItemAt(0)?.uri
|
||||
null -> false
|
||||
val isEqual = when (internalPrimaryClip?.type) {
|
||||
ItemType.TEXT -> internalPrimaryClip.text == systemPrimaryClip.getItemAt(0)?.text
|
||||
ItemType.IMAGE -> internalPrimaryClip.uri == systemPrimaryClip.getItemAt(0)?.uri
|
||||
else -> false
|
||||
}
|
||||
systemClipboardManager.primaryClip?.let {
|
||||
if (prefHelper.clipboard.enableInternal) {
|
||||
// In the event that the internal clipboard is enabled, sync to internal clipboard is enabled
|
||||
// and the item is not already in internal clipboard, add it.
|
||||
if (prefHelper.clipboard.syncToFloris && !isEqual) {
|
||||
addNewClip(ClipboardItem.fromClipData(it, true))
|
||||
}
|
||||
} else if (prefHelper.clipboard.enableHistory) {
|
||||
// in the event history is enabled, and it should be updated it is updated
|
||||
if (shouldUpdateHistory) {
|
||||
updateHistory(ClipboardItem.fromClipData(it, false))
|
||||
} else {
|
||||
shouldUpdateHistory = true
|
||||
}
|
||||
if (prefs.clipboard.enableInternal) {
|
||||
// In the event that the internal clipboard is enabled, sync to internal clipboard is enabled
|
||||
// and the item is not already in internal clipboard, add it.
|
||||
if (prefs.clipboard.syncToFloris && !isEqual) {
|
||||
addNewClip(ClipboardItem.fromClipData(systemPrimaryClip, true))
|
||||
}
|
||||
} else if (prefs.clipboard.enableHistory) {
|
||||
// in the event history is enabled, and it should be updated it is updated
|
||||
if (shouldUpdateHistory) {
|
||||
updateHistory(ClipboardItem.fromClipData(systemPrimaryClip, false))
|
||||
} else {
|
||||
shouldUpdateHistory = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun hasPrimaryClip(): Boolean {
|
||||
return this.primaryClip != null
|
||||
return primaryClip != null
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,28 +237,24 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
|
||||
/**
|
||||
* Initialize the floris clipboard manager. Exists to avoid dependency loop due to reference
|
||||
* to [FlorisBoard.context]
|
||||
* to [FlorisBoard].
|
||||
*
|
||||
* Sets up the clipboard cleanup task, links the recycler view in clipInputManager to [history].
|
||||
*
|
||||
* @param context Required to register as an onPrimaryClipChangedListener of ClipboardManager
|
||||
*/
|
||||
fun initialize(context: Context) {
|
||||
|
||||
this.systemClipboardManager = (context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager)
|
||||
systemClipboardManager = (context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager)
|
||||
systemClipboardManager.addPrimaryClipChangedListener(this)
|
||||
|
||||
prefHelper = PrefHelper.getDefaultInstance(context)
|
||||
|
||||
val cleanUpClipboard = Runnable {
|
||||
|
||||
if (!prefHelper.clipboard.cleanUpOld) {
|
||||
if (!prefs.clipboard.cleanUpOld) {
|
||||
return@Runnable
|
||||
}
|
||||
|
||||
val currentTime = System.currentTimeMillis()
|
||||
var numToPop = 0
|
||||
val expiryTime = prefHelper.clipboard.cleanUpAfter * 60 * 1000
|
||||
val expiryTime = prefs.clipboard.cleanUpAfter * 60 * 1000
|
||||
for (item in history.asReversed()) {
|
||||
if (item.timeUTC + expiryTime < currentTime) {
|
||||
numToPop += 1
|
||||
@@ -278,7 +269,7 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
}
|
||||
FlorisBoard.getInstance().clipInputManager.initClipboard(this.history, this.pins)
|
||||
handler = Handler(Looper.getMainLooper())
|
||||
prefHelper
|
||||
prefs
|
||||
handler.postAtScheduledRate(0, INTERVAL, cleanUpClipboard)
|
||||
executor = FlorisBoard.getInstance().asyncExecutor
|
||||
executor.execute {
|
||||
@@ -288,7 +279,6 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the history with an animation.
|
||||
*/
|
||||
@@ -341,7 +331,7 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
val clipInputManager = FlorisBoard.getInstance().clipInputManager
|
||||
val item = pins.removeAt(adapterPos)
|
||||
|
||||
val clipboardPrefs = prefHelper.clipboard
|
||||
val clipboardPrefs = prefs.clipboard
|
||||
if (clipboardPrefs.limitHistorySize) {
|
||||
var numRemoved = 0
|
||||
while (history.size >= clipboardPrefs.maxHistorySize) {
|
||||
@@ -400,6 +390,4 @@ class FlorisClipboardManager private constructor() : ClipboardManager.OnPrimaryC
|
||||
}
|
||||
} == true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +1,39 @@
|
||||
package dev.patrickgold.florisboard.ime.clip.provider
|
||||
|
||||
import android.net.Uri
|
||||
import dev.patrickgold.florisboard.debug.*
|
||||
import dev.patrickgold.florisboard.ime.core.FlorisBoard
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
/**
|
||||
* Backend class which is used by [FlorisContentProvider] to serve content.
|
||||
* Backend helper object which is used by [FlorisContentProvider] to serve content.
|
||||
*/
|
||||
class FileStorage private constructor() {
|
||||
|
||||
|
||||
companion object {
|
||||
private const val BUF_SIZE = 1024 * 8
|
||||
private var instance: FileStorage? = null
|
||||
private var offset = 0
|
||||
|
||||
|
||||
fun getInstance() : FileStorage {
|
||||
if (this.instance == null){
|
||||
this.instance = FileStorage()
|
||||
}
|
||||
return instance!!
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object FileStorage {
|
||||
private const val BUF_SIZE = 1024 * 8
|
||||
private var offset = 0
|
||||
|
||||
/**
|
||||
* Clones a content URI to internal storage.
|
||||
*
|
||||
* @param uri The URI
|
||||
* @return the file's name which is a unique long
|
||||
* @return The file's name which is a unique long
|
||||
*/
|
||||
@Synchronized
|
||||
fun cloneURI(uri: Uri) : Long {
|
||||
val context = FlorisBoard.getInstance().context
|
||||
fun cloneURI(uri: Uri): Result<Long> {
|
||||
val context = FlorisBoard.getInstance()
|
||||
// nanoTime + the number of items created so that it's unique.
|
||||
val name = (System.nanoTime() + offset)
|
||||
|
||||
// Just a normal copy from input stream to output stream.
|
||||
val source = context.contentResolver.openInputStream(uri)!!
|
||||
val source: InputStream
|
||||
try {
|
||||
source = context.contentResolver.openInputStream(uri) ?: return Result.failure(
|
||||
NullPointerException("Input stream for given URI '$uri' is null!")
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
return Result.failure(e)
|
||||
}
|
||||
val sink = File(context.filesDir, name.toString()).outputStream()
|
||||
var nread = 0L
|
||||
val buf = ByteArray(BUF_SIZE)
|
||||
@@ -52,14 +46,14 @@ class FileStorage private constructor() {
|
||||
source.close()
|
||||
sink.close()
|
||||
|
||||
return name
|
||||
return Result.success(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the file corresponding to an id.
|
||||
*/
|
||||
fun deleteById(id: Long) {
|
||||
Timber.d("Cleaning up $id")
|
||||
flogDebug(LogTopic.CLIPBOARD) { "Cleaning up $id" }
|
||||
val file = File(FlorisBoard.getInstance().filesDir, id.toString())
|
||||
file.delete()
|
||||
}
|
||||
@@ -70,6 +64,4 @@ class FileStorage private constructor() {
|
||||
fun getAddress(id: Long): String {
|
||||
return FlorisBoard.getInstance().filesDir.toString() + "/$id"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,10 +6,13 @@ import android.net.Uri
|
||||
import android.os.ParcelFileDescriptor
|
||||
import androidx.room.Room
|
||||
import dev.patrickgold.florisboard.BuildConfig
|
||||
import dev.patrickgold.florisboard.ime.core.FlorisBoard
|
||||
import dev.patrickgold.florisboard.debug.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.util.concurrent.ExecutorService
|
||||
|
||||
/**
|
||||
* Allows apps to access images on the clipboard.
|
||||
@@ -20,7 +23,27 @@ import java.util.concurrent.ExecutorService
|
||||
class FlorisContentProvider : ContentProvider() {
|
||||
private lateinit var fileUriDao: FileUriDao
|
||||
private val mimeTypes: HashMap<Long, Array<String>> = hashMapOf()
|
||||
private lateinit var executor: ExecutorService
|
||||
private val ioScope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
||||
companion object {
|
||||
const val AUTHORITY = "${BuildConfig.APPLICATION_ID}.provider.clip"
|
||||
val CONTENT_URI: Uri = Uri.parse("content://$AUTHORITY")
|
||||
val CLIPS_URI: Uri = Uri.parse("content://$AUTHORITY/clips")
|
||||
|
||||
private var instance: FlorisContentProvider? = null
|
||||
|
||||
fun getInstance(): FlorisContentProvider {
|
||||
return instance!!
|
||||
}
|
||||
|
||||
private const val CLIPS_TABLE = 1
|
||||
private const val CLIP_ITEM = 0
|
||||
|
||||
val matcher: UriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
|
||||
addURI(AUTHORITY, "clips/#", CLIP_ITEM)
|
||||
addURI(AUTHORITY, "clips", CLIPS_TABLE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(): Boolean {
|
||||
instance = this
|
||||
@@ -32,13 +55,11 @@ class FlorisContentProvider : ContentProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
fileUriDao = Room.databaseBuilder(
|
||||
context!!,
|
||||
FileUriDatabase::class.java, "fileuridb"
|
||||
).build().fileUriDao()
|
||||
|
||||
executor = FlorisBoard.getInstance().asyncExecutor
|
||||
for (fileUri in fileUriDao.getAll()) {
|
||||
mimeTypes[fileUri.fileName] = fileUri.mimeTypes
|
||||
}
|
||||
@@ -65,7 +86,7 @@ class FlorisContentProvider : ContentProvider() {
|
||||
|
||||
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor {
|
||||
val id = ContentUris.parseId(uri)
|
||||
val path = File(FileStorage.getInstance().getAddress(id))
|
||||
val path = File(FileStorage.getAddress(id))
|
||||
|
||||
// Nothing has permission to write anyway.
|
||||
return ParcelFileDescriptor.open(path, ParcelFileDescriptor.MODE_READ_ONLY)
|
||||
@@ -74,16 +95,18 @@ class FlorisContentProvider : ContentProvider() {
|
||||
override fun insert(uri: Uri, values: ContentValues?): Uri {
|
||||
when (matcher.match(uri)){
|
||||
CLIPS_TABLE -> {
|
||||
val id = FileStorage.getInstance().cloneURI(Uri.parse(values?.getAsString("uri")))
|
||||
val id = FileStorage.cloneURI(Uri.parse(values?.getAsString("uri"))).getOrElse {
|
||||
flogError(LogTopic.CLIPBOARD) { it.toString() }
|
||||
return uri.buildUpon().appendPath("0").build()
|
||||
}
|
||||
val mimes = values?.getAsString("mimetypes")?.split(",")?.toTypedArray()
|
||||
mimes?.let {
|
||||
mimeTypes[id] = mimes
|
||||
executor.execute {
|
||||
ioScope.launch {
|
||||
Timber.d("Inserted file uri $id")
|
||||
fileUriDao.insert(FileUri(id, mimes))
|
||||
}
|
||||
}
|
||||
|
||||
return ContentUris.withAppendedId(CLIPS_URI, id)
|
||||
}
|
||||
else -> throw IllegalArgumentException("Don't know what this is $uri")
|
||||
@@ -94,10 +117,10 @@ class FlorisContentProvider : ContentProvider() {
|
||||
when (matcher.match(uri)){
|
||||
CLIP_ITEM -> {
|
||||
val id = ContentUris.parseId(uri)
|
||||
FileStorage.getInstance().deleteById(id)
|
||||
FileStorage.deleteById(id)
|
||||
mimeTypes.remove(id)
|
||||
context?.revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
executor.execute {
|
||||
ioScope.launch {
|
||||
fileUriDao.delete(id)
|
||||
}
|
||||
return 1
|
||||
@@ -109,23 +132,4 @@ class FlorisContentProvider : ContentProvider() {
|
||||
override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?): Int {
|
||||
throw IllegalArgumentException("This ContentProvider does not support update.")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var instance: FlorisContentProvider? = null
|
||||
const val AUTHORITY = "${BuildConfig.APPLICATION_ID}.provider.clip"
|
||||
val CONTENT_URI: Uri = Uri.parse("content://$AUTHORITY")
|
||||
val CLIPS_URI: Uri = Uri.parse("content://$AUTHORITY/clips")
|
||||
|
||||
fun getInstance(): FlorisContentProvider {
|
||||
return instance!!
|
||||
}
|
||||
|
||||
private const val CLIPS_TABLE = 1
|
||||
private const val CLIP_ITEM = 0
|
||||
|
||||
val matcher: UriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
|
||||
addURI(AUTHORITY, "clips/#", CLIP_ITEM)
|
||||
addURI(AUTHORITY, "clips", CLIPS_TABLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import android.content.ContentValues
|
||||
import android.net.Uri
|
||||
import android.provider.BaseColumns
|
||||
import androidx.room.*
|
||||
import dev.patrickgold.florisboard.ime.clip.FlorisClipboardManager
|
||||
import dev.patrickgold.florisboard.ime.core.FlorisBoard
|
||||
import java.io.Closeable
|
||||
|
||||
|
||||
enum class ItemType(val value: Int) {
|
||||
TEXT(1),
|
||||
IMAGE(2);
|
||||
@@ -20,7 +20,6 @@ enum class ItemType(val value: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents an item on the clipboard.
|
||||
* The URI stored belongs to FlorisContentProvider, not whatever app copied the image
|
||||
@@ -43,7 +42,7 @@ data class ClipboardItem(
|
||||
fun toClipData(): ClipData {
|
||||
return when (type) {
|
||||
ItemType.IMAGE -> {
|
||||
ClipData.newUri(FlorisBoard.getInstance().context.contentResolver, "Clipboard data", uri)
|
||||
ClipData.newUri(FlorisBoard.getInstance().contentResolver, "Clipboard data", uri)
|
||||
}
|
||||
ItemType.TEXT -> {
|
||||
ClipData.newPlainText("Clipboard data", text)
|
||||
@@ -56,7 +55,7 @@ data class ClipboardItem(
|
||||
*/
|
||||
override fun close() {
|
||||
if (type == ItemType.IMAGE) {
|
||||
FlorisBoard.getInstance().context.contentResolver.delete(this.uri!!, null, null)
|
||||
FlorisBoard.getInstance().contentResolver.delete(this.uri!!, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,12 +104,10 @@ data class ClipboardItem(
|
||||
* @param cloneUri Whether to store the image using [FlorisContentProvider].
|
||||
*/
|
||||
fun fromClipData(data: ClipData, cloneUri: Boolean) : ClipboardItem {
|
||||
|
||||
val type = when {
|
||||
data.getItemAt(0)?.uri != null -> ItemType.IMAGE
|
||||
data.getItemAt(0)?.text != null -> ItemType.TEXT
|
||||
else -> null
|
||||
}!!
|
||||
data.getItemAt(0)?.uri != null && data.description.hasMimeType("image/*") -> ItemType.IMAGE
|
||||
else -> ItemType.TEXT
|
||||
}
|
||||
|
||||
val uri = if (type == ItemType.IMAGE) {
|
||||
if (data.getItemAt(0).uri.authority == FlorisContentProvider.CONTENT_URI.authority || !cloneUri){
|
||||
@@ -120,11 +117,11 @@ data class ClipboardItem(
|
||||
put("uri", data.getItemAt(0).uri.toString())
|
||||
put("mimetypes", data.description.filterMimeTypes("*/*").joinToString(","))
|
||||
}
|
||||
FlorisBoard.getInstance().context.contentResolver.insert(FlorisContentProvider.CLIPS_URI, values)
|
||||
FlorisBoard.getInstance().contentResolver.insert(FlorisContentProvider.CLIPS_URI, values)
|
||||
}
|
||||
} else { null }
|
||||
|
||||
val text = data.getItemAt(0).text?.toString()
|
||||
val text = FlorisBoard.getInstanceOrNull()?.let { data.getItemAt(0).coerceToText(it).toString() } ?: "#ERROR"
|
||||
val mimeTypes = when (type) {
|
||||
ItemType.IMAGE -> {
|
||||
(0 until data.description.mimeTypeCount).map {
|
||||
@@ -174,7 +171,6 @@ class Converters {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Dao
|
||||
interface PinnedClipboardItemDao {
|
||||
@Query("SELECT * FROM pins")
|
||||
@@ -199,7 +195,7 @@ abstract class PinnedItemsDatabase : RoomDatabase() {
|
||||
|
||||
if (instance == null) {
|
||||
instance = Room.databaseBuilder(
|
||||
FlorisBoard.getInstance().context,
|
||||
FlorisBoard.getInstance(),
|
||||
PinnedItemsDatabase::class.java,
|
||||
"pins").build()
|
||||
}
|
||||
|
||||
@@ -28,11 +28,13 @@ import android.view.KeyEvent
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputConnection
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.text.isDigitsOnly
|
||||
import androidx.core.view.inputmethod.InputConnectionCompat
|
||||
import androidx.core.view.inputmethod.InputContentInfoCompat
|
||||
import dev.patrickgold.florisboard.ime.clip.FlorisClipboardManager
|
||||
import dev.patrickgold.florisboard.ime.clip.provider.ClipboardItem
|
||||
import dev.patrickgold.florisboard.ime.clip.provider.ItemType
|
||||
import dev.patrickgold.florisboard.ime.text.TextInputManager
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
@@ -91,7 +93,9 @@ class EditorInstance private constructor(
|
||||
}
|
||||
|
||||
fun from(editorInfo: EditorInfo?, ims: InputMethodService?): EditorInstance {
|
||||
return if (editorInfo == null) { default() } else {
|
||||
return if (editorInfo == null) {
|
||||
default()
|
||||
} else {
|
||||
EditorInstance(
|
||||
ims = ims,
|
||||
imeOptions = ImeOptions.fromImeOptionsInt(editorInfo.imeOptions),
|
||||
@@ -213,38 +217,23 @@ class EditorInstance private constructor(
|
||||
/**
|
||||
* Commit a word generated by a gesture.
|
||||
*/
|
||||
fun commitGesture(text: String): Boolean{
|
||||
fun commitGesture(text: String): Boolean {
|
||||
val ic = inputConnection ?: return false
|
||||
return if (isRawInputEditor) {
|
||||
false
|
||||
} else {
|
||||
ic.beginBatchEdit()
|
||||
ic.finishComposingText()
|
||||
if (selection.start > 0 && getTextBeforeCursor(1).isNotBlank()) {
|
||||
ic.commitText(" ", 1)
|
||||
if (selection.start > 0) {
|
||||
val previous = getTextBeforeCursor(1)
|
||||
if (CachedInput.isWordComponent(previous) ||
|
||||
previous.isDigitsOnly() ||
|
||||
previous in TextInputManager.getInstance().symbolsWithSpaceAfter
|
||||
) {
|
||||
ic.commitText(" ", 1)
|
||||
}
|
||||
}
|
||||
ic.commitText(text, 1)
|
||||
isPhantomSpaceActive = true
|
||||
wasPhantomSpaceActiveLastUpdate = false
|
||||
ic.endBatchEdit()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the previous word with the given [text]. Used to correct gestures.
|
||||
*/
|
||||
fun commitGestureCorrection(text: String): Boolean {
|
||||
val ic = inputConnection ?: return false
|
||||
return if (isRawInputEditor) {
|
||||
false
|
||||
} else {
|
||||
ic.beginBatchEdit()
|
||||
markComposingRegion(Region(this, cachedInput.getWordForIndex(-1).start, cachedInput.getWordForIndex(-1).end))
|
||||
ic.commitText(text, 1)
|
||||
markComposingRegion(null)
|
||||
isPhantomSpaceActive = true
|
||||
wasPhantomSpaceActiveLastUpdate = false
|
||||
ic.endBatchEdit()
|
||||
true
|
||||
}
|
||||
@@ -260,7 +249,7 @@ class EditorInstance private constructor(
|
||||
*/
|
||||
fun commitClipboardItem(item: ClipboardItem): Boolean {
|
||||
val mimeTypes = item.mimeTypes
|
||||
return when (item.type){
|
||||
return when (item.type) {
|
||||
ItemType.IMAGE -> {
|
||||
val inputContentInfo = InputContentInfoCompat(
|
||||
item.uri!!,
|
||||
@@ -272,8 +261,12 @@ class EditorInstance private constructor(
|
||||
var flags = 0
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
flags = flags or InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION
|
||||
}else {
|
||||
FlorisBoard.getInstance().context.grantUriPermission(editorInfo.packageName, item.uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
} else {
|
||||
FlorisBoard.getInstance().grantUriPermission(
|
||||
editorInfo.packageName,
|
||||
item.uri,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
}
|
||||
InputConnectionCompat.commitContent(ic, editorInfo, inputContentInfo, flags, null)
|
||||
}
|
||||
@@ -283,7 +276,6 @@ class EditorInstance private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes a backward delete on this editor's text. If a text selection is active, all
|
||||
* characters inside this selection will be removed, else only the left-most character from
|
||||
@@ -317,13 +309,18 @@ class EditorInstance private constructor(
|
||||
markComposingRegion(null)
|
||||
|
||||
try {
|
||||
getWordsInString(cachedInput.rawText.substring(0,
|
||||
(selection.start - cachedInput.offset).coerceAtLeast(0))).run {
|
||||
getWordsInString(
|
||||
cachedInput.rawText.substring(
|
||||
0,
|
||||
(selection.start - cachedInput.offset).coerceAtLeast(0)
|
||||
)
|
||||
).run {
|
||||
get(size - n.coerceAtLeast(0)).range
|
||||
}.run {
|
||||
ic.setSelection(first + cachedInput.offset, selection.start)
|
||||
}
|
||||
} catch (e: Exception) {}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
|
||||
ic.commitText("", 1)
|
||||
|
||||
@@ -372,7 +369,7 @@ class EditorInstance private constructor(
|
||||
* @param string String to select words from
|
||||
* @return Words in [string] as a List of [MatchResult]
|
||||
*/
|
||||
private fun getWordsInString(string: String):List<MatchResult>{
|
||||
private fun getWordsInString(string: String): List<MatchResult> {
|
||||
val wordRegexPattern = "[\\p{L}]+".toRegex()
|
||||
return wordRegexPattern.findAll(
|
||||
string
|
||||
@@ -384,14 +381,15 @@ class EditorInstance private constructor(
|
||||
*
|
||||
* @return True on success, false if no new words are selected.
|
||||
*/
|
||||
fun leftAppendWordToSelection(): Boolean{
|
||||
fun leftAppendWordToSelection(): Boolean {
|
||||
isPhantomSpaceActive = false
|
||||
wasPhantomSpaceActiveLastUpdate = false
|
||||
// no words left to select
|
||||
if (selection.start <= 0) {
|
||||
return false
|
||||
}
|
||||
val stringBeforeSelection = cachedInput.rawText.substring(0, (selection.start - cachedInput.offset).coerceAtLeast(0))
|
||||
val stringBeforeSelection =
|
||||
cachedInput.rawText.substring(0, (selection.start - cachedInput.offset).coerceAtLeast(0))
|
||||
getWordsInString(stringBeforeSelection).last().range.apply {
|
||||
selection.updateAndNotify(first + cachedInput.offset, selection.end)
|
||||
}
|
||||
@@ -403,7 +401,7 @@ class EditorInstance private constructor(
|
||||
*
|
||||
* @return True on success, false if no new words are deselected.
|
||||
*/
|
||||
fun leftPopWordFromSelection(): Boolean{
|
||||
fun leftPopWordFromSelection(): Boolean {
|
||||
isPhantomSpaceActive = false
|
||||
wasPhantomSpaceActiveLastUpdate = false
|
||||
// no words left to pop
|
||||
@@ -667,6 +665,7 @@ class ImeOptions private constructor(imeOptions: Int) {
|
||||
val flagNoEnterAction: Boolean = imeOptions and EditorInfo.IME_FLAG_NO_ENTER_ACTION > 0
|
||||
val flagNoExtractUi: Boolean = imeOptions and EditorInfo.IME_FLAG_NO_EXTRACT_UI > 0
|
||||
val flagNoFullscreen: Boolean = imeOptions and EditorInfo.IME_FLAG_NO_FULLSCREEN > 0
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
val flagNoPersonalizedLearning: Boolean = imeOptions and EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING > 0
|
||||
|
||||
@@ -886,12 +885,15 @@ open class Region(
|
||||
/** The start marker for this region. */
|
||||
var start: Int = initStart ?: -1
|
||||
private set
|
||||
|
||||
/** The end marker for this region. */
|
||||
var end: Int = initEnd ?: -1
|
||||
private set
|
||||
|
||||
/** Returns true if the region's start and end markers are valid, false otherwise. */
|
||||
val isValid: Boolean
|
||||
get() = start >= 0 && end >= 0 && length >= 0
|
||||
|
||||
/** The length of the region. */
|
||||
val length: Int
|
||||
get() = end - start
|
||||
@@ -906,7 +908,9 @@ open class Region(
|
||||
val eiText = editorInstance.cachedInput.rawText
|
||||
val eiStart = (start - editorInstance.cachedInput.offset).coerceIn(0, eiText.length)
|
||||
val eiEnd = (end - editorInstance.cachedInput.offset).coerceIn(0, eiText.length)
|
||||
return if (!isValid || eiEnd - eiStart <= 0) { "" } else {
|
||||
return if (!isValid || eiEnd - eiStart <= 0) {
|
||||
""
|
||||
} else {
|
||||
eiText.substring(eiStart, eiEnd)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,7 @@ abstract class FlorisActivity<V : ViewBinding> : AppCompatActivity(), CoroutineS
|
||||
private var _binding: V? = null
|
||||
protected val binding: V
|
||||
get() = _binding!!
|
||||
|
||||
private var _prefs: PrefHelper? = null
|
||||
protected val prefs: PrefHelper
|
||||
get() = _prefs!!
|
||||
protected val prefs: Preferences get() = Preferences.default()
|
||||
|
||||
private var errorDialog: AlertDialog? = null
|
||||
private var errorSnackbar: Snackbar? = null
|
||||
@@ -48,7 +45,6 @@ abstract class FlorisActivity<V : ViewBinding> : AppCompatActivity(), CoroutineS
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
_prefs = PrefHelper.getDefaultInstance(applicationContext)
|
||||
onCreateBinding().let {
|
||||
_binding = it
|
||||
setContentView(it.root)
|
||||
@@ -59,7 +55,6 @@ abstract class FlorisActivity<V : ViewBinding> : AppCompatActivity(), CoroutineS
|
||||
super.onDestroy()
|
||||
cancel()
|
||||
_binding = null
|
||||
_prefs = null
|
||||
errorDialog?.dismiss()
|
||||
errorDialog = null
|
||||
errorSnackbar?.dismiss()
|
||||
@@ -102,7 +97,7 @@ abstract class FlorisActivity<V : ViewBinding> : AppCompatActivity(), CoroutineS
|
||||
errorDialog?.dismiss()
|
||||
errorDialog = AlertDialog.Builder(this@FlorisActivity).run {
|
||||
setTitle(R.string.assets__error__details)
|
||||
setMessage(errorThrowable.toString())
|
||||
setMessage(errorThrowable?.stackTraceToString())
|
||||
setPositiveButton(android.R.string.ok, null)
|
||||
setNeutralButton(R.string.crash_dialog__copy_to_clipboard) { _, _ ->
|
||||
val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE)
|
||||
|
||||
@@ -19,6 +19,8 @@ package dev.patrickgold.florisboard.ime.core
|
||||
import android.app.Application
|
||||
import dev.patrickgold.florisboard.BuildConfig
|
||||
import dev.patrickgold.florisboard.crashutility.CrashUtility
|
||||
import dev.patrickgold.florisboard.debug.Flog
|
||||
import dev.patrickgold.florisboard.debug.LogTopic
|
||||
import dev.patrickgold.florisboard.ime.dictionary.DictionaryManager
|
||||
import dev.patrickgold.florisboard.ime.extension.AssetManager
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeManager
|
||||
@@ -26,17 +28,26 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import timber.log.Timber
|
||||
|
||||
@Suppress("unused")
|
||||
class FlorisApplication : Application(), CoroutineScope by MainScope() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(Timber.DebugTree())
|
||||
}
|
||||
Flog.install(
|
||||
applicationContext = this,
|
||||
isFloggingEnabled = BuildConfig.DEBUG,
|
||||
flogTopics = LogTopic.ALL,
|
||||
flogLevels = Flog.LEVEL_ALL,
|
||||
flogOutputs = Flog.OUTPUT_CONSOLE
|
||||
)
|
||||
CrashUtility.install(this)
|
||||
val prefHelper = PrefHelper.getDefaultInstance(this)
|
||||
val prefs = Preferences.initDefault(this)
|
||||
val assetManager = AssetManager.init(this)
|
||||
SubtypeManager.init(this)
|
||||
DictionaryManager.init(this)
|
||||
ThemeManager.init(this, assetManager, prefHelper)
|
||||
prefHelper.initDefaultPreferences()
|
||||
ThemeManager.init(this, assetManager)
|
||||
prefs.initDefaultPreferences()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,39 +25,40 @@ import android.inputmethodservice.ExtractEditText
|
||||
import android.inputmethodservice.InputMethodService
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.provider.Settings
|
||||
import android.view.*
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputConnection
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Button
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.StyleRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.lifecycle.*
|
||||
import com.squareup.moshi.Json
|
||||
import dev.patrickgold.florisboard.BuildConfig
|
||||
import dev.patrickgold.florisboard.R
|
||||
import dev.patrickgold.florisboard.debug.*
|
||||
import dev.patrickgold.florisboard.ime.clip.ClipboardInputManager
|
||||
import dev.patrickgold.florisboard.ime.clip.FlorisClipboardManager
|
||||
import dev.patrickgold.florisboard.ime.keyboard.KeyData
|
||||
import dev.patrickgold.florisboard.ime.landscapeinput.LandscapeInputUiMode
|
||||
import dev.patrickgold.florisboard.ime.media.MediaInputManager
|
||||
import dev.patrickgold.florisboard.ime.onehanded.OneHandedMode
|
||||
import dev.patrickgold.florisboard.ime.popup.PopupLayerView
|
||||
import dev.patrickgold.florisboard.ime.text.TextInputManager
|
||||
import dev.patrickgold.florisboard.ime.text.gestures.SwipeAction
|
||||
import dev.patrickgold.florisboard.ime.text.key.CurrencySet
|
||||
import dev.patrickgold.florisboard.ime.text.key.KeyCode
|
||||
import dev.patrickgold.florisboard.ime.text.key.KeyData
|
||||
import dev.patrickgold.florisboard.ime.text.key.*
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.KeyboardMode
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
|
||||
import dev.patrickgold.florisboard.ime.theme.Theme
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeManager
|
||||
import dev.patrickgold.florisboard.setup.SetupActivity
|
||||
import dev.patrickgold.florisboard.util.*
|
||||
import timber.log.Timber
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.ExecutorService
|
||||
@@ -66,6 +67,8 @@ import java.util.concurrent.Executors
|
||||
/**
|
||||
* Variable which holds the current [FlorisBoard] instance. To get this instance from another
|
||||
* package, see [FlorisBoard.getInstance].
|
||||
* TODO: The end goal is to have no static field for service/manager class anymore. This will take a long time to
|
||||
* rework the codebase but it should be doable.
|
||||
*/
|
||||
private var florisboardInstance: FlorisBoard? = null
|
||||
|
||||
@@ -76,12 +79,20 @@ private var florisboardInstance: FlorisBoard? = null
|
||||
class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager.OnPrimaryClipChangedListener,
|
||||
ThemeManager.OnThemeUpdatedListener {
|
||||
|
||||
lateinit var prefs: PrefHelper
|
||||
private set
|
||||
|
||||
val context: Context
|
||||
get() = inputWindowView?.context ?: this
|
||||
private val serviceLifecycleDispatcher: ServiceLifecycleDispatcher = ServiceLifecycleDispatcher(this)
|
||||
private val uiScope: LifecycleCoroutineScope
|
||||
get() = lifecycle.coroutineScope
|
||||
private var devtoolsOverlaySyncJob: Job? = null
|
||||
|
||||
/**
|
||||
* The theme context for the UI. Must only be used for inflating/creating Views for the keyboard UI, else the IME
|
||||
* service class should be used directly.
|
||||
*/
|
||||
private var _themeContext: Context? = null
|
||||
val themeContext: Context
|
||||
get() = _themeContext ?: this
|
||||
|
||||
private val prefs: Preferences get() = Preferences.default()
|
||||
|
||||
private var extractEditLayout: WeakReference<ViewGroup?> = WeakReference(null)
|
||||
var inputView: InputView? = null
|
||||
@@ -92,11 +103,10 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
private var eventListeners: CopyOnWriteArrayList<EventListener> = CopyOnWriteArrayList()
|
||||
|
||||
private var audioManager: AudioManager? = null
|
||||
var imeManager:InputMethodManager? = null
|
||||
var imeManager: InputMethodManager? = null
|
||||
var florisClipboardManager: FlorisClipboardManager? = null
|
||||
private val themeManager: ThemeManager = ThemeManager.default()
|
||||
private var vibrator: Vibrator? = null
|
||||
private val osHandler = Handler()
|
||||
|
||||
private var internalBatchNestingLevel: Int = 0
|
||||
private val internalSelectionCache = object {
|
||||
@@ -111,7 +121,7 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
|
||||
var activeEditorInstance: EditorInstance = EditorInstance.default()
|
||||
|
||||
lateinit var subtypeManager: SubtypeManager
|
||||
val subtypeManager: SubtypeManager get() = SubtypeManager.default()
|
||||
lateinit var activeSubtype: Subtype
|
||||
private var currentThemeIsNight: Boolean = false
|
||||
private var currentThemeResId: Int = 0
|
||||
@@ -135,48 +145,6 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
lateinit var asyncExecutor: ExecutorService
|
||||
|
||||
companion object {
|
||||
private const val IME_ID: String = "dev.patrickgold.florisboard/.ime.core.FlorisBoard"
|
||||
private const val IME_ID_BETA: String = "dev.patrickgold.florisboard.beta/dev.patrickgold.florisboard.ime.core.FlorisBoard"
|
||||
private const val IME_ID_DEBUG: String = "dev.patrickgold.florisboard.debug/dev.patrickgold.florisboard.ime.core.FlorisBoard"
|
||||
|
||||
fun checkIfImeIsEnabled(context: Context): Boolean {
|
||||
val activeImeIds = Settings.Secure.getString(
|
||||
context.contentResolver,
|
||||
Settings.Secure.ENABLED_INPUT_METHODS
|
||||
) ?: "(none)"
|
||||
Timber.i("List of active IMEs: $activeImeIds")
|
||||
return when {
|
||||
BuildConfig.DEBUG -> {
|
||||
activeImeIds.split(":").contains(IME_ID_DEBUG)
|
||||
}
|
||||
context.packageName.endsWith(".beta") -> {
|
||||
activeImeIds.split(":").contains(IME_ID_BETA)
|
||||
}
|
||||
else -> {
|
||||
activeImeIds.split(":").contains(IME_ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkIfImeIsSelected(context: Context): Boolean {
|
||||
val selectedImeId = Settings.Secure.getString(
|
||||
context.contentResolver,
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD
|
||||
) ?: "(none)"
|
||||
Timber.i("Selected IME: $selectedImeId")
|
||||
return when {
|
||||
BuildConfig.DEBUG -> {
|
||||
selectedImeId == IME_ID_DEBUG
|
||||
}
|
||||
context.packageName.endsWith(".beta") -> {
|
||||
selectedImeId.split(":").contains(IME_ID_BETA)
|
||||
}
|
||||
else -> {
|
||||
selectedImeId == IME_ID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getInstance(): FlorisBoard {
|
||||
return florisboardInstance!!
|
||||
@@ -199,6 +167,10 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
return serviceLifecycleDispatcher.lifecycle
|
||||
}
|
||||
|
||||
private fun updateThemeContext(@StyleRes themeId: Int) {
|
||||
_themeContext = ContextThemeWrapper(this, themeId)
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
/*if (BuildConfig.DEBUG) {
|
||||
StrictMode.setThreadPolicy(
|
||||
@@ -218,16 +190,13 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
.build()
|
||||
)
|
||||
}*/
|
||||
Timber.i("onCreate()")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
serviceLifecycleDispatcher.onServicePreSuperOnCreate()
|
||||
|
||||
imeManager = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
||||
audioManager = getSystemService(Context.AUDIO_SERVICE) as? AudioManager
|
||||
vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
|
||||
prefs = PrefHelper.getDefaultInstance(this)
|
||||
prefs.initDefaultPreferences()
|
||||
vibrator = getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator
|
||||
prefs.sync()
|
||||
subtypeManager = SubtypeManager(this, prefs)
|
||||
activeSubtype = subtypeManager.getActiveSubtype() ?: Subtype.DEFAULT
|
||||
|
||||
currentThemeIsNight = themeManager.activeTheme.isNightTheme
|
||||
@@ -239,9 +208,10 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
AppVersionUtils.updateVersionOnInstallAndLastUse(this, prefs)
|
||||
|
||||
asyncExecutor = Executors.newSingleThreadExecutor()
|
||||
florisClipboardManager = FlorisClipboardManager.getInstance()
|
||||
florisClipboardManager!!.initialize(context)
|
||||
florisClipboardManager?.addPrimaryClipChangedListener(this)
|
||||
florisClipboardManager = FlorisClipboardManager.getInstance().also {
|
||||
it.initialize(this)
|
||||
it.addPrimaryClipChangedListener(this)
|
||||
}
|
||||
|
||||
super.onCreate()
|
||||
eventListeners.toList().forEach { it?.onCreate() }
|
||||
@@ -249,11 +219,13 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
override fun onCreateInputView(): View? {
|
||||
Timber.i("onCreateInputView()")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
|
||||
baseContext.setTheme(currentThemeResId)
|
||||
updateThemeContext(currentThemeResId)
|
||||
|
||||
inputWindowView = layoutInflater.inflate(R.layout.florisboard, null) as? InputWindowView
|
||||
popupLayerView = PopupLayerView(themeContext)
|
||||
|
||||
inputWindowView = LayoutInflater.from(themeContext).inflate(R.layout.florisboard, null) as? InputWindowView
|
||||
inputWindowView?.isHapticFeedbackEnabled = true
|
||||
|
||||
eventListeners.toList().forEach { it?.onCreateInputView() }
|
||||
@@ -291,16 +263,23 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
Timber.i("onDestroy()")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
serviceLifecycleDispatcher.onServicePreSuperOnDestroy()
|
||||
|
||||
themeManager.unregisterOnThemeUpdatedListener(this)
|
||||
florisClipboardManager!!.removePrimaryClipChangedListener(this)
|
||||
florisClipboardManager!!.close()
|
||||
osHandler.removeCallbacksAndMessages(null)
|
||||
florisClipboardManager?.let {
|
||||
it.removePrimaryClipChangedListener(this)
|
||||
it.close()
|
||||
florisClipboardManager = null
|
||||
}
|
||||
audioManager = null
|
||||
imeManager = null
|
||||
vibrator = null
|
||||
popupLayerView = null
|
||||
inputView = null
|
||||
inputWindowView = null
|
||||
florisboardInstance = null
|
||||
|
||||
serviceLifecycleDispatcher.onServicePreSuperOnDestroy()
|
||||
|
||||
eventListeners.toList().forEach { it?.onDestroy() }
|
||||
eventListeners.clear()
|
||||
super.onDestroy()
|
||||
@@ -334,12 +313,11 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
|
||||
fun registerInputView(inputView: InputView) {
|
||||
Timber.i("registerInputView($inputView)")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
|
||||
window?.window?.findViewById<View>(android.R.id.content)?.let { content ->
|
||||
popupLayerView = PopupLayerView(content.context)
|
||||
if (content is ViewGroup) {
|
||||
content.addView(popupLayerView)
|
||||
popupLayerView?.let { content.addView(it) }
|
||||
}
|
||||
}
|
||||
this.inputView = inputView
|
||||
@@ -352,14 +330,15 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
|
||||
override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
|
||||
Timber.i("onStartInput($attribute, $restarting)")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
|
||||
super.onStartInput(attribute, restarting)
|
||||
currentInputConnection?.requestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR)
|
||||
}
|
||||
|
||||
override fun onStartInputView(info: EditorInfo?, restarting: Boolean) {
|
||||
Timber.i("onStartInputView($info, $restarting)")
|
||||
Timber.i("onStartInputView: ${info?.debugSummarize()}")
|
||||
flogInfo(LogTopic.IMS_EVENTS) { "restarting=$restarting"}
|
||||
flogInfo(LogTopic.IMS_EVENTS) { info?.debugSummarize() ?: "" }
|
||||
|
||||
super.onStartInputView(info, restarting)
|
||||
activeEditorInstance = EditorInstance.from(info, this)
|
||||
@@ -370,7 +349,7 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
|
||||
override fun onFinishInputView(finishingInput: Boolean) {
|
||||
Timber.i( "onFinishInputView($finishingInput)")
|
||||
flogInfo(LogTopic.IMS_EVENTS) { "finishingInput=$finishingInput" }
|
||||
|
||||
if (finishingInput) {
|
||||
activeEditorInstance = EditorInstance.default()
|
||||
@@ -381,53 +360,66 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
|
||||
override fun onFinishInput() {
|
||||
Timber.i("onFinishInput()")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
|
||||
super.onFinishInput()
|
||||
currentInputConnection?.requestCursorUpdates(0)
|
||||
super.onFinishInput()
|
||||
}
|
||||
|
||||
override fun onWindowShown() {
|
||||
super.onWindowShown()
|
||||
if (isWindowShown) {
|
||||
Timber.i("Ignoring onWindowShown()")
|
||||
flogInfo(LogTopic.IMS_EVENTS) { "Ignoring (is already shown)" }
|
||||
return
|
||||
} else {
|
||||
Timber.i("onWindowShown()")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
}
|
||||
isWindowShown = true
|
||||
|
||||
prefs.sync()
|
||||
val newIsNumberRowVisible = prefs.keyboard.numberRow
|
||||
if (isNumberRowVisible != newIsNumberRowVisible) {
|
||||
textInputManager.layoutManager.clearLayoutCache(KeyboardMode.CHARACTERS)
|
||||
textInputManager.keyboards.clear(KeyboardMode.CHARACTERS)
|
||||
isNumberRowVisible = newIsNumberRowVisible
|
||||
}
|
||||
textInputManager.layoutManager.clearLayoutCache()
|
||||
themeManager.update()
|
||||
updateOneHandedPanelVisibility()
|
||||
activeSubtype = subtypeManager.getActiveSubtype() ?: Subtype.DEFAULT
|
||||
onSubtypeChanged(activeSubtype)
|
||||
setActiveInput(R.id.text_input)
|
||||
|
||||
super.onWindowShown()
|
||||
if (prefs.devtools.enabled && prefs.devtools.showHeapMemoryStats) {
|
||||
devtoolsOverlaySyncJob?.cancel()
|
||||
devtoolsOverlaySyncJob = uiScope.launch(Dispatchers.Default) {
|
||||
while (true) {
|
||||
if (!isActive) break
|
||||
withContext(Dispatchers.Main) { inputView?.invalidate() }
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventListeners.toList().forEach { it?.onWindowShown() }
|
||||
}
|
||||
|
||||
override fun onWindowHidden() {
|
||||
super.onWindowHidden()
|
||||
if (!isWindowShown) {
|
||||
Timber.i("Ignoring onWindowHidden()")
|
||||
flogInfo(LogTopic.IMS_EVENTS) { "Ignoring (is already hidden)" }
|
||||
return
|
||||
} else {
|
||||
Timber.i("onWindowHidden()")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
}
|
||||
isWindowShown = false
|
||||
|
||||
super.onWindowHidden()
|
||||
devtoolsOverlaySyncJob?.cancel()
|
||||
devtoolsOverlaySyncJob = null
|
||||
|
||||
eventListeners.toList().forEach { it?.onWindowHidden() }
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
Timber.i("onConfigurationChanged($newConfig)")
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
if (isInputViewShown) {
|
||||
updateOneHandedPanelVisibility()
|
||||
}
|
||||
@@ -485,7 +477,7 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
)
|
||||
|
||||
if (internalBatchNestingLevel == 0) {
|
||||
Timber.i("onUpdateSelection($oldSelStart, $oldSelEnd, $newSelStart, $newSelEnd, $candidatesStart, $candidatesEnd)")
|
||||
flogInfo(LogTopic.IMS_EVENTS) { "$oldSelStart, $oldSelEnd, $newSelStart, $newSelEnd, $candidatesStart, $candidatesEnd" }
|
||||
activeEditorInstance.onUpdateSelection(
|
||||
oldSelStart, oldSelEnd,
|
||||
newSelStart, newSelEnd,
|
||||
@@ -493,7 +485,9 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
)
|
||||
eventListeners.toList().forEach { it?.onUpdateSelection() }
|
||||
} else {
|
||||
Timber.i("onUpdateSelection($oldSelStart, $oldSelEnd, $newSelStart, $newSelEnd, $candidatesStart, $candidatesEnd): caught due to internal batch level of $internalBatchNestingLevel!")
|
||||
flogInfo(LogTopic.IMS_EVENTS) {
|
||||
"$oldSelStart, $oldSelEnd, $newSelStart, $newSelEnd, $candidatesStart, $candidatesEnd: caught due to internal batch level of $internalBatchNestingLevel!"
|
||||
}
|
||||
if (internalSelectionCache.selectionCatchCount++ == 0) {
|
||||
internalSelectionCache.oldSelStart = oldSelStart
|
||||
internalSelectionCache.oldSelEnd = oldSelEnd
|
||||
@@ -620,28 +614,54 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
/**
|
||||
* Makes a key press vibration if the user has this feature enabled in the preferences.
|
||||
*/
|
||||
fun keyPressVibrate() {
|
||||
fun keyPressVibrate(isMovingGestureEffect: Boolean = false) {
|
||||
if (prefs.keyboard.vibrationEnabled) {
|
||||
var vibrationDuration = prefs.keyboard.vibrationDuration.toLong()
|
||||
var vibrationStrength = prefs.keyboard.vibrationStrength
|
||||
if (vibrationStrength == -1 && prefs.keyboard.vibrationEnabledSystem) {
|
||||
val hapticsPerformed =
|
||||
inputWindowView?.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||
|
||||
if (hapticsPerformed == false) {
|
||||
vibrationStrength = 36
|
||||
}
|
||||
if (!prefs.keyboard.vibrationEnabledSystem && vibrationDuration < 0 && vibrationStrength < 0) {
|
||||
return
|
||||
}
|
||||
if (vibrationStrength > 0) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
vibrator?.vibrate(
|
||||
VibrationEffect.createOneShot(
|
||||
vibrationStrength.toLong(), VibrationEffect.DEFAULT_AMPLITUDE
|
||||
)
|
||||
)
|
||||
|
||||
val hapticsPerformed = if (vibrationDuration < 0 && vibrationStrength < 0) {
|
||||
if (isMovingGestureEffect && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
inputWindowView?.performHapticFeedback(HapticFeedbackConstants.TEXT_HANDLE_MOVE)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
vibrator?.vibrate(vibrationStrength.toLong())
|
||||
inputWindowView?.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
if (hapticsPerformed == true) {
|
||||
return
|
||||
}
|
||||
|
||||
if (vibrationDuration == -1L) {
|
||||
vibrationDuration = 36
|
||||
}
|
||||
if (isMovingGestureEffect) {
|
||||
vibrationDuration = (vibrationDuration / 8.0).toLong().coerceAtLeast(1)
|
||||
}
|
||||
if (vibrationStrength == -1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
vibrationStrength = VibrationEffect.DEFAULT_AMPLITUDE
|
||||
} else if (vibrationStrength == -1) {
|
||||
vibrationStrength = 36
|
||||
}
|
||||
if (isMovingGestureEffect && vibrationStrength > 0) {
|
||||
vibrationStrength = (vibrationStrength / 2.0).toInt().coerceAtLeast(1)
|
||||
} else if (isMovingGestureEffect) {
|
||||
vibrationStrength = 8
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
vibrator?.vibrate(
|
||||
VibrationEffect.createOneShot(
|
||||
vibrationDuration, vibrationStrength
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
vibrator?.vibrate(vibrationDuration)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -652,10 +672,13 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
fun keyPressSound(keyData: KeyData? = null) {
|
||||
if (prefs.keyboard.soundEnabled) {
|
||||
val soundVolume = prefs.keyboard.soundVolume
|
||||
val effect = when (keyData?.code) {
|
||||
KeyCode.SPACE -> AudioManager.FX_KEYPRESS_SPACEBAR
|
||||
KeyCode.DELETE -> AudioManager.FX_KEYPRESS_DELETE
|
||||
KeyCode.ENTER -> AudioManager.FX_KEYPRESS_RETURN
|
||||
val effect = when (keyData) {
|
||||
is TextKeyData -> when (keyData.code) {
|
||||
KeyCode.SPACE -> AudioManager.FX_KEYPRESS_SPACEBAR
|
||||
KeyCode.DELETE -> AudioManager.FX_KEYPRESS_DELETE
|
||||
KeyCode.ENTER -> AudioManager.FX_KEYPRESS_RETURN
|
||||
else -> AudioManager.FX_KEYPRESS_STANDARD
|
||||
}
|
||||
else -> AudioManager.FX_KEYPRESS_STANDARD
|
||||
}
|
||||
if (soundVolume == -1 && prefs.keyboard.soundEnabledSystem) {
|
||||
@@ -710,7 +733,7 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e,"Unable to switch to the previous IME")
|
||||
flogError { "Unable to switch to the previous IME" }
|
||||
imeManager?.showInputMethodPicker()
|
||||
}
|
||||
}
|
||||
@@ -726,22 +749,25 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e,"Unable to switch to the next IME")
|
||||
flogError { "Unable to switch to the next IME" }
|
||||
imeManager?.showInputMethodPicker()
|
||||
}
|
||||
}
|
||||
|
||||
fun switchToPrevSubtype() {
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
activeSubtype = subtypeManager.switchToPrevSubtype() ?: Subtype.DEFAULT
|
||||
onSubtypeChanged(activeSubtype)
|
||||
}
|
||||
|
||||
fun switchToNextSubtype() {
|
||||
flogInfo(LogTopic.IMS_EVENTS)
|
||||
activeSubtype = subtypeManager.switchToNextSubtype() ?: Subtype.DEFAULT
|
||||
onSubtypeChanged(activeSubtype)
|
||||
}
|
||||
|
||||
private fun onSubtypeChanged(newSubtype: Subtype) {
|
||||
flogInfo(LogTopic.SUBTYPE_MANAGER) { "New subtype: $newSubtype" }
|
||||
textInputManager.onSubtypeChanged(newSubtype)
|
||||
mediaInputManager.onSubtypeChanged(newSubtype)
|
||||
clipInputManager.onSubtypeChanged(newSubtype)
|
||||
@@ -752,7 +778,7 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
R.id.text_input -> {
|
||||
inputView?.mainViewFlipper?.displayedChild = 0
|
||||
if (forceSwitchToCharacters) {
|
||||
textInputManager.inputEventDispatcher.send(InputKeyEvent.downUp(KeyData.VIEW_CHARACTERS))
|
||||
textInputManager.inputEventDispatcher.send(InputKeyEvent.downUp(TextKeyData.VIEW_CHARACTERS))
|
||||
}
|
||||
}
|
||||
R.id.media_input -> {
|
||||
@@ -762,6 +788,7 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
inputView?.mainViewFlipper?.displayedChild = 2
|
||||
}
|
||||
}
|
||||
textInputManager.isGlidePostEffect = false
|
||||
}
|
||||
|
||||
fun toggleOneHandedMode(isRight: Boolean) {
|
||||
@@ -793,9 +820,9 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
}
|
||||
}
|
||||
// Delay execution so this function can return, then refresh the whole layout
|
||||
osHandler.postDelayed({
|
||||
uiScope.launch {
|
||||
refreshLayoutOf(inputView)
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPrimaryClipChanged() {
|
||||
@@ -858,16 +885,17 @@ class FlorisBoard : InputMethodService(), LifecycleOwner, FlorisClipboardManager
|
||||
* @property defaultSubtypesLanguageCodes Helper list for Settings Subtype Spinner elements.
|
||||
* @property defaultSubtypesLanguageNames Helper list for Settings Subtype Spinner elements.
|
||||
*/
|
||||
@Serializable
|
||||
data class ImeConfig(
|
||||
@Json(name = "package")
|
||||
@SerialName("package")
|
||||
val packageName: String,
|
||||
val currencySets: List<CurrencySet> = listOf(),
|
||||
val defaultSubtypes: List<DefaultSubtype> = listOf()
|
||||
) {
|
||||
val currencySetNames: List<String>
|
||||
val currencySetLabels: List<String>
|
||||
val defaultSubtypesLanguageCodes: List<String>
|
||||
val defaultSubtypesLanguageNames: List<String>
|
||||
@Transient var currencySetNames: List<String> = listOf()
|
||||
@Transient var currencySetLabels: List<String> = listOf()
|
||||
@Transient var defaultSubtypesLanguageCodes: List<String> = listOf()
|
||||
@Transient var defaultSubtypesLanguageNames: List<String> = listOf()
|
||||
|
||||
init {
|
||||
val tmpCurrencyList = mutableListOf<Pair<String, String>>()
|
||||
|
||||
@@ -19,17 +19,9 @@ package dev.patrickgold.florisboard.ime.core
|
||||
import android.os.SystemClock
|
||||
import dev.patrickgold.florisboard.BuildConfig
|
||||
import dev.patrickgold.florisboard.ime.text.key.KeyCode
|
||||
import dev.patrickgold.florisboard.ime.text.key.KeyData
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
@@ -38,14 +30,13 @@ import timber.log.Timber
|
||||
* events can be dispatched.
|
||||
*/
|
||||
class InputEventDispatcher private constructor(
|
||||
parentScope: CoroutineScope,
|
||||
channelCapacity: Int,
|
||||
private val mainDispatcher: CoroutineDispatcher,
|
||||
private val defaultDispatcher: CoroutineDispatcher,
|
||||
private val repeatableKeyCodes: IntArray
|
||||
) : InputKeyEventSender {
|
||||
private val channel: Channel<InputKeyEvent> = Channel(channelCapacity)
|
||||
private val scope: CoroutineScope = CoroutineScope(parentScope.coroutineContext)
|
||||
private val scope: CoroutineScope = CoroutineScope(defaultDispatcher + SupervisorJob())
|
||||
private val pressedKeys: HashMap<Int, PressedKeyInfo> = hashMapOf()
|
||||
var lastKeyEventDown: InputKeyEvent? = null
|
||||
private set
|
||||
@@ -67,7 +58,6 @@ class InputEventDispatcher private constructor(
|
||||
/**
|
||||
* Creates a new [InputEventDispatcher] instance from given arguments and returns it.
|
||||
*
|
||||
* @param parentScope The parent coroutine scope which this dispatcher will attach its own scope to.
|
||||
* @param channelCapacity The capacity of this input channel, defaults to [DEFAULT_CHANNEL_CAPACITY].
|
||||
* @param mainDispatcher The main dispatcher used to switch the context to call the receiver callbacks.
|
||||
* Defaults to [Dispatchers.Main].
|
||||
@@ -78,13 +68,12 @@ class InputEventDispatcher private constructor(
|
||||
* @return A new [InputEventDispatcher] instance initialized with given arguments.
|
||||
*/
|
||||
fun new(
|
||||
parentScope: CoroutineScope,
|
||||
channelCapacity: Int = DEFAULT_CHANNEL_CAPACITY,
|
||||
mainDispatcher: CoroutineDispatcher = Dispatchers.Main,
|
||||
defaultDispatcher: CoroutineDispatcher = Dispatchers.Default,
|
||||
repeatableKeyCodes: IntArray = intArrayOf()
|
||||
): InputEventDispatcher = InputEventDispatcher(
|
||||
parentScope, channelCapacity, mainDispatcher, defaultDispatcher, repeatableKeyCodes.clone()
|
||||
channelCapacity, mainDispatcher, defaultDispatcher, repeatableKeyCodes.clone()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -209,7 +198,7 @@ class InputEventDispatcher private constructor(
|
||||
data class InputKeyEvent(
|
||||
val eventTime: Long,
|
||||
val action: Action,
|
||||
val data: KeyData,
|
||||
val data: TextKeyData,
|
||||
val count: Int
|
||||
) {
|
||||
companion object {
|
||||
@@ -220,7 +209,7 @@ data class InputKeyEvent(
|
||||
*
|
||||
* @return The created input key event.
|
||||
*/
|
||||
fun down(keyData: KeyData): InputKeyEvent {
|
||||
fun down(keyData: TextKeyData): InputKeyEvent {
|
||||
return InputKeyEvent(
|
||||
eventTime = SystemClock.uptimeMillis(),
|
||||
action = Action.DOWN,
|
||||
@@ -237,7 +226,7 @@ data class InputKeyEvent(
|
||||
*
|
||||
* @return The created input key event.
|
||||
*/
|
||||
fun downUp(keyData: KeyData, count: Int = 1): InputKeyEvent {
|
||||
fun downUp(keyData: TextKeyData, count: Int = 1): InputKeyEvent {
|
||||
return InputKeyEvent(
|
||||
eventTime = SystemClock.uptimeMillis(),
|
||||
action = Action.DOWN_UP,
|
||||
@@ -253,7 +242,7 @@ data class InputKeyEvent(
|
||||
*
|
||||
* @return The created input key event.
|
||||
*/
|
||||
fun up(keyData: KeyData): InputKeyEvent {
|
||||
fun up(keyData: TextKeyData): InputKeyEvent {
|
||||
return InputKeyEvent(
|
||||
eventTime = SystemClock.uptimeMillis(),
|
||||
action = Action.UP,
|
||||
@@ -270,7 +259,7 @@ data class InputKeyEvent(
|
||||
*
|
||||
* @return The created input key event.
|
||||
*/
|
||||
fun repeat(keyData: KeyData, count: Int = 1): InputKeyEvent {
|
||||
fun repeat(keyData: TextKeyData, count: Int = 1): InputKeyEvent {
|
||||
return InputKeyEvent(
|
||||
eventTime = SystemClock.uptimeMillis(),
|
||||
action = Action.REPEAT,
|
||||
@@ -286,7 +275,7 @@ data class InputKeyEvent(
|
||||
*
|
||||
* @return The created input key event.
|
||||
*/
|
||||
fun cancel(keyData: KeyData): InputKeyEvent {
|
||||
fun cancel(keyData: TextKeyData): InputKeyEvent {
|
||||
return InputKeyEvent(
|
||||
eventTime = SystemClock.uptimeMillis(),
|
||||
action = Action.CANCEL,
|
||||
|
||||
@@ -18,6 +18,11 @@ package dev.patrickgold.florisboard.ime.core
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Typeface
|
||||
import android.text.TextPaint
|
||||
import android.util.AttributeSet
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.ViewGroup
|
||||
@@ -35,8 +40,8 @@ import kotlin.math.roundToInt
|
||||
* Root view of the keyboard. Notifies [FlorisBoard] when it has been attached to a window.
|
||||
*/
|
||||
class InputView : LinearLayout {
|
||||
private var florisboard: FlorisBoard = FlorisBoard.getInstance()
|
||||
private val prefs: PrefHelper = PrefHelper.getDefaultInstance(context)
|
||||
private val florisboard get() = FlorisBoard.getInstance()
|
||||
private val prefs get() = Preferences.default()
|
||||
|
||||
var desiredInputViewHeight: Float = resources.getDimension(R.dimen.inputView_baseHeight)
|
||||
private set
|
||||
@@ -58,6 +63,13 @@ class InputView : LinearLayout {
|
||||
var oneHandedCtrlPanelEnd: ViewGroup? = null
|
||||
private set
|
||||
|
||||
private val overlayTextPaint: TextPaint = TextPaint().apply {
|
||||
color = Color.GREEN
|
||||
textAlign = Paint.Align.RIGHT
|
||||
textSize = resources.getDimension(R.dimen.devtools_memory_overlay_textSize)
|
||||
typeface = Typeface.MONOSPACE
|
||||
}
|
||||
|
||||
constructor(context: Context) : this(context, null)
|
||||
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||
@@ -111,10 +123,7 @@ class InputView : LinearLayout {
|
||||
baseTextInputHeight += additionalHeight
|
||||
}
|
||||
val smartbarDisabled = !prefs.smartbar.enabled ||
|
||||
tim.keyVariation == KeyVariation.PASSWORD && prefs.keyboard.numberRow ||
|
||||
tim.getActiveKeyboardMode() == KeyboardMode.NUMERIC ||
|
||||
tim.getActiveKeyboardMode() == KeyboardMode.PHONE ||
|
||||
tim.getActiveKeyboardMode() == KeyboardMode.PHONE2
|
||||
tim.keyVariation == KeyVariation.PASSWORD && prefs.keyboard.numberRow
|
||||
if (smartbarDisabled) {
|
||||
baseHeight = baseTextInputHeight
|
||||
baseSmartbarHeight = 0.0f
|
||||
@@ -127,9 +136,9 @@ class InputView : LinearLayout {
|
||||
// adding a value to the height now will result in a bottom padding (aka offset).
|
||||
baseHeight += ViewLayoutUtils.convertDpToPixel(
|
||||
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
florisboard.prefs.keyboard.bottomOffsetLandscape.toFloat()
|
||||
prefs.keyboard.bottomOffsetLandscape.toFloat()
|
||||
} else {
|
||||
florisboard.prefs.keyboard.bottomOffsetPortrait.toFloat()
|
||||
prefs.keyboard.bottomOffsetPortrait.toFloat()
|
||||
},
|
||||
context
|
||||
)
|
||||
@@ -164,4 +173,34 @@ class InputView : LinearLayout {
|
||||
resources.getDimension(R.dimen.inputView_baseHeight)
|
||||
)
|
||||
}
|
||||
|
||||
override fun dispatchDraw(canvas: Canvas?) {
|
||||
super.dispatchDraw(canvas)
|
||||
canvas ?: return
|
||||
|
||||
if (prefs.devtools.enabled && prefs.devtools.showHeapMemoryStats) {
|
||||
try {
|
||||
// Note: the below code only gets the heap size in MB, the actual RAM usage (native or others) can be
|
||||
// a lot higher
|
||||
// Source: https://stackoverflow.com/a/19267315/6801193
|
||||
val runtime = Runtime.getRuntime()
|
||||
val usedMemInMB = (runtime.totalMemory() - runtime.freeMemory()) / 1048576L
|
||||
val maxHeapSizeInMB = runtime.maxMemory() / 1048576L
|
||||
val availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB
|
||||
val output = listOf(
|
||||
"heap mem:",
|
||||
String.format("used=%4dMB", usedMemInMB),
|
||||
String.format("max=%4dMB", maxHeapSizeInMB),
|
||||
String.format("avail=%4dMB", availHeapSizeInMB),
|
||||
)
|
||||
val x = measuredWidth.toFloat()
|
||||
var y = overlayTextPaint.descent() - overlayTextPaint.ascent()
|
||||
for (line in output) {
|
||||
canvas.drawText(line, x, y, overlayTextPaint)
|
||||
y += overlayTextPaint.descent() - overlayTextPaint.ascent()
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,20 +32,26 @@ import dev.patrickgold.florisboard.ime.text.smartbar.CandidateView
|
||||
import dev.patrickgold.florisboard.ime.theme.ThemeMode
|
||||
import dev.patrickgold.florisboard.util.TimeUtil
|
||||
import dev.patrickgold.florisboard.util.VersionName
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* Helper class for an organized access to the shared preferences.
|
||||
*/
|
||||
class PrefHelper(
|
||||
private val context: Context,
|
||||
class Preferences(
|
||||
context: Context,
|
||||
val shared: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
) {
|
||||
private val applicationContext: WeakReference<Context> = WeakReference(context.applicationContext)
|
||||
|
||||
private val cacheBoolean: HashMap<String, Boolean> = hashMapOf()
|
||||
private val cacheInt: HashMap<String, Int> = hashMapOf()
|
||||
private val cacheString: HashMap<String, String> = hashMapOf()
|
||||
|
||||
val advanced = Advanced(this)
|
||||
val clipboard = Clipboard(this)
|
||||
val correction = Correction(this)
|
||||
val devtools = Devtools(this)
|
||||
val dictionary = Dictionary(this)
|
||||
val gestures = Gestures(this)
|
||||
val glide = Glide(this)
|
||||
val internal = Internal(this)
|
||||
@@ -54,7 +60,6 @@ class PrefHelper(
|
||||
val smartbar = Smartbar(this)
|
||||
val suggestion = Suggestion(this)
|
||||
val theme = Theme(this)
|
||||
val clipboard = Clipboard(this)
|
||||
|
||||
/**
|
||||
* Checks the cache if an entry for [key] exists, else calls [getPrefInternal] to retrieve the
|
||||
@@ -124,15 +129,22 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val OLD_SUBTYPES_REGEX = """^([\-0-9]+\/[\-a-zA-Z0-9]+\/[a-zA-Z\_]+[;]*)+${'$'}""".toRegex()
|
||||
private var defaultInstance: PrefHelper? = null
|
||||
private val OLD_SUBTYPES_REGEX = """^([\-0-9]+/[\-a-zA-Z0-9]+/[a-zA-Z_]+[;]*)+${'$'}""".toRegex()
|
||||
private var defaultInstance: Preferences? = null
|
||||
|
||||
@Synchronized
|
||||
fun getDefaultInstance(context: Context): PrefHelper {
|
||||
if (defaultInstance == null) {
|
||||
defaultInstance = PrefHelper(context)
|
||||
}
|
||||
return defaultInstance!!
|
||||
fun initDefault(context: Context): Preferences {
|
||||
val instance = Preferences(context.applicationContext)
|
||||
defaultInstance = instance
|
||||
return instance
|
||||
}
|
||||
|
||||
fun default(): Preferences {
|
||||
return defaultInstance
|
||||
?: throw UninitializedPropertyAccessException("""
|
||||
Default preferences not initialized! Make sure to call initDefault()
|
||||
before accessing the default preferences.
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,11 +153,14 @@ class PrefHelper(
|
||||
* they have not been initialized yet.
|
||||
*/
|
||||
fun initDefaultPreferences() {
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_advanced, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_gestures, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_keyboard, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_theme, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_typing, true)
|
||||
applicationContext.get()?.let { context ->
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_advanced, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_gestures, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_keyboard, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_theme, true)
|
||||
PreferenceManager.setDefaultValues(context, R.xml.prefs_typing, true)
|
||||
}
|
||||
|
||||
//theme.dayThemeRef = "assets:ime/theme/floris_day.json"
|
||||
//theme.nightThemeRef = "assets:ime/theme/floris_night.json"
|
||||
//setPref(Localization.SUBTYPES, "-234/de-AT/euro/c=qwertz")
|
||||
@@ -159,13 +174,15 @@ class PrefHelper(
|
||||
* Syncs the system preference values and clears the cache.
|
||||
*/
|
||||
fun sync() {
|
||||
val contentResolver = context.contentResolver
|
||||
keyboard.soundEnabledSystem = Settings.System.getInt(
|
||||
contentResolver, Settings.System.SOUND_EFFECTS_ENABLED, 0
|
||||
) != 0
|
||||
keyboard.vibrationEnabledSystem = Settings.System.getInt(
|
||||
contentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED, 0
|
||||
) != 0
|
||||
applicationContext.get()?.let { context ->
|
||||
val contentResolver = context.contentResolver
|
||||
keyboard.soundEnabledSystem = Settings.System.getInt(
|
||||
contentResolver, Settings.System.SOUND_EFFECTS_ENABLED, 0
|
||||
) != 0
|
||||
keyboard.vibrationEnabledSystem = Settings.System.getInt(
|
||||
contentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED, 0
|
||||
) != 0
|
||||
}
|
||||
|
||||
cacheBoolean.clear()
|
||||
cacheInt.clear()
|
||||
@@ -175,7 +192,7 @@ class PrefHelper(
|
||||
/**
|
||||
* Wrapper class for advanced preferences.
|
||||
*/
|
||||
class Advanced(private val prefHelper: PrefHelper) {
|
||||
class Advanced(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val SETTINGS_THEME = "advanced__settings_theme"
|
||||
const val SHOW_APP_ICON = "advanced__show_app_icon"
|
||||
@@ -183,20 +200,20 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
var settingsTheme: String = ""
|
||||
get() = prefHelper.getPref(SETTINGS_THEME, "auto")
|
||||
get() = prefs.getPref(SETTINGS_THEME, "auto")
|
||||
private set
|
||||
var showAppIcon: Boolean = false
|
||||
get() = prefHelper.getPref(SHOW_APP_ICON, true)
|
||||
get() = prefs.getPref(SHOW_APP_ICON, true)
|
||||
private set
|
||||
var forcePrivateMode: Boolean
|
||||
get() = prefHelper.getPref(FORCE_PRIVATE_MODE, false)
|
||||
set(v) = prefHelper.setPref(FORCE_PRIVATE_MODE, v)
|
||||
get() = prefs.getPref(FORCE_PRIVATE_MODE, false)
|
||||
set(v) = prefs.setPref(FORCE_PRIVATE_MODE, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for correction preferences.
|
||||
*/
|
||||
class Correction(private val prefHelper: PrefHelper) {
|
||||
class Correction(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val AUTO_CAPITALIZATION = "correction__auto_capitalization"
|
||||
const val DOUBLE_SPACE_PERIOD = "correction__double_space_period"
|
||||
@@ -204,20 +221,57 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
var autoCapitalization: Boolean
|
||||
get() = prefHelper.getPref(AUTO_CAPITALIZATION, true)
|
||||
set(v) = prefHelper.setPref(AUTO_CAPITALIZATION, v)
|
||||
get() = prefs.getPref(AUTO_CAPITALIZATION, true)
|
||||
set(v) = prefs.setPref(AUTO_CAPITALIZATION, v)
|
||||
var doubleSpacePeriod: Boolean
|
||||
get() = prefHelper.getPref(DOUBLE_SPACE_PERIOD, true)
|
||||
set(v) = prefHelper.setPref(DOUBLE_SPACE_PERIOD, v)
|
||||
get() = prefs.getPref(DOUBLE_SPACE_PERIOD, true)
|
||||
set(v) = prefs.setPref(DOUBLE_SPACE_PERIOD, v)
|
||||
var rememberCapsLockState: Boolean
|
||||
get() = prefHelper.getPref(REMEMBER_CAPS_LOCK_STATE, false)
|
||||
set(v) = prefHelper.setPref(REMEMBER_CAPS_LOCK_STATE, v)
|
||||
get() = prefs.getPref(REMEMBER_CAPS_LOCK_STATE, false)
|
||||
set(v) = prefs.setPref(REMEMBER_CAPS_LOCK_STATE, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for devtools preferences.
|
||||
*/
|
||||
class Devtools(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val ENABLED = "devtools__enabled"
|
||||
const val SHOW_HEAP_MEMORY_STATS = "devtools__show_heap_memory_stats"
|
||||
const val CLEAR_UDM_INTERNAL_DATABASE = "devtools__clear_udm_internal_database"
|
||||
}
|
||||
|
||||
var enabled: Boolean
|
||||
get() = prefs.getPref(ENABLED, false)
|
||||
set(v) = prefs.setPref(ENABLED, v)
|
||||
var showHeapMemoryStats: Boolean
|
||||
get() = prefs.getPref(SHOW_HEAP_MEMORY_STATS, false)
|
||||
set(v) = prefs.setPref(SHOW_HEAP_MEMORY_STATS, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for dictionary preferences.
|
||||
*/
|
||||
class Dictionary(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val ENABLE_SYSTEM_USER_DICTIONARY = "suggestion__enable_system_user_dictionary"
|
||||
const val MANAGE_SYSTEM_USER_DICTIONARY = "suggestion__manage_system_user_dictionary"
|
||||
const val ENABLE_FLORIS_USER_DICTIONARY = "suggestion__enable_floris_user_dictionary"
|
||||
const val MANAGE_FLORIS_USER_DICTIONARY = "suggestion__manage_floris_user_dictionary"
|
||||
}
|
||||
|
||||
var enableSystemUserDictionary: Boolean
|
||||
get() = prefs.getPref(ENABLE_SYSTEM_USER_DICTIONARY, true)
|
||||
set(v) = prefs.setPref(ENABLE_SYSTEM_USER_DICTIONARY, v)
|
||||
var enableFlorisUserDictionary: Boolean
|
||||
get() = prefs.getPref(ENABLE_FLORIS_USER_DICTIONARY, true)
|
||||
set(v) = prefs.setPref(ENABLE_FLORIS_USER_DICTIONARY, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for gestures preferences.
|
||||
*/
|
||||
class Gestures(private val prefHelper: PrefHelper) {
|
||||
class Gestures(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val SWIPE_UP = "gestures__swipe_up"
|
||||
const val SWIPE_DOWN = "gestures__swipe_down"
|
||||
@@ -233,74 +287,78 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
var swipeUp: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SWIPE_UP, "no_action"))
|
||||
set(v) = prefHelper.setPref(SWIPE_UP, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SWIPE_UP, "no_action"))
|
||||
set(v) = prefs.setPref(SWIPE_UP, v)
|
||||
var swipeDown: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SWIPE_DOWN, "no_action"))
|
||||
set(v) = prefHelper.setPref(SWIPE_DOWN, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SWIPE_DOWN, "no_action"))
|
||||
set(v) = prefs.setPref(SWIPE_DOWN, v)
|
||||
var swipeLeft: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SWIPE_LEFT, "no_action"))
|
||||
set(v) = prefHelper.setPref(SWIPE_LEFT, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SWIPE_LEFT, "no_action"))
|
||||
set(v) = prefs.setPref(SWIPE_LEFT, v)
|
||||
var swipeRight: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SWIPE_RIGHT, "no_action"))
|
||||
set(v) = prefHelper.setPref(SWIPE_RIGHT, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SWIPE_RIGHT, "no_action"))
|
||||
set(v) = prefs.setPref(SWIPE_RIGHT, v)
|
||||
var spaceBarLongPress: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SPACE_BAR_LONG_PRESS, "no_action"))
|
||||
set(v) = prefHelper.setPref(SPACE_BAR_LONG_PRESS, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SPACE_BAR_LONG_PRESS, "no_action"))
|
||||
set(v) = prefs.setPref(SPACE_BAR_LONG_PRESS, v)
|
||||
var spaceBarSwipeUp: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SPACE_BAR_SWIPE_UP, "no_action"))
|
||||
set(v) = prefHelper.setPref(SPACE_BAR_SWIPE_UP, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SPACE_BAR_SWIPE_UP, "no_action"))
|
||||
set(v) = prefs.setPref(SPACE_BAR_SWIPE_UP, v)
|
||||
var spaceBarSwipeLeft: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SPACE_BAR_SWIPE_LEFT, "no_action"))
|
||||
set(v) = prefHelper.setPref(SPACE_BAR_SWIPE_LEFT, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SPACE_BAR_SWIPE_LEFT, "no_action"))
|
||||
set(v) = prefs.setPref(SPACE_BAR_SWIPE_LEFT, v)
|
||||
var spaceBarSwipeRight: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(SPACE_BAR_SWIPE_RIGHT, "no_action"))
|
||||
set(v) = prefHelper.setPref(SPACE_BAR_SWIPE_RIGHT, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(SPACE_BAR_SWIPE_RIGHT, "no_action"))
|
||||
set(v) = prefs.setPref(SPACE_BAR_SWIPE_RIGHT, v)
|
||||
var deleteKeySwipeLeft: SwipeAction
|
||||
get() = SwipeAction.fromString(prefHelper.getPref(DELETE_KEY_SWIPE_LEFT, "no_action"))
|
||||
set(v) = prefHelper.setPref(DELETE_KEY_SWIPE_LEFT, v)
|
||||
get() = SwipeAction.fromString(prefs.getPref(DELETE_KEY_SWIPE_LEFT, "no_action"))
|
||||
set(v) = prefs.setPref(DELETE_KEY_SWIPE_LEFT, v)
|
||||
var swipeVelocityThreshold: VelocityThreshold
|
||||
get() = VelocityThreshold.fromString(prefHelper.getPref(SWIPE_VELOCITY_THRESHOLD, "normal"))
|
||||
set(v) = prefHelper.setPref(SWIPE_VELOCITY_THRESHOLD, v)
|
||||
get() = VelocityThreshold.fromString(prefs.getPref(SWIPE_VELOCITY_THRESHOLD, "normal"))
|
||||
set(v) = prefs.setPref(SWIPE_VELOCITY_THRESHOLD, v)
|
||||
var swipeDistanceThreshold: DistanceThreshold
|
||||
get() = DistanceThreshold.fromString(prefHelper.getPref(SWIPE_DISTANCE_THRESHOLD, "normal"))
|
||||
set(v) = prefHelper.setPref(SWIPE_DISTANCE_THRESHOLD, v)
|
||||
get() = DistanceThreshold.fromString(prefs.getPref(SWIPE_DISTANCE_THRESHOLD, "normal"))
|
||||
set(v) = prefs.setPref(SWIPE_DISTANCE_THRESHOLD, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for glide preferences.
|
||||
*/
|
||||
class Glide(private val prefHelper: PrefHelper) {
|
||||
class Glide(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val ENABLED = "glide__enabled"
|
||||
const val SHOW_TRAIL = "glide__show_trail"
|
||||
const val TRAIL_DURATION = "glide__trail_fade_duration"
|
||||
const val SHOW_PREVIEW = "glide__show_preview"
|
||||
const val PREVIEW_REFRESH_DELAY = "glide__preview_refresh_delay"
|
||||
const val MAX_TRAIL_LENGTH = "glide__trail_max_length"
|
||||
}
|
||||
|
||||
var enabled: Boolean
|
||||
get() = prefHelper.getPref(ENABLED, false)
|
||||
set(v) = prefHelper.setPref(ENABLED, v)
|
||||
get() = prefs.getPref(ENABLED, false)
|
||||
set(v) = prefs.setPref(ENABLED, v)
|
||||
var showTrail: Boolean
|
||||
get() = prefHelper.getPref(SHOW_TRAIL, false)
|
||||
set(v) = prefHelper.setPref(SHOW_TRAIL, v)
|
||||
get() = prefs.getPref(SHOW_TRAIL, false)
|
||||
set(v) = prefs.setPref(SHOW_TRAIL, v)
|
||||
var trailDuration: Int
|
||||
get() = prefHelper.getPref(TRAIL_DURATION, 200)
|
||||
set(v) = prefHelper.setPref(TRAIL_DURATION, v)
|
||||
get() = prefs.getPref(TRAIL_DURATION, 200)
|
||||
set(v) = prefs.setPref(TRAIL_DURATION, v)
|
||||
var showPreview: Boolean
|
||||
get() = prefHelper.getPref(SHOW_PREVIEW, true)
|
||||
set(v) = prefHelper.setPref(SHOW_PREVIEW, v)
|
||||
get() = prefs.getPref(SHOW_PREVIEW, true)
|
||||
set(v) = prefs.setPref(SHOW_PREVIEW, v)
|
||||
var previewRefreshDelay: Int
|
||||
get() = prefHelper.getPref(PREVIEW_REFRESH_DELAY, 150)
|
||||
set(v) = prefHelper.setPref(PREVIEW_REFRESH_DELAY, v)
|
||||
get() = prefs.getPref(PREVIEW_REFRESH_DELAY, 150)
|
||||
set(v) = prefs.setPref(PREVIEW_REFRESH_DELAY, v)
|
||||
var trailMaxLength: Int
|
||||
get() = prefs.getPref(MAX_TRAIL_LENGTH, 150)
|
||||
set(v) = prefs.setPref(MAX_TRAIL_LENGTH, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for internal preferences. A preference qualifies as an internal pref if the
|
||||
* user has no ability to control this preference's value directly (via a UI pref view).
|
||||
*/
|
||||
class Internal(private val prefHelper: PrefHelper) {
|
||||
class Internal(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val IS_IME_SET_UP = "internal__is_ime_set_up"
|
||||
const val VERSION_ON_INSTALL = "internal__version_on_install"
|
||||
@@ -309,23 +367,23 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
var isImeSetUp: Boolean
|
||||
get() = prefHelper.getPref(IS_IME_SET_UP, false)
|
||||
set(v) = prefHelper.setPref(IS_IME_SET_UP, v)
|
||||
get() = prefs.getPref(IS_IME_SET_UP, false)
|
||||
set(v) = prefs.setPref(IS_IME_SET_UP, v)
|
||||
var versionOnInstall: String
|
||||
get() = prefHelper.getPref(VERSION_ON_INSTALL, VersionName.DEFAULT_RAW)
|
||||
set(v) = prefHelper.setPref(VERSION_ON_INSTALL, v)
|
||||
get() = prefs.getPref(VERSION_ON_INSTALL, VersionName.DEFAULT_RAW)
|
||||
set(v) = prefs.setPref(VERSION_ON_INSTALL, v)
|
||||
var versionLastUse: String
|
||||
get() = prefHelper.getPref(VERSION_LAST_USE, VersionName.DEFAULT_RAW)
|
||||
set(v) = prefHelper.setPref(VERSION_LAST_USE, v)
|
||||
get() = prefs.getPref(VERSION_LAST_USE, VersionName.DEFAULT_RAW)
|
||||
set(v) = prefs.setPref(VERSION_LAST_USE, v)
|
||||
var versionLastChangelog: String
|
||||
get() = prefHelper.getPref(VERSION_LAST_CHANGELOG, VersionName.DEFAULT_RAW)
|
||||
set(v) = prefHelper.setPref(VERSION_LAST_CHANGELOG, v)
|
||||
get() = prefs.getPref(VERSION_LAST_CHANGELOG, VersionName.DEFAULT_RAW)
|
||||
set(v) = prefs.setPref(VERSION_LAST_CHANGELOG, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for keyboard preferences.
|
||||
*/
|
||||
class Keyboard(private val prefHelper: PrefHelper) {
|
||||
class Keyboard(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val BOTTOM_OFFSET_PORTRAIT = "keyboard__bottom_offset_portrait"
|
||||
const val BOTTOM_OFFSET_LANDSCAPE = "keyboard__bottom_offset_landscape"
|
||||
@@ -349,116 +407,120 @@ class PrefHelper(
|
||||
const val UTILITY_KEY_ACTION = "keyboard__utility_key_action"
|
||||
const val UTILITY_KEY_ENABLED = "keyboard__utility_key_enabled"
|
||||
const val VIBRATION_ENABLED = "keyboard__vibration_enabled"
|
||||
const val VIBRATION_DURATION = "keyboard__vibration_duration"
|
||||
const val VIBRATION_STRENGTH = "keyboard__vibration_strength"
|
||||
}
|
||||
|
||||
var bottomOffsetPortrait: Int = 0
|
||||
get() = prefHelper.getPref(BOTTOM_OFFSET_PORTRAIT, 0)
|
||||
get() = prefs.getPref(BOTTOM_OFFSET_PORTRAIT, 0)
|
||||
private set
|
||||
var bottomOffsetLandscape: Int = 0
|
||||
get() = prefHelper.getPref(BOTTOM_OFFSET_LANDSCAPE, 0)
|
||||
get() = prefs.getPref(BOTTOM_OFFSET_LANDSCAPE, 0)
|
||||
private set
|
||||
var fontSizeMultiplierPortrait: Int
|
||||
get() = prefHelper.getPref(FONT_SIZE_MULTIPLIER_PORTRAIT, 100)
|
||||
set(v) = prefHelper.setPref(FONT_SIZE_MULTIPLIER_PORTRAIT, v)
|
||||
get() = prefs.getPref(FONT_SIZE_MULTIPLIER_PORTRAIT, 100)
|
||||
set(v) = prefs.setPref(FONT_SIZE_MULTIPLIER_PORTRAIT, v)
|
||||
var fontSizeMultiplierLandscape: Int
|
||||
get() = prefHelper.getPref(FONT_SIZE_MULTIPLIER_LANDSCAPE, 100)
|
||||
set(v) = prefHelper.setPref(FONT_SIZE_MULTIPLIER_LANDSCAPE, v)
|
||||
get() = prefs.getPref(FONT_SIZE_MULTIPLIER_LANDSCAPE, 100)
|
||||
set(v) = prefs.setPref(FONT_SIZE_MULTIPLIER_LANDSCAPE, v)
|
||||
var heightFactor: String = ""
|
||||
get() = prefHelper.getPref(HEIGHT_FACTOR, "normal")
|
||||
get() = prefs.getPref(HEIGHT_FACTOR, "normal")
|
||||
private set
|
||||
var heightFactorCustom: Int
|
||||
get() = prefHelper.getPref(HEIGHT_FACTOR_CUSTOM, 100)
|
||||
set(v) = prefHelper.setPref(HEIGHT_FACTOR_CUSTOM, v)
|
||||
get() = prefs.getPref(HEIGHT_FACTOR_CUSTOM, 100)
|
||||
set(v) = prefs.setPref(HEIGHT_FACTOR_CUSTOM, v)
|
||||
var hintedNumberRowMode: KeyHintMode
|
||||
get() = KeyHintMode.fromString(prefHelper.getPref(HINTED_NUMBER_ROW_MODE, KeyHintMode.ENABLED_ACCENT_PRIORITY.toString()))
|
||||
set(v) = prefHelper.setPref(HINTED_NUMBER_ROW_MODE, v)
|
||||
get() = KeyHintMode.fromString(prefs.getPref(HINTED_NUMBER_ROW_MODE, KeyHintMode.ENABLED_ACCENT_PRIORITY.toString()))
|
||||
set(v) = prefs.setPref(HINTED_NUMBER_ROW_MODE, v)
|
||||
var hintedSymbolsMode: KeyHintMode
|
||||
get() = KeyHintMode.fromString(prefHelper.getPref(HINTED_SYMBOLS_MODE, KeyHintMode.ENABLED_ACCENT_PRIORITY.toString()))
|
||||
set(v) = prefHelper.setPref(HINTED_SYMBOLS_MODE, v)
|
||||
get() = KeyHintMode.fromString(prefs.getPref(HINTED_SYMBOLS_MODE, KeyHintMode.ENABLED_ACCENT_PRIORITY.toString()))
|
||||
set(v) = prefs.setPref(HINTED_SYMBOLS_MODE, v)
|
||||
var keySpacingHorizontal: Float = 2f
|
||||
get() = prefHelper.getPref(KEY_SPACING_HORIZONTAL, 4) / 2f
|
||||
get() = prefs.getPref(KEY_SPACING_HORIZONTAL, 4) / 2f
|
||||
private set
|
||||
var keySpacingVertical: Float = 5f
|
||||
get() = prefHelper.getPref(KEY_SPACING_VERTICAL, 10) / 2f
|
||||
get() = prefs.getPref(KEY_SPACING_VERTICAL, 10) / 2f
|
||||
private set
|
||||
var landscapeInputUiMode: LandscapeInputUiMode
|
||||
get() = LandscapeInputUiMode.fromString(prefHelper.getPref(LANDSCAPE_INPUT_UI_MODE, LandscapeInputUiMode.DYNAMICALLY_SHOW.toString()))
|
||||
set(v) = prefHelper.setPref(LANDSCAPE_INPUT_UI_MODE, v)
|
||||
get() = LandscapeInputUiMode.fromString(prefs.getPref(LANDSCAPE_INPUT_UI_MODE, LandscapeInputUiMode.DYNAMICALLY_SHOW.toString()))
|
||||
set(v) = prefs.setPref(LANDSCAPE_INPUT_UI_MODE, v)
|
||||
var longPressDelay: Int = 0
|
||||
get() = prefHelper.getPref(LONG_PRESS_DELAY, 300)
|
||||
get() = prefs.getPref(LONG_PRESS_DELAY, 300)
|
||||
private set
|
||||
var numberRow: Boolean
|
||||
get() = prefHelper.getPref(NUMBER_ROW, false)
|
||||
set(v) = prefHelper.setPref(NUMBER_ROW, v)
|
||||
get() = prefs.getPref(NUMBER_ROW, false)
|
||||
set(v) = prefs.setPref(NUMBER_ROW, v)
|
||||
var oneHandedMode: String
|
||||
get() = prefHelper.getPref(ONE_HANDED_MODE, OneHandedMode.OFF)
|
||||
set(value) = prefHelper.setPref(ONE_HANDED_MODE, value)
|
||||
get() = prefs.getPref(ONE_HANDED_MODE, OneHandedMode.OFF)
|
||||
set(value) = prefs.setPref(ONE_HANDED_MODE, value)
|
||||
var oneHandedModeScaleFactor: Int
|
||||
get() = prefHelper.getPref(ONE_HANDED_MODE_SCALE_FACTOR, 87)
|
||||
set(v) = prefHelper.setPref(ONE_HANDED_MODE_SCALE_FACTOR, v)
|
||||
get() = prefs.getPref(ONE_HANDED_MODE_SCALE_FACTOR, 87)
|
||||
set(v) = prefs.setPref(ONE_HANDED_MODE_SCALE_FACTOR, v)
|
||||
var popupEnabled: Boolean = false
|
||||
get() = prefHelper.getPref(POPUP_ENABLED, true)
|
||||
get() = prefs.getPref(POPUP_ENABLED, true)
|
||||
private set
|
||||
var soundEnabled: Boolean = false
|
||||
get() = prefHelper.getPref(SOUND_ENABLED, true)
|
||||
get() = prefs.getPref(SOUND_ENABLED, true)
|
||||
private set
|
||||
var soundEnabledSystem: Boolean = false
|
||||
var soundVolume: Int = 0
|
||||
get() = prefHelper.getPref(SOUND_VOLUME, -1)
|
||||
get() = prefs.getPref(SOUND_VOLUME, -1)
|
||||
private set
|
||||
var spaceBarSwitchesToCharacters: Boolean
|
||||
get() = prefHelper.getPref(SPACE_BAR_SWITCHES_TO_CHARACTERS, true)
|
||||
set(v) = prefHelper.setPref(SPACE_BAR_SWITCHES_TO_CHARACTERS, v)
|
||||
get() = prefs.getPref(SPACE_BAR_SWITCHES_TO_CHARACTERS, true)
|
||||
set(v) = prefs.setPref(SPACE_BAR_SWITCHES_TO_CHARACTERS, v)
|
||||
var utilityKeyAction: UtilityKeyAction
|
||||
get() = UtilityKeyAction.fromString(prefHelper.getPref(UTILITY_KEY_ACTION, UtilityKeyAction.DYNAMIC_SWITCH_LANGUAGE_EMOJIS.toString()))
|
||||
set(v) = prefHelper.setPref(UTILITY_KEY_ACTION, v)
|
||||
get() = UtilityKeyAction.fromString(prefs.getPref(UTILITY_KEY_ACTION, UtilityKeyAction.DYNAMIC_SWITCH_LANGUAGE_EMOJIS.toString()))
|
||||
set(v) = prefs.setPref(UTILITY_KEY_ACTION, v)
|
||||
var utilityKeyEnabled: Boolean
|
||||
get() = prefHelper.getPref(UTILITY_KEY_ENABLED, true)
|
||||
set(v) = prefHelper.setPref(UTILITY_KEY_ENABLED, v)
|
||||
get() = prefs.getPref(UTILITY_KEY_ENABLED, true)
|
||||
set(v) = prefs.setPref(UTILITY_KEY_ENABLED, v)
|
||||
var vibrationEnabled: Boolean = false
|
||||
get() = prefHelper.getPref(VIBRATION_ENABLED, true)
|
||||
get() = prefs.getPref(VIBRATION_ENABLED, true)
|
||||
private set
|
||||
var vibrationEnabledSystem: Boolean = false
|
||||
var vibrationDuration: Int = 0
|
||||
get() = prefs.getPref(VIBRATION_DURATION, -1)
|
||||
private set
|
||||
var vibrationStrength: Int = 0
|
||||
get() = prefHelper.getPref(VIBRATION_STRENGTH, -1)
|
||||
get() = prefs.getPref(VIBRATION_STRENGTH, -1)
|
||||
private set
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for localization preferences.
|
||||
*/
|
||||
class Localization(private val prefHelper: PrefHelper) {
|
||||
class Localization(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val ACTIVE_SUBTYPE_ID = "localization__active_subtype_id"
|
||||
const val SUBTYPES = "localization__subtypes"
|
||||
}
|
||||
|
||||
var activeSubtypeId: Int
|
||||
get() = prefHelper.getPref(ACTIVE_SUBTYPE_ID, Subtype.DEFAULT.id)
|
||||
set(v) = prefHelper.setPref(ACTIVE_SUBTYPE_ID, v)
|
||||
get() = prefs.getPref(ACTIVE_SUBTYPE_ID, Subtype.DEFAULT.id)
|
||||
set(v) = prefs.setPref(ACTIVE_SUBTYPE_ID, v)
|
||||
var subtypes: String
|
||||
get() = prefHelper.getPref(SUBTYPES, "")
|
||||
set(v) = prefHelper.setPref(SUBTYPES, v)
|
||||
get() = prefs.getPref(SUBTYPES, "")
|
||||
set(v) = prefs.setPref(SUBTYPES, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for Smartbar preferences.
|
||||
*/
|
||||
class Smartbar(private val prefHelper: PrefHelper) {
|
||||
class Smartbar(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val ENABLED = "smartbar__enabled"
|
||||
}
|
||||
|
||||
var enabled: Boolean
|
||||
get() = prefHelper.getPref(ENABLED, true)
|
||||
set(v) = prefHelper.setPref(ENABLED, v)
|
||||
get() = prefs.getPref(ENABLED, true)
|
||||
set(v) = prefs.setPref(ENABLED, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for suggestion preferences.
|
||||
*/
|
||||
class Suggestion(private val prefHelper: PrefHelper) {
|
||||
class Suggestion(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val BLOCK_POSSIBLY_OFFENSIVE = "suggestion__block_possibly_offensive"
|
||||
const val CLIPBOARD_CONTENT_ENABLED = "suggestion__clipboard_content_enabled"
|
||||
@@ -469,29 +531,29 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
var blockPossiblyOffensive: Boolean
|
||||
get() = prefHelper.getPref(BLOCK_POSSIBLY_OFFENSIVE, true)
|
||||
set(v) = prefHelper.setPref(BLOCK_POSSIBLY_OFFENSIVE, v)
|
||||
get() = prefs.getPref(BLOCK_POSSIBLY_OFFENSIVE, true)
|
||||
set(v) = prefs.setPref(BLOCK_POSSIBLY_OFFENSIVE, v)
|
||||
var clipboardContentEnabled: Boolean
|
||||
get() = prefHelper.getPref(CLIPBOARD_CONTENT_ENABLED, false)
|
||||
set(v) = prefHelper.setPref(CLIPBOARD_CONTENT_ENABLED, v)
|
||||
get() = prefs.getPref(CLIPBOARD_CONTENT_ENABLED, false)
|
||||
set(v) = prefs.setPref(CLIPBOARD_CONTENT_ENABLED, v)
|
||||
var clipboardContentTimeout: Int
|
||||
get() = prefHelper.getPref(CLIPBOARD_CONTENT_TIMEOUT, 30)
|
||||
set(v) = prefHelper.setPref(CLIPBOARD_CONTENT_TIMEOUT, v)
|
||||
get() = prefs.getPref(CLIPBOARD_CONTENT_TIMEOUT, 30)
|
||||
set(v) = prefs.setPref(CLIPBOARD_CONTENT_TIMEOUT, v)
|
||||
var displayMode: CandidateView.DisplayMode
|
||||
get() = CandidateView.DisplayMode.fromString(prefHelper.getPref(DISPLAY_MODE, CandidateView.DisplayMode.DYNAMIC_SCROLLABLE.toString()))
|
||||
set(v) = prefHelper.setPref(DISPLAY_MODE, v)
|
||||
get() = CandidateView.DisplayMode.fromString(prefs.getPref(DISPLAY_MODE, CandidateView.DisplayMode.DYNAMIC_SCROLLABLE.toString()))
|
||||
set(v) = prefs.setPref(DISPLAY_MODE, v)
|
||||
var enabled: Boolean
|
||||
get() = prefHelper.getPref(ENABLED, true)
|
||||
set(v) = prefHelper.setPref(ENABLED, v)
|
||||
get() = prefs.getPref(ENABLED, true)
|
||||
set(v) = prefs.setPref(ENABLED, v)
|
||||
var usePrevWords: Boolean
|
||||
get() = prefHelper.getPref(USE_PREV_WORDS, true)
|
||||
set(v) = prefHelper.setPref(USE_PREV_WORDS, v)
|
||||
get() = prefs.getPref(USE_PREV_WORDS, true)
|
||||
set(v) = prefs.setPref(USE_PREV_WORDS, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for theme preferences.
|
||||
*/
|
||||
class Theme(private val prefHelper: PrefHelper) {
|
||||
class Theme(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val MODE = "theme__mode"
|
||||
const val DAY_THEME_REF = "theme__day_theme_ref"
|
||||
@@ -503,32 +565,32 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
var mode: ThemeMode
|
||||
get() = ThemeMode.fromString(prefHelper.getPref(MODE, ThemeMode.FOLLOW_SYSTEM.toString()))
|
||||
set(v) = prefHelper.setPref(MODE, v)
|
||||
get() = ThemeMode.fromString(prefs.getPref(MODE, ThemeMode.FOLLOW_SYSTEM.toString()))
|
||||
set(v) = prefs.setPref(MODE, v)
|
||||
var dayThemeRef: String
|
||||
get() = prefHelper.getPref(DAY_THEME_REF, "assets:ime/theme/floris_day.json")
|
||||
set(v) = prefHelper.setPref(DAY_THEME_REF, v)
|
||||
get() = prefs.getPref(DAY_THEME_REF, "assets:ime/theme/floris_day.json")
|
||||
set(v) = prefs.setPref(DAY_THEME_REF, v)
|
||||
var dayThemeAdaptToApp: Boolean
|
||||
get() = prefHelper.getPref(DAY_THEME_ADAPT_TO_APP, false)
|
||||
set(v) = prefHelper.setPref(DAY_THEME_ADAPT_TO_APP, v)
|
||||
get() = prefs.getPref(DAY_THEME_ADAPT_TO_APP, false)
|
||||
set(v) = prefs.setPref(DAY_THEME_ADAPT_TO_APP, v)
|
||||
var nightThemeRef: String
|
||||
get() = prefHelper.getPref(NIGHT_THEME_REF, "assets:ime/theme/floris_night.json")
|
||||
set(v) = prefHelper.setPref(NIGHT_THEME_REF, v)
|
||||
get() = prefs.getPref(NIGHT_THEME_REF, "assets:ime/theme/floris_night.json")
|
||||
set(v) = prefs.setPref(NIGHT_THEME_REF, v)
|
||||
var nightThemeAdaptToApp: Boolean
|
||||
get() = prefHelper.getPref(NIGHT_THEME_ADAPT_TO_APP, false)
|
||||
set(v) = prefHelper.setPref(NIGHT_THEME_ADAPT_TO_APP, v)
|
||||
get() = prefs.getPref(NIGHT_THEME_ADAPT_TO_APP, false)
|
||||
set(v) = prefs.setPref(NIGHT_THEME_ADAPT_TO_APP, v)
|
||||
var sunriseTime: Int
|
||||
get() = prefHelper.getPref(SUNRISE_TIME, TimeUtil.encode(6, 0))
|
||||
set(v) = prefHelper.setPref(SUNRISE_TIME, v)
|
||||
get() = prefs.getPref(SUNRISE_TIME, TimeUtil.encode(6, 0))
|
||||
set(v) = prefs.setPref(SUNRISE_TIME, v)
|
||||
var sunsetTime: Int
|
||||
get() = prefHelper.getPref(SUNSET_TIME, TimeUtil.encode(18, 0))
|
||||
set(v) = prefHelper.setPref(SUNSET_TIME, v)
|
||||
get() = prefs.getPref(SUNSET_TIME, TimeUtil.encode(18, 0))
|
||||
set(v) = prefs.setPref(SUNSET_TIME, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for clipboard preferences
|
||||
*/
|
||||
class Clipboard(private val prefHelper: PrefHelper) {
|
||||
class Clipboard(private val prefs: Preferences) {
|
||||
companion object {
|
||||
const val ENABLE_INTERNAL = "clipboard__enable_internal"
|
||||
const val SYNC_TO_SYSTEM = "clipboard__sync_to_system"
|
||||
@@ -541,35 +603,35 @@ class PrefHelper(
|
||||
}
|
||||
|
||||
var enableInternal: Boolean
|
||||
get() = prefHelper.getPref(ENABLE_INTERNAL, false)
|
||||
set(v) = prefHelper.setPref(ENABLE_INTERNAL, v)
|
||||
get() = prefs.getPref(ENABLE_INTERNAL, false)
|
||||
set(v) = prefs.setPref(ENABLE_INTERNAL, v)
|
||||
|
||||
var syncToSystem: Boolean
|
||||
get() = prefHelper.getPref(SYNC_TO_SYSTEM, false)
|
||||
set(v) = prefHelper.setPref(SYNC_TO_SYSTEM, v)
|
||||
get() = prefs.getPref(SYNC_TO_SYSTEM, false)
|
||||
set(v) = prefs.setPref(SYNC_TO_SYSTEM, v)
|
||||
|
||||
var syncToFloris: Boolean
|
||||
get() = prefHelper.getPref(SYNC_TO_FLORIS, true)
|
||||
set(v) = prefHelper.setPref(SYNC_TO_FLORIS, v)
|
||||
get() = prefs.getPref(SYNC_TO_FLORIS, true)
|
||||
set(v) = prefs.setPref(SYNC_TO_FLORIS, v)
|
||||
|
||||
var enableHistory: Boolean
|
||||
get() = prefHelper.getPref(ENABLE_HISTORY, false)
|
||||
set(v) = prefHelper.setPref(ENABLE_HISTORY, v)
|
||||
get() = prefs.getPref(ENABLE_HISTORY, false)
|
||||
set(v) = prefs.setPref(ENABLE_HISTORY, v)
|
||||
|
||||
var cleanUpOld: Boolean
|
||||
get() = prefHelper.getPref(CLEAN_UP_OLD, false)
|
||||
set(v) = prefHelper.setPref(CLEAN_UP_OLD, v)
|
||||
get() = prefs.getPref(CLEAN_UP_OLD, false)
|
||||
set(v) = prefs.setPref(CLEAN_UP_OLD, v)
|
||||
|
||||
var limitHistorySize: Boolean
|
||||
get() = prefHelper.getPref(LIMIT_HISTORY_SIZE, true)
|
||||
set(v) = prefHelper.setPref(LIMIT_HISTORY_SIZE, v)
|
||||
get() = prefs.getPref(LIMIT_HISTORY_SIZE, true)
|
||||
set(v) = prefs.setPref(LIMIT_HISTORY_SIZE, v)
|
||||
|
||||
var cleanUpAfter: Int
|
||||
get() = prefHelper.getPref(CLEAN_UP_AFTER, 20)
|
||||
set(v) = prefHelper.setPref(CLEAN_UP_AFTER, v)
|
||||
get() = prefs.getPref(CLEAN_UP_AFTER, 20)
|
||||
set(v) = prefs.setPref(CLEAN_UP_AFTER, v)
|
||||
|
||||
var maxHistorySize: Int
|
||||
get() = prefHelper.getPref(MAX_HISTORY_SIZE, 20)
|
||||
set(v) = prefHelper.setPref(MAX_HISTORY_SIZE, v)
|
||||
get() = prefs.getPref(MAX_HISTORY_SIZE, 20)
|
||||
set(v) = prefs.setPref(MAX_HISTORY_SIZE, v)
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,14 @@
|
||||
|
||||
package dev.patrickgold.florisboard.ime.core
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import dev.patrickgold.florisboard.ime.text.layout.LayoutType
|
||||
import dev.patrickgold.florisboard.util.LocaleUtils
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@@ -31,11 +36,13 @@ import java.util.*
|
||||
* @property layoutMap The layout map to properly display the correct layout for each layout type.
|
||||
*/
|
||||
data class Subtype(
|
||||
var id: Int,
|
||||
var locale: Locale,
|
||||
var currencySetName: String,
|
||||
var layoutMap: SubtypeLayoutMap,
|
||||
val id: Int,
|
||||
val locale: Locale,
|
||||
val currencySetName: String,
|
||||
val layoutMap: SubtypeLayoutMap,
|
||||
) {
|
||||
private val _hashCode: Int
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Subtype to use when prefs do not contain any valid subtypes.
|
||||
@@ -76,6 +83,14 @@ data class Subtype(
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
var result = id
|
||||
result = 31 * result + locale.hashCode()
|
||||
result = 31 * result + currencySetName.hashCode()
|
||||
result = 31 * result + layoutMap.hashCode()
|
||||
_hashCode = result
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this object into its string representation. Format:
|
||||
* <id>/<language_tag>/<currency_set_name>/<layout_map>
|
||||
@@ -85,6 +100,15 @@ data class Subtype(
|
||||
return "$id/$languageTag/$currencySetName/$layoutMap"
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this object into its short string representation, used for debugging. Format:
|
||||
* <id>/<language_tag>/<currency_set_name>
|
||||
*/
|
||||
fun toShortString(): String {
|
||||
val languageTag = locale.toLanguageTag()
|
||||
return "$id/$languageTag/$currencySetName"
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
@@ -100,14 +124,11 @@ data class Subtype(
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id
|
||||
result = 31 * result + locale.hashCode()
|
||||
result = 31 * result + currencySetName.hashCode()
|
||||
result = 31 * result + layoutMap.hashCode()
|
||||
return result
|
||||
return _hashCode
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class SubtypeLayoutMap(
|
||||
val characters: String = CHARACTERS_DEFAULT,
|
||||
val symbols: String = SYMBOLS_DEFAULT,
|
||||
@@ -118,6 +139,8 @@ data class SubtypeLayoutMap(
|
||||
val phone: String = PHONE_DEFAULT,
|
||||
val phone2: String = PHONE2_DEFAULT,
|
||||
) {
|
||||
@Transient private var _hashCode: Int = 0
|
||||
|
||||
companion object {
|
||||
private const val CHARACTERS_CODE = "c"
|
||||
private const val SYMBOLS_CODE = "s"
|
||||
@@ -172,6 +195,18 @@ data class SubtypeLayoutMap(
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
var result = characters.hashCode()
|
||||
result = 31 * result + symbols.hashCode()
|
||||
result = 31 * result + symbols2.hashCode()
|
||||
result = 31 * result + numeric.hashCode()
|
||||
result = 31 * result + numericAdvanced.hashCode()
|
||||
result = 31 * result + numericRow.hashCode()
|
||||
result = 31 * result + phone.hashCode()
|
||||
result = 31 * result + phone2.hashCode()
|
||||
_hashCode = result
|
||||
}
|
||||
|
||||
operator fun get(layoutType: LayoutType): String? {
|
||||
return when (layoutType) {
|
||||
LayoutType.CHARACTERS -> characters
|
||||
@@ -257,15 +292,7 @@ data class SubtypeLayoutMap(
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = characters.hashCode()
|
||||
result = 31 * result + symbols.hashCode()
|
||||
result = 31 * result + symbols2.hashCode()
|
||||
result = 31 * result + numeric.hashCode()
|
||||
result = 31 * result + numericAdvanced.hashCode()
|
||||
result = 31 * result + numericRow.hashCode()
|
||||
result = 31 * result + phone.hashCode()
|
||||
result = 31 * result + phone2.hashCode()
|
||||
return result
|
||||
return _hashCode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,11 +304,25 @@ data class SubtypeLayoutMap(
|
||||
* @property currencySetName The currency set name of this subtype. Beware its different name in json: 'currencySet'.
|
||||
* @property preferred The preferred layout map for this subtype's locale.
|
||||
*/
|
||||
@Serializable
|
||||
data class DefaultSubtype(
|
||||
var id: Int,
|
||||
@Json(name = "languageTag")
|
||||
@Serializable(with = LocaleSerializer::class)
|
||||
@SerialName("languageTag")
|
||||
var locale: Locale,
|
||||
@Json(name = "currencySet")
|
||||
@SerialName("currencySet")
|
||||
var currencySetName: String,
|
||||
var preferred: SubtypeLayoutMap
|
||||
)
|
||||
|
||||
class LocaleSerializer : KSerializer<Locale> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Locale", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Locale) {
|
||||
encoder.encodeString(value.toString())
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): Locale {
|
||||
return LocaleUtils.stringToLocale(decoder.decodeString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,53 +17,65 @@
|
||||
package dev.patrickgold.florisboard.ime.core
|
||||
|
||||
import android.content.Context
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import dev.patrickgold.florisboard.debug.*
|
||||
import dev.patrickgold.florisboard.ime.extension.AssetManager
|
||||
import dev.patrickgold.florisboard.ime.extension.AssetRef
|
||||
import dev.patrickgold.florisboard.ime.extension.AssetSource
|
||||
import dev.patrickgold.florisboard.ime.text.key.CurrencySet
|
||||
import dev.patrickgold.florisboard.util.LocaleUtils
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/**
|
||||
* Class which acts as a high level helper for the raw implementation of subtypes in the prefs.
|
||||
* Also interprets the default subtype list defined in ime/config.json and provides helper
|
||||
* arrays for the language spinner.
|
||||
* @property context Android context, used for interacting with the system.
|
||||
* @property packageName The package name this SubtypeManager is for.
|
||||
* @property prefs Reference to the preferences, where the raw subtype settings are accessible.
|
||||
* @property imeConfig The [FlorisBoard.ImeConfig] of this input method editor.
|
||||
* @property subtypes Dynamic property which parses the raw subtype list from prefs and returns a
|
||||
* list of [Subtype]s. When setting this property, the given list is converted to a raw string
|
||||
* and written to prefs.
|
||||
* @property subtypes The currently active subtypes.
|
||||
*/
|
||||
class SubtypeManager(
|
||||
private val context: Context,
|
||||
private val prefs: PrefHelper
|
||||
private val packageName: String
|
||||
) : CoroutineScope by MainScope() {
|
||||
private val assetManager get() = AssetManager.default()
|
||||
private val prefs get() = Preferences.default()
|
||||
|
||||
companion object {
|
||||
const val IME_CONFIG_FILE_PATH = "ime/config.json"
|
||||
const val SUBTYPE_LIST_STR_DELIMITER = ";"
|
||||
|
||||
private var instance: SubtypeManager? = null
|
||||
|
||||
fun init(context: Context): SubtypeManager {
|
||||
val defaultInstance = SubtypeManager(context.packageName)
|
||||
instance = defaultInstance
|
||||
return defaultInstance
|
||||
}
|
||||
|
||||
fun default(): SubtypeManager = instance!!
|
||||
|
||||
fun defaultOrNull(): SubtypeManager? = instance
|
||||
}
|
||||
|
||||
var imeConfig: FlorisBoard.ImeConfig = FlorisBoard.ImeConfig(context.packageName)
|
||||
var subtypes: List<Subtype>
|
||||
get() {
|
||||
val listRaw = prefs.localization.subtypes
|
||||
return if (listRaw.isBlank()) {
|
||||
listOf()
|
||||
} else {
|
||||
listRaw.split(SUBTYPE_LIST_STR_DELIMITER).map {
|
||||
Subtype.fromString(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
set(v) {
|
||||
prefs.localization.subtypes = v.joinToString(SUBTYPE_LIST_STR_DELIMITER)
|
||||
}
|
||||
var imeConfig: FlorisBoard.ImeConfig = FlorisBoard.ImeConfig(packageName)
|
||||
private val _subtypes: ArrayList<Subtype> = ArrayList()
|
||||
val subtypes: List<Subtype> get() = _subtypes
|
||||
|
||||
init {
|
||||
imeConfig = loadImeConfig(IME_CONFIG_FILE_PATH)
|
||||
|
||||
val listRaw = prefs.localization.subtypes
|
||||
if (listRaw.isNotBlank()) {
|
||||
listRaw.split(SUBTYPE_LIST_STR_DELIMITER).forEach {
|
||||
_subtypes.add(Subtype.fromString(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun syncSubtypeListToPrefs() {
|
||||
prefs.localization.subtypes = _subtypes.joinToString(SUBTYPE_LIST_STR_DELIMITER)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,19 +85,10 @@ class SubtypeManager(
|
||||
* @return The [FlorisBoard.ImeConfig] or a default config.
|
||||
*/
|
||||
private fun loadImeConfig(path: String): FlorisBoard.ImeConfig {
|
||||
val rawJsonData: String = try {
|
||||
context.assets.open(path).bufferedReader().use { it.readText() }
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
} ?: return FlorisBoard.ImeConfig(context.packageName)
|
||||
val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.add(LocaleUtils.JsonAdapter())
|
||||
.build()
|
||||
val layoutAdapter = moshi.adapter(FlorisBoard.ImeConfig::class.java)
|
||||
return layoutAdapter.fromJson(rawJsonData) ?: FlorisBoard.ImeConfig(
|
||||
context.packageName
|
||||
)
|
||||
return assetManager.loadJsonAsset<FlorisBoard.ImeConfig>(AssetRef(AssetSource.Assets, path)).getOrElse {
|
||||
flogError(LogTopic.SUBTYPE_MANAGER) { "Failed to retrieve IME config: $it" }
|
||||
FlorisBoard.ImeConfig(packageName)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,12 +99,11 @@ class SubtypeManager(
|
||||
* that the subtype already exists.
|
||||
*/
|
||||
private fun addSubtype(subtypeToAdd: Subtype): Boolean {
|
||||
val subtypeList = subtypes.toMutableList()
|
||||
if (subtypeList.contains(subtypeToAdd)) {
|
||||
if (_subtypes.contains(subtypeToAdd)) {
|
||||
return false
|
||||
}
|
||||
subtypeList.add(subtypeToAdd)
|
||||
subtypes = subtypeList
|
||||
_subtypes.add(subtypeToAdd)
|
||||
syncSubtypeListToPrefs()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -144,12 +146,12 @@ class SubtypeManager(
|
||||
* could be determined.
|
||||
*/
|
||||
fun getActiveSubtype(): Subtype? {
|
||||
for (subtype in subtypes) {
|
||||
val subtypeList = _subtypes
|
||||
for (subtype in subtypeList) {
|
||||
if (subtype.id == prefs.localization.activeSubtypeId) {
|
||||
return subtype
|
||||
}
|
||||
}
|
||||
val subtypeList = subtypes
|
||||
return if (subtypeList.isNotEmpty()) {
|
||||
prefs.localization.activeSubtypeId = subtypeList[0].id
|
||||
subtypeList[0]
|
||||
@@ -166,7 +168,8 @@ class SubtypeManager(
|
||||
* @return The subtype or null, if no matching subtype could be found.
|
||||
*/
|
||||
fun getSubtypeById(id: Int): Subtype? {
|
||||
for (subtype in subtypes) {
|
||||
val subtypeList = _subtypes
|
||||
for (subtype in subtypeList) {
|
||||
if (subtype.id == id) {
|
||||
return subtype
|
||||
}
|
||||
@@ -197,16 +200,11 @@ class SubtypeManager(
|
||||
* @param subtypeToModify The subtype with the new details but same id.
|
||||
*/
|
||||
fun modifySubtypeWithSameId(subtypeToModify: Subtype) {
|
||||
val subtypeList = subtypes
|
||||
for (subtype in subtypeList) {
|
||||
if (subtype.id == subtypeToModify.id) {
|
||||
subtype.locale = subtypeToModify.locale
|
||||
subtype.currencySetName = subtypeToModify.currencySetName
|
||||
subtype.layoutMap = subtypeToModify.layoutMap
|
||||
break
|
||||
}
|
||||
val index = _subtypes.indexOfFirst { subtypeToModify.id == it.id }
|
||||
if (index >= 0 && index < _subtypes.size) {
|
||||
_subtypes[index] = subtypeToModify
|
||||
syncSubtypeListToPrefs()
|
||||
}
|
||||
subtypes = subtypeList
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,14 +214,14 @@ class SubtypeManager(
|
||||
* @param subtypeToRemove The subtype which should be removed.
|
||||
*/
|
||||
fun removeSubtype(subtypeToRemove: Subtype) {
|
||||
val subtypeList = subtypes.toMutableList()
|
||||
val subtypeList = _subtypes
|
||||
for (subtype in subtypeList) {
|
||||
if (subtype == subtypeToRemove) {
|
||||
subtypeList.remove(subtypeToRemove)
|
||||
break
|
||||
}
|
||||
}
|
||||
subtypes = subtypeList
|
||||
syncSubtypeListToPrefs()
|
||||
if (subtypeToRemove.id == prefs.localization.activeSubtypeId) {
|
||||
getActiveSubtype()
|
||||
}
|
||||
@@ -235,7 +233,7 @@ class SubtypeManager(
|
||||
* @return The new active subtype or null if the determination process failed.
|
||||
*/
|
||||
fun switchToPrevSubtype(): Subtype? {
|
||||
val subtypeList = subtypes
|
||||
val subtypeList = _subtypes
|
||||
val activeSubtype = getActiveSubtype() ?: return null
|
||||
var triggerNextSubtype = false
|
||||
var newActiveSubtype: Subtype? = null
|
||||
@@ -263,7 +261,7 @@ class SubtypeManager(
|
||||
* @return The new active subtype or null if the determination process failed.
|
||||
*/
|
||||
fun switchToNextSubtype(): Subtype? {
|
||||
val subtypeList = subtypes
|
||||
val subtypeList = _subtypes
|
||||
val activeSubtype = getActiveSubtype() ?: return null
|
||||
var triggerNextSubtype = false
|
||||
var newActiveSubtype: Subtype? = null
|
||||
|
||||
@@ -17,15 +17,24 @@
|
||||
package dev.patrickgold.florisboard.ime.dictionary
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import dev.patrickgold.florisboard.ime.core.Preferences
|
||||
import dev.patrickgold.florisboard.ime.extension.AssetRef
|
||||
import timber.log.Timber
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* TODO: document
|
||||
*/
|
||||
class DictionaryManager private constructor(private val applicationContext: Context) {
|
||||
class DictionaryManager private constructor(context: Context) {
|
||||
private val applicationContext: WeakReference<Context> = WeakReference(context.applicationContext ?: context)
|
||||
private val prefs get() = Preferences.default()
|
||||
|
||||
private val dictionaryCache: MutableMap<String, Dictionary<String, Int>> = mutableMapOf()
|
||||
|
||||
private var florisUserDictionaryDatabase: FlorisUserDictionaryDatabase? = null
|
||||
private var systemUserDictionaryDatabase: SystemUserDictionaryDatabase? = null
|
||||
|
||||
companion object {
|
||||
private var defaultInstance: DictionaryManager? = null
|
||||
|
||||
@@ -53,16 +62,83 @@ class DictionaryManager private constructor(private val applicationContext: Cont
|
||||
}
|
||||
if (ref.path.endsWith(".flict")) {
|
||||
// Assume this is a Flictionary
|
||||
Flictionary.load(applicationContext, ref).onSuccess { flict ->
|
||||
dictionaryCache[ref.toString()] = flict
|
||||
return Result.success(flict)
|
||||
}.onFailure { err ->
|
||||
Timber.i(err)
|
||||
return Result.failure(err)
|
||||
applicationContext.get()?.let {
|
||||
Flictionary.load(it, ref).onSuccess { flict ->
|
||||
dictionaryCache[ref.toString()] = flict
|
||||
return Result.success(flict)
|
||||
}.onFailure { err ->
|
||||
Timber.i(err)
|
||||
return Result.failure(err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Result.failure(Exception("Unable to determine supported type for given AssetRef!"))
|
||||
}
|
||||
return Result.failure(Exception("If this message is ever thrown, something is completely broken..."))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun florisUserDictionaryDao(): UserDictionaryDao? {
|
||||
return if (prefs.suggestion.enabled && prefs.dictionary.enableFlorisUserDictionary) {
|
||||
florisUserDictionaryDatabase?.userDictionaryDao()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun florisUserDictionaryDatabase(): FlorisUserDictionaryDatabase? {
|
||||
return if (prefs.suggestion.enabled && prefs.dictionary.enableFlorisUserDictionary) {
|
||||
florisUserDictionaryDatabase
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun systemUserDictionaryDao(): UserDictionaryDao? {
|
||||
return if (prefs.suggestion.enabled && prefs.dictionary.enableSystemUserDictionary) {
|
||||
systemUserDictionaryDatabase?.userDictionaryDao()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun systemUserDictionaryDatabase(): SystemUserDictionaryDatabase? {
|
||||
return if (prefs.suggestion.enabled && prefs.dictionary.enableSystemUserDictionary) {
|
||||
systemUserDictionaryDatabase
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun loadUserDictionariesIfNecessary() {
|
||||
val context = applicationContext.get() ?: return
|
||||
|
||||
if (prefs.suggestion.enabled) {
|
||||
if (florisUserDictionaryDatabase == null && prefs.dictionary.enableFlorisUserDictionary) {
|
||||
florisUserDictionaryDatabase = Room.databaseBuilder(
|
||||
context,
|
||||
FlorisUserDictionaryDatabase::class.java,
|
||||
FlorisUserDictionaryDatabase.DB_FILE_NAME
|
||||
).allowMainThreadQueries().build()
|
||||
}
|
||||
if (systemUserDictionaryDatabase == null && prefs.dictionary.enableSystemUserDictionary) {
|
||||
systemUserDictionaryDatabase = SystemUserDictionaryDatabase(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun unloadUserDictionariesIfNecessary() {
|
||||
if (florisUserDictionaryDatabase != null) {
|
||||
florisUserDictionaryDatabase?.close()
|
||||
florisUserDictionaryDatabase = null
|
||||
}
|
||||
if (systemUserDictionaryDatabase != null) {
|
||||
systemUserDictionaryDatabase = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user