diff --git a/.github/workflows/auto-approve-and-merge-keyman-server-pr.yml b/.github/workflows/auto-approve-and-merge-keyman-server-pr.yml new file mode 100644 index 000000000..d3888f79b --- /dev/null +++ b/.github/workflows/auto-approve-and-merge-keyman-server-pr.yml @@ -0,0 +1,29 @@ +# +# Automatically approves and queues for merge any pull requests with a branch +# name starting with auto/, that are opened by keyman-server. This action is +# used to merge keyboard, font, and lexical model PRs. +# +name: Auto Approve and Merge PRs from keyman-server + +on: pull_request_target + +jobs: + auto-approve: + if: github.actor == 'keyman-server' && startsWith(github.head_ref, 'auto/') + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.AUTO_PR_APPROVAL_BY_KEYMAN_STATUS }} + permissions: write-all + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + sparse-checkout: | + README.md + sparse-checkout-cone-mode: false + - name: Approve pull request + run: | + gh pr review --approve ${{github.head_ref}} + - name: Enable auto-merge + run: | + gh pr merge --merge --auto ${{github.head_ref}} diff --git a/.github/workflows/auto-approve-keyman-server-pr.yml b/.github/workflows/auto-approve-keyman-server-pr.yml deleted file mode 100644 index 14d5be135..000000000 --- a/.github/workflows/auto-approve-keyman-server-pr.yml +++ /dev/null @@ -1,18 +0,0 @@ -# -# Automatically approves pull requests opened by keyman-server -# -# When a script creates a PR, this workflow will be triggered to approve the PR, -# and then auto-merge-keyman-server-pr.yml will merge it -# -name: Auto Approve PRs from keyman-server - -on: pull_request_target - -jobs: - auto-approve: - runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - - uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 - if: github.actor == 'keyman-server' diff --git a/.github/workflows/auto-merge-keyman-server-pr.yml b/.github/workflows/auto-merge-keyman-server-pr.yml deleted file mode 100644 index 4f5ff9a1d..000000000 --- a/.github/workflows/auto-merge-keyman-server-pr.yml +++ /dev/null @@ -1,38 +0,0 @@ -# -# Automatically merges pull requests opened by keyman-server. -# -# This workflow will be triggered to merge the PR once approved by the -# auto-approve-keyman-server-pr.yml script. -# -name: Auto Merge PRs from keyman-server -on: - pull_request: - types: - - labeled - - unlabeled - - synchronize - - opened - - edited - - ready_for_review - - reopened - - unlocked - pull_request_review: - types: - - submitted - status: - check_suite: - types: - - completed -jobs: - automerge: - runs-on: ubuntu-latest - steps: - - name: auto merge PR from keyman-server - uses: "pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584" # v0.15.6 - if: github.actor == 'keyman-server' - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - MERGE_LABELS: "auto" - MERGE_FORKS: false - MERGE_RETRY: 6 - MERGE_RETRY_SLEEP: 30000 diff --git a/keyboard/burushaski_girminas/2.0.25/burushaski_girminas-2.0.25.js b/keyboard/burushaski_girminas/2.0.25/burushaski_girminas-2.0.25.js new file mode 100644 index 000000000..72d2a3f44 --- /dev/null +++ b/keyboard/burushaski_girminas/2.0.25/burushaski_girminas-2.0.25.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_burushaski_girminas());}function Keyboard_burushaski_girminas(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_burushaski_girminas";this.KN="Burushaski Girminas";this.KMINVER="15.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={"shift": ["~","1","2","3","4","5","6","7","8","9","0","1","=","","","","q","w","é","r","ṭ","y","u","í","ó","p","[","]","","","","","á","ś","ḍ","f","ġ","ʰ","j","k","l",";","'","","","","","","","ẓ","x","ć","c̣","b","ṅ","m","m",",",".","","","","","",""],"default": ["~","1","2","3","4","5","6","7","8","9","0","1","=","","","","q","w","e","r","t","y","u","i","o","p","[","]","","","","","a","s","d","f","g","h","i","j","k","l",";","","","","","","","z","x","c","v","b","n","m","m",",",".","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH="śau, capan, c̣uk, ćapuk, chell, ḍaḍaṅ, ćhaq";this.KM=0;this.KBVER="2.0.25";this.KMBM=0x0010;this.KVKL={"tablet":{"font":"DejaVu Sans","fontsize":"1.1em","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_Q","pad":"20","text":"q"},{"id":"K_W","text":"w"},{"id":"K_E","text":"e","sk":[{"id":"U_00E9","text":"\u00E9"},{"id":"U_0113","text":"\u0113"},{"id":"U_1EBD","text":"\u1EBD"}]},{"id":"K_R","text":"r"},{"id":"K_T","text":"t","sk":[{"id":"U_1E6D","text":"\u1E6D"}]},{"id":"K_Y","text":"y","sk":[{"id":"U_1E8F","text":"\u1E8F"}]},{"id":"K_U","text":"u","sk":[{"id":"U_00FA","text":"\u00FA"},{"id":"U_0169","text":"\u0169"},{"id":"U_016B","text":"\u016B"}]},{"id":"K_I","text":"i","sk":[{"id":"U_00ED","text":"\u00ED"},{"id":"U_0129","text":"\u0129"},{"id":"U_012B","text":"\u012B"}]},{"id":"K_o","text":"o","sk":[{"id":"U_00F3","text":"\u00F3"},{"id":"U_00F5","text":"\u00F5"},{"id":"U_014D","text":"\u014D"}]},{"id":"K_P","text":"p"}]},{"id":"2","key":[{"width":"10","id":"T_new_366","sp":"10"},{"width":"99","id":"K_A","pad":"20","text":"a","sk":[{"id":"U_00E1","text":"\u00E1"},{"id":"U_00E3","text":"\u00E3"},{"id":"U_0101","text":"\u0101"}]},{"id":"K_S","pad":"20","text":"s","sk":[{"id":"U_015B","text":"\u015B"},{"id":"U_1E63","text":"\u1E63"}]},{"id":"K_D","pad":"20","text":"d","sk":[{"id":"U_1E0D","text":"\u1E0D"}]},{"id":"K_F","pad":"20","text":"f"},{"id":"K_G","pad":"20","text":"g","sk":[{"id":"U_0121","text":"\u0121"}]},{"id":"K_H","pad":"20","text":"h","sk":[{"id":"U_02B0","text":"\u02B0"}]},{"id":"K_J","pad":"20","text":"j"},{"id":"K_K","pad":"20","text":"k"},{"width":"99","id":"K_L","pad":"20","text":"l"},{"width":"1","id":"T_new_437","sp":"10"}]},{"id":"3","key":[{"nextlayer":"shift","width":"135","id":"K_SHIFT","pad":"20","sp":"1","text":"*Shift*"},{"id":"K_Z","pad":"20","text":"z","sk":[{"id":"U_1E93","text":"\u1E93"}]},{"id":"U_0078","pad":"20","text":"x"},{"id":"K_C","pad":"20","text":"c","sk":[{"id":"U_0107","text":"\u0107"}]},{"id":"K_V","pad":"20","text":"v"},{"id":"K_B","pad":"20","text":"b"},{"id":"K_N","pad":"20","text":"n","sk":[{"id":"U_1E45","text":"\u1E45"}]},{"id":"K_M","pad":"20","text":"m"},{"width":"135","id":"K_BKSP","pad":"20","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"135","id":"K_NUMLOCK","pad":"20","sp":"1","text":"*123*"},{"id":"K_LOPT","pad":"20","sp":"1","text":"*Menu*"},{"width":"1","id":"T_new_169","sp":"10"},{"id":"U_002C","text":","},{"width":"420","id":"K_SPACE","pad":"20"},{"id":"U_002E","text":"."},{"width":"1","id":"T_new_100","sp":"10"},{"width":"132","id":"K_ENTER","pad":"20","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"nextlayer":"numeric","id":"K_1","pad":"20","text":"1"},{"id":"K_2","pad":"20","text":"2","sk":[{"id":"U_0624","text":"\u0624"}]},{"id":"K_3","pad":"20","text":"3","sk":[{"id":"U_063A","text":"\u063A"}]},{"id":"K_4","pad":"20","text":"4","sk":[{"id":"U_0691","text":"\u0691"},{"id":"U_0699","text":"\u0699"},{"id":"U_0652","text":"\u0652"}]},{"id":"K_5","pad":"20","text":"5","sk":[{"id":"U_0679","text":"\u0679"}]},{"id":"K_6","text":"6"},{"id":"K_7","pad":"20","text":"7","sk":[{"id":"U_0626","text":"\u0626"}]},{"id":"K_8","pad":"20","text":"8"},{"id":"K_9","pad":"20","text":"9"}]},{"id":"2","key":[{"width":"20","id":"T_new_267","sp":"10"},{"id":"U_005F","pad":"20","text":"_"},{"id":"U_002F","pad":"20","text":"\/"},{"id":"U_003A","pad":"20","text":":"},{"id":"U_003B","pad":"20","text":";"},{"id":"U_0028","pad":"20","text":"("},{"id":"U_0029","pad":"20","text":")"},{"id":"U_0024","text":"$"},{"id":"U_0040","text":"@"},{"id":"K_0","text":"0"},{"width":"1","id":"T_new_448","sp":"10"}]},{"id":"3","key":[{"width":"20","id":"T_new_2210","sp":"10"},{"nextlayer":"default","layer":"default","width":"135","id":"K_HOME","pad":"20","sp":"1","text":"*abc*"},{"id":"U_007E","pad":"20","text":"~"},{"nextlayer":"default","id":"U_002C","pad":"20","text":","},{"nextlayer":"default","id":"U_003F","pad":"20","text":"?"},{"id":"U_0021","text":"!"},{"id":"U_0027","pad":"20","text":"'"},{"id":"U_0022","pad":"20","text":"\""},{"id":"K_BKSP","pad":"20","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"Num2","id":"K_SHIFT","pad":"20","text":"1\/2"},{"id":"K_LOPT","pad":"20","sp":"1","text":"*Menu*"},{"width":"1","id":"T_new_448","sp":"10"},{"width":"610","id":"K_SPACE","pad":"20"},{"width":"1","id":"T_new_570","sp":"10"},{"width":"105","id":"K_ENTER","pad":"20","sp":"1","text":"*Enter*"}]}]},{"id":"Num2","row":[{"id":"1","key":[{"nextlayer":"numeric","id":"K_1","pad":"20","text":"1"},{"id":"K_2","pad":"20","text":"2","sk":[{"id":"U_0624","text":"\u0624"}]},{"id":"K_3","pad":"20","text":"3","sk":[{"id":"U_063A","text":"\u063A"}]},{"id":"K_4","pad":"20","text":"4","sk":[{"id":"U_0691","text":"\u0691"},{"id":"U_0699","text":"\u0699"},{"id":"U_0652","text":"\u0652"}]},{"id":"K_5","pad":"20","text":"5","sk":[{"id":"U_0679","text":"\u0679"}]},{"id":"K_6","text":"6"},{"id":"K_7","pad":"20","text":"7","sk":[{"id":"U_0626","text":"\u0626"}]},{"id":"K_8","pad":"20","text":"8"},{"id":"K_9","pad":"20","text":"9"}]},{"id":"2","key":[{"id":"U_0040","pad":"20","text":"@"},{"id":"U_0023","pad":"20","text":"#"},{"id":"U_0024","pad":"20","text":"$"},{"id":"U_0025","pad":"20","text":"%"},{"id":"U_0026","pad":"20","text":"&"},{"id":"U_002D","pad":"20","text":"-"},{"id":"U_005B","pad":"20","text":"["},{"id":"U_005D","pad":"20","text":"]"},{"id":"K_0","text":"0"}]},{"id":"3","key":[{"nextlayer":"default","layer":"default","id":"K_HOME","pad":"20","sp":"1","text":"*abc*"},{"id":"U_0021","text":"!"},{"id":"U_0027","pad":"20","text":"'"},{"id":"U_0022","pad":"20","text":"\""},{"id":"U_003A","pad":"20","text":":"},{"id":"U_003B","pad":"20","text":";"},{"id":"U_007E","pad":"20","text":"~"},{"id":"U_003F","pad":"20","text":"?"},{"id":"K_BKSP","pad":"20","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","id":"K_NUMLOCK","pad":"20","sp":"1","text":"2\/2"},{"id":"K_LOPT","pad":"20","sp":"1","text":"*Menu*"},{"id":"U_002C","pad":"20","text":","},{"width":"448","id":"K_SPACE","pad":"20"},{"id":"U_002E","pad":"20","text":"."},{"width":"105","id":"K_ENTER","pad":"20","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"layer":"shift","id":"K_Q","pad":"20","text":"Q"},{"id":"K_W","text":"W"},{"id":"K_E","text":"E"},{"id":"K_R","text":"R"},{"id":"K_T","text":"T","sk":[{"id":"U_1E6D","text":"\u1E6D"}]},{"id":"K_Y","text":"Y","sk":[{"id":"U_1E8F","text":"\u1E8F"}]},{"id":"K_U","text":"U"},{"id":"K_I","text":"I"},{"id":"K_o","text":"O"},{"id":"K_P","text":"P"}]},{"id":"2","key":[{"width":"10","id":"T_new_407","sp":"10"},{"id":"K_A","pad":"20","text":"A"},{"id":"K_S","pad":"20","text":"S","sk":[{"id":"U_015B","text":"\u015B"},{"id":"U_1E63","text":"\u1E63"}]},{"id":"K_D","pad":"20","text":"D","sk":[{"id":"U_1E0D","text":"\u1E0D"}]},{"id":"K_F","pad":"20","text":"F"},{"id":"K_G","pad":"20","text":"G","sk":[{"id":"U_0121","text":"\u0121"}]},{"id":"K_H","pad":"20","text":"H","sk":[{"id":"U_02B0","text":"\u02B0"}]},{"id":"K_J","pad":"20","text":"J"},{"id":"K_K","pad":"20","text":"K"},{"id":"K_L","pad":"20","text":"L"},{"width":"1","id":"T_new_519","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","width":"135","id":"K_SHIFT","pad":"20","sp":"1","text":"*Shifted*"},{"id":"K_Z","pad":"20","text":"Z","sk":[{"id":"U_1E93","text":"\u1E93"}]},{"id":"U_0058","pad":"20","text":"X"},{"id":"K_C","pad":"20","text":"C","sk":[{"id":"U_0107","text":"\u0107"}]},{"id":"K_V","pad":"20","text":"V"},{"id":"K_B","pad":"20","text":"B"},{"id":"K_N","pad":"20","text":"N","sk":[{"id":"U_1E45","text":"\u1E45"}]},{"id":"K_M","pad":"20","text":"M"},{"width":"135","id":"K_BKSP","pad":"20","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"135","id":"K_NUMLOCK","pad":"20","sp":"1","text":"*123*"},{"id":"K_LOPT","pad":"20","sp":"1","text":"*Menu*"},{"width":"1","id":"T_new_1096","sp":"10"},{"id":"U_002C","text":","},{"width":"420","id":"K_SPACE","pad":"20"},{"id":"U_002E","text":"."},{"width":"1","id":"T_new_1228","sp":"10"},{"width":"132","id":"K_ENTER","pad":"20","sp":"1","text":"*Enter*"}]}]}]}};this.s14="aeiouAEIO";this.s15="áéíóúÁÉÍÓÚ";this.s16="ãẽĩõũÃẼĨÕŨ";this.s17="āēīōūĀĒĪŌŪ";this.s18="csCS";this.s19="ćśĆŚ";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16400,65)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Á");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ã");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ā");}}else if(k.KKM(e,16400,67)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ć");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"C̣");}else if(k.KFCM(1,t,['C'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"C̣");}}else if(k.KKM(e,16400,68)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ḍ");}}else if(k.KKM(e,16400,69)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"É");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ẽ");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ē");}}else if(k.KKM(e,16400,71)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ġ");}}else if(k.KKM(e,16400,73)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Í");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ĩ");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ī");}}else if(k.KKM(e,16400,78)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ṅ");}else if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ṇ");}}else if(k.KKM(e,16400,79)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ó");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Õ");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ō");}}else if(k.KKM(e,16400,83)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ś");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ṣ");}}else if(k.KKM(e,16400,84)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ṭ");}}else if(k.KKM(e,16400,89)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ẏ");}}else if(k.KKM(e,16400,90)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"Ẓ");}}else if(k.KKM(e,16384,65)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"á");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ã");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ā");}}else if(k.KKM(e,16384,67)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ć");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"c̣");}else if(k.KFCM(1,t,['c'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"c̣");}}else if(k.KKM(e,16384,68)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ḍ");}}else if(k.KKM(e,16384,69)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"é");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ẽ");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ē");}}else if(k.KKM(e,16384,71)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ġ");}}else if(k.KKM(e,16384,72)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ʰ");}}else if(k.KKM(e,16384,73)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"í");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ĩ");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ī");}}else if(k.KKM(e,16384,78)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ṅ");}else if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ṇ");}}else if(k.KKM(e,16384,79)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ó");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"õ");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ō");}}else if(k.KKM(e,16384,83)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ś");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ṣ");}}else if(k.KKM(e,16384,84)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ṭ");}}else if(k.KKM(e,16384,85)) {if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ú");}else if(k.KFCM(1,t,['~'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ũ");}else if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ū");}}else if(k.KKM(e,16384,89)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ẏ");}}else if(k.KKM(e,16384,90)) {if(k.KFCM(1,t,['.'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ẓ");}}return r;};} \ No newline at end of file diff --git a/keyboard/burushaski_girminas_perso_arabic/1.25/burushaski_girminas_perso_arabic-1.25.js b/keyboard/burushaski_girminas_perso_arabic/1.25/burushaski_girminas_perso_arabic-1.25.js new file mode 100644 index 000000000..8b2b4df58 --- /dev/null +++ b/keyboard/burushaski_girminas_perso_arabic/1.25/burushaski_girminas_perso_arabic-1.25.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_burushaski_girminas_perso_arabic());}function Keyboard_burushaski_girminas_perso_arabic(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_burushaski_girminas_perso_arabic";this.KN="Burushaski Girminas (بروشسکی)";this.KMINVER="15.0";this.KV={F:' 1em "Burusho Quwatz Nastaliq"',K102:0};this.KV.KLS={"shift-alt": ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","آ","","","","","","","","","","”","","","","","","","","","","ۗ","","","","","","","","","","","",""],"shift-ctrl": ["","","","","","","","","","","","ّ","","","","","","","","رْ","","","","","","","","","؎","","","","اࣷ","","","","","","","","","","“","","","","","","","ژ","","څ","","","ݩ","","","","","","","","","",""],"shift": ["ً","","","","","","","","",")","(","","","","","","ْ","ﷺ","ؑ","ڑ","ٹ","","ٔ","ٰ","ۃ","ُ","}","{","","","","","ٓ","ص","ڈ","ٖ","غ","ح","ض","خ","ؒ",":","\"","","","","","","","ذ","ݜ","ث","ظ","ؓ","ں","","ِ","َ","؟","","","","","",""],"ctrl": ["","","","","","","","","","","","","","","","","","","","","","","ٕ","ئ","","ٌ","","","ؔ","","","","","","","","","","","","","","‘","","","","","","","ژ","","څ","","","","","","","٪","","","","","",""],"alt": ["","","","","","","","","","","","ّ","","","","","","","","","","","ٔ","","","","","","","","","","","","","","","","","","","","’","","","","","","","","","","","ٮ","","","","","","","","","","",""],"default": ["ٍ","1","2","3","4","5","6","7","8","9","0","","","","","","ق","و","ع","ر","ت","ے","ئ","ی","ہ","پ","]","[","\\","","","","ا","س","د","ف","گ","ھ","ج","ک","ل","؛","'","","","","","","","ز","ش","چ","ط","ب","ن","م","،","۔","/","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=1;this.KH="څنژ، ژمےࣷ، ݜمن، ݜپیک";this.KM=0;this.KBVER="1.25";this.KMBM=0x0070;this.KRTL=1;this.KVKL={"tablet":{"font":"Burusho Quwatz Nastaliq","fontsize":"1.10em","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_Q","pad":"20","text":"\u0642"},{"id":"K_W","text":"\u0648","hint":"\u0632","sk":[{"id":"U_0624","text":"\u0624"}]},{"id":"U_06CC_08F7","text":"\u06CC\u08F7","hint":"\u0639","sk":[{"id":"U_063A","text":"\u063A"}]},{"id":"K_R","text":"\u0631","hint":"\u0632","sk":[{"id":"U_0691","text":"\u0691"},{"id":"U_0699","text":"\u0699"},{"id":"U_0652","text":"\u0652"}]},{"id":"K_T","text":"\u062A","sk":[{"id":"U_0679","text":"\u0679"}]},{"id":"K_Y","text":"\u06D2"},{"id":"K_I","text":"\u06CC","sk":[{"id":"U_0626","text":"\u0626"}]},{"id":"K_O","text":"\u06C1"},{"id":"K_P","text":"\u067E"}]},{"id":"2","key":[{"id":"K_A","pad":"20","text":"\u0627","sk":[{"id":"U_0622","text":"\u0622"}]},{"id":"K_S","text":"\u0633","hint":"\u075C","sk":[{"id":"U_0634","text":"\u0634"}]},{"id":"K_D","text":"\u062F","hint":"\u0688","sk":[{"id":"U_0688","text":"\u0688"}]},{"id":"K_F","text":"\u0641"},{"id":"K_G","text":"\u06AF","sk":[{"id":"U_063A","text":"\u063A"}]},{"id":"U_06BE","text":"\u06BE","sk":[{"id":"U_062D","text":"\u062D"},{"id":"U_062E","text":"\u062E"}]},{"id":"K_J","text":"\u062C","sk":[{"id":"U_0698","text":"\u0698"}]},{"id":"K_K","text":"\u06A9"},{"id":"K_L","text":"\u0644","sk":[{"id":"U_06B5","text":"\u06B5"},{"id":"U_0652","text":"\u0652"}]}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","pad":"20","sp":"1","text":"*Shifted*"},{"id":"U_0630","text":"\u0630","sk":[{"id":"U_0630","text":"\u0630"}]},{"id":"U_0634","text":"\u0634","sk":[{"id":"U_0638","text":"\u0638"}]},{"id":"K_C","text":"\u0686","sk":[{"id":"U_062B","text":"\u062B"}]},{"id":"U_0637","text":"\u0637","hint":"\u0638","sk":[{"id":"U_0636","text":"\u0636"}]},{"id":"K_B","text":"\u0628"},{"id":"K_N","text":"\u0646","sk":[{"id":"U_06BA","text":"\u06BA"},{"id":"U_0769","text":"\u0769"}]},{"id":"K_M","text":"\u0645"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"rightalt","layer":"rightalt-shift","id":"T_new_102","pad":"20","sp":"1","text":"*Symbol*"},{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"numeric","width":"5","id":"T_new_327","sp":"10"},{"width":"75","id":"U_060C","text":"\u060C"},{"width":"5","id":"T_new_3804","sp":"10"},{"width":"400","id":"K_SPACE"},{"width":"5","id":"T_new_364","sp":"10"},{"width":"95","id":"U_06D4","text":" \u06D4 ","sk":[{"layer":"shift","id":"U_0021","text":"!"},{"id":"U_0027","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"shift","id":"U_061F","text":"\u061F"},{"id":"K_COLON","text":"\u061B"},{"id":"K_COMMA","text":"\u060C"}]},{"width":"5","id":"T_new_3920","sp":"10"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"nextlayer":"default","id":"U_0627_08F7","pad":"20","text":"\u0627\u08F7"},{"nextlayer":"default","id":"U_0632","text":"\u0632"},{"nextlayer":"default","id":"U_0639","text":"\u0639"},{"nextlayer":"default","id":"U_0631_0652","text":"\u0631\u0652"},{"nextlayer":"default","id":"K_T","text":"\u0679"},{"nextlayer":"default","id":"U_06D2_08F7","text":"\u06D2\u08F7"},{"nextlayer":"default","id":"U_0626","text":"\u0626"},{"nextlayer":"default","id":"U_06CC_08F7","text":"\u06CC\u08F7"},{"nextlayer":"default","id":"U_0636","text":"\u0636"}]},{"id":"2","key":[{"nextlayer":"default","id":"U_0622","pad":"20","text":"\u0622"},{"nextlayer":"default","id":"U_0635","text":"\u0635","sk":[{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"\u061F"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":"\u061B"},{"layer":"default","id":"K_COMMA","text":"\u060C"}]},{"nextlayer":"default","id":"K_D","text":"\u0688"},{"nextlayer":"default","id":"K_R","text":"\u0691"},{"nextlayer":"default","id":"K_G","text":"\u063A"},{"nextlayer":"default","id":"U_062D","text":"\u062D"},{"nextlayer":"default","id":"U_0685","text":"\u0685"},{"nextlayer":"default","id":"K_K","text":"\u062E"},{"nextlayer":"default","id":"U_0644_0652","text":"\u0644\u0652"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","pad":"20","sp":"1","text":"*Shift*","hint":"\u27A1"},{"nextlayer":"default","layer":"default","id":"U_08F7","text":"\u068E"},{"nextlayer":"default","id":"U_0698","text":"\u0698"},{"nextlayer":"default","id":"U_075C","text":"\u075C"},{"nextlayer":"default","id":"K_V","text":"\u0638"},{"nextlayer":"default","id":"U_0769","text":"\u0769"},{"nextlayer":"default","id":"K_N","text":"\u06BA"},{"nextlayer":"default","id":"U_06B5","text":"\u06B5"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","id":"K_NUMLOCK","pad":"20","sp":"1","text":"!#1"},{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"5","id":"T_new_3129","sp":"10"},{"width":"75","id":"U_060C","text":"\u060C"},{"width":"5","id":"T_new_2888","sp":"10"},{"width":"400","id":"K_SPACE"},{"width":"5","id":"T_new_3196","sp":"10"},{"nextlayer":"rightalt","width":"95","id":"U_06D4","text":"\u06D4"},{"width":"5","id":"T_new_3069","sp":"10"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"rightalt","row":[{"id":"1","key":[{"nextlayer":"default","id":"U_0610","pad":"20","text":"\u0610"},{"nextlayer":"default","id":"U_0611","text":"\u0611"},{"nextlayer":"default","id":"U_FDFD","text":"\uFDFD"},{"nextlayer":"default","id":"U_0612","text":"\u0612"},{"nextlayer":"default","id":"U_FDF2","text":"\uFDF2"},{"nextlayer":"default","id":"U_064E","text":"\u064E"},{"nextlayer":"default","id":"U_064F","text":"\u064F"}]},{"id":"2","key":[{"nextlayer":"default","id":"U_0653","pad":"20","text":"\u0653"},{"nextlayer":"default","id":"U_0614","text":"\u0614"},{"nextlayer":"default","id":"U_064B","text":"\u064B"},{"nextlayer":"default","id":"U_0644_0652","text":"\u0644\u0652"},{"nextlayer":"default","id":"U_0651","text":"\u0651"},{"nextlayer":"default","id":"U_06E1"},{"nextlayer":"default","id":"U_0650","text":"\u0650"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","pad":"20","sp":"1","text":"\u0627\u0628"},{"nextlayer":"default","id":"U_062B","text":"\u062B"},{"id":"U_0631_0652","text":"\u0631\u0652","hint":"\u0652"},{"nextlayer":"default","id":"U_061F","text":"\u061F"},{"nextlayer":"default","id":"U_06CE","text":"\u06CE"},{"nextlayer":"default","id":"U_08F7","text":"\u06D2\u065A"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"115","id":"K_NUMLOCK","pad":"20","sp":"1","text":"*123*"},{"nextlayer":"default","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"329","id":"K_SPACE"},{"id":"U_06D4","text":"\u06D4"},{"width":"99","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"rightalt-shift","row":[{"id":"1","key":[{"id":"U_06F9","pad":"20","text":"\u06F9"},{"id":"U_06F8","text":"\u06F8"},{"id":"U_06F7","text":"\u06F7"},{"id":"U_06F6","text":"\u06F6"},{"id":"U_06F5","text":"\u06F5"},{"id":"U_06F4","text":"\u06F4"},{"id":"U_06F3","text":"\u06F3"},{"id":"U_06F2","text":"\u06F2"},{"id":"U_06F1","text":"\u06F1"}]},{"id":"2","key":[{"id":"U_0040","pad":"20","text":"@"},{"id":"U_0023","text":"#"},{"id":"U_0024","text":"$"},{"id":"U_0025","text":"%"},{"id":"U_0026","text":"&"},{"id":"U_005F","text":"*"},{"id":"U_0028","text":"("},{"id":"U_0029","text":")"},{"id":"U_06F0","text":"\u06F0"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","pad":"20","sp":"1","text":"*Shift*"},{"id":"U_0021","text":"!"},{"id":"U_002D","text":"-"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_003A","text":":"},{"id":"U_061B","text":"\u061B"},{"id":"U_061F","text":"\u061F"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"101","id":"K_SHIFT","pad":"20","sp":"1","text":"2\/2"},{"layer":"default","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"U_002C","text":"\u060C"},{"width":"443","id":"K_SPACE"},{"id":"U_06D4","text":"\u06D4"},{"width":"99","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","pad":"20","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"}]},{"id":"2","key":[{"id":"U_002B","pad":"20","text":"+"},{"id":"U_00D7","text":"\u00D7"},{"id":"U_00F7","text":"\u00F7"},{"id":"U_003D","text":"="},{"id":"U_002F","text":"\/"},{"id":"U_005F","text":"_"},{"id":"U_0028","text":"("},{"id":"U_0029","text":")"},{"id":"K_0","text":"0"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","pad":"20","sp":"1","text":"*Shift*"},{"id":"U_0021","text":"!"},{"id":"U_002D","text":"-"},{"id":"U_0027","text":"'"},{"id":"U_061F","text":"\u061F"},{"id":"U_0022","text":"\""},{"id":"U_003A","text":":"},{"id":"U_061B","text":"\u061B"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"rightalt-shift","width":"101","id":"K_SHIFT","pad":"20","sp":"1","text":"1\/2"},{"layer":"default","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"U_060C","text":"\u060C"},{"width":"443","id":"K_SPACE"},{"id":"U_06D4","text":"\u06D4"},{"width":"99","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KCSS=".tablet .kmw-key-text{position:relative;left:0;top: -8%;-webkit-user-select:none;}\n ";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16464,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"”");}}else if(k.KKM(e,16432,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"“");}}else if(k.KKM(e,16400,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\"");}}else if(k.KKM(e,16416,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‘");}}else if(k.KKM(e,16448,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"’");}}else if(k.KKM(e,16384,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"'");}}else if(k.KKM(e,16400,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,")");}}else if(k.KKM(e,16400,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"(");}}else if(k.KKM(e,16384,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"،");}}else if(k.KKM(e,16448,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ّ");}}else if(k.KKM(e,16384,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"۔");}}else if(k.KKM(e,16416,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"٪");}}else if(k.KKM(e,16384,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"/");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"0");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"1");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"2");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"3");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"4");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"5");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"6");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"7");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"8");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"9");}}else if(k.KKM(e,16400,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,":");}}else if(k.KKM(e,16384,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"؛");}}else if(k.KKM(e,16400,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ِ");}}else if(k.KKM(e,16400,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"َ");}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"؟");}}else if(k.KKM(e,16464,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"آ");}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٓ");}}else if(k.KKM(e,16432,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"اࣷ");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ؓ");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ث");}}else if(k.KKM(e,16432,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"څ");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ڈ");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ؑ");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٖ");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"غ");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ح");}}else if(k.KKM(e,16400,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٰ");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ض");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"خ");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ؒ");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ں");}}else if(k.KKM(e,16432,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ݩ");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ۃ");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ُ");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ْ");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ڑ");}}else if(k.KKM(e,16432,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"رْ");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ص");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٹ");}}else if(k.KKM(e,16400,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٔ");}}else if(k.KKM(e,16464,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ۗ");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ظ");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ﷺ");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ݜ");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ذ");}}else if(k.KKM(e,16432,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ژ");}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"]");}}else if(k.KKM(e,16416,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ؔ");}}else if(k.KKM(e,16384,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\\");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"[");}}else if(k.KKM(e,16432,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ّ");}}else if(k.KKM(e,16384,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٍ");}}else if(k.KKM(e,16384,65)) {if(k.KFCM(1,t,['،'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"اࣷ");}else if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"آ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ا");}}else if(k.KKM(e,16448,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٮ");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ب");}}else if(k.KKM(e,16384,67)) {if(k.KFCM(1,t,['،'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ڎ");}else if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"څ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"چ");}}else if(k.KKM(e,16384,68)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ذ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"د");}}else if(k.KKM(e,16384,69)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"غ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ع");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ف");}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"گ");}}else if(k.KKM(e,16384,72)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ْ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ھ");}}else if(k.KKM(e,16384,73)) {if(k.KFCM(1,t,['،'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"یࣷ");}else if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ێ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ی");}}else if(k.KKM(e,16416,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ئ");}}else if(k.KKM(e,16384,74)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ض");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ج");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ک");}}else if(k.KKM(e,16384,76)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ڵ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ل");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"م");}}else if(k.KKM(e,16384,78)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ݩ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ن");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ہ");}}else if(k.KKM(e,16416,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٌ");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"پ");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ق");}}else if(k.KKM(e,16384,82)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ز");}else if(k.KFCM(1,t,['ر'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"رْ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ر");}}else if(k.KKM(e,16384,83)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ݜ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"س");}}else if(k.KKM(e,16384,84)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ٹ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ت");}}else if(k.KKM(e,16448,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٔ");}}else if(k.KKM(e,16416,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ٕ");}}else if(k.KKM(e,16384,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ئ");}}else if(k.KKM(e,16384,86)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ظ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ط");}}else if(k.KKM(e,16384,87)) {if(k.KFCM(1,t,['،'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"وࣷ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"و");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ش");}}else if(k.KKM(e,16384,89)) {if(k.KFCM(1,t,['،'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ےࣷ");}else if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ےٚ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ے");}}else if(k.KKM(e,16384,90)) {if(k.KFCM(1,t,['۔'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ژ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ز");}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"}");}}else if(k.KKM(e,16432,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"؎");}}if(m) {}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"{");}}else if(k.KKM(e,16400,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ً");}}return r;};} \ No newline at end of file diff --git a/keyboard/deseret/1.2/deseret-1.2.js b/keyboard/deseret/1.2/deseret-1.2.js new file mode 100644 index 000000000..0e68245f4 --- /dev/null +++ b/keyboard/deseret/1.2/deseret-1.2.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_deseret());}function Keyboard_deseret(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_deseret";this.KN="Deseret";this.KMINVER="14.0";this.KV={F:' 1em "Noto Sans Deseret"',K102:0};this.KV.KLS={"default": ["`","1","2","3","4","5","6","7","8","9","0","-","=","","","","","𐐶","𐐯","𐑉","𐐻","𐐷","𐐳","𐐮","𐐲","𐐹","[","]","\\","","","","𐐰","𐑅","𐐼","𐑁","𐑀","𐐸","𐐾","𐐿","𐑊",";","'","","","","","","\\","𐑆","","𐐽","𐑂","𐐺","𐑌","𐑋",",",".","/","","","","","",""],"shift": ["~","!","@","#","$","%","^","&","*","(",")","_","+","","","","","𐐎","𐐇","𐐡","𐐓","𐐏","𐐋","𐐆","𐐊","𐐑","{","}","|","","","","𐐈","𐐝","𐐔","𐐙","𐐘","𐐐","𐐖","𐐗","𐐢",":","\"","","","","","","|","𐐞","","𐐕","𐐚","𐐒","𐐤","𐐣","<",">","?","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=1;this.KH='';this.KM=0;this.KBVER="1.2";this.KMBM=0x0010;this.KS=1;this.KVKL={"tablet":{"displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"id":"K_HYPHEN","text":"-"},{"id":"K_EQUAL","text":"="},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"2","key":[{"id":"K_Q","pad":"75"},{"id":"K_W","text":"\uD801\uDC36"},{"id":"K_E","text":"\uD801\uDC2F","sk":[{"id":"U_010429"},{"id":"U_01044f"}]},{"id":"K_R","text":"\uD801\uDC49"},{"id":"K_T","text":"\uD801\uDC3B","sk":[{"id":"U_010443"}]},{"id":"K_Y","text":"\uD801\uDC37"},{"id":"K_U","text":"\uD801\uDC33","sk":[{"id":"U_01042d"}]},{"id":"K_I","text":"\uD801\uDC2E","sk":[{"id":"U_010428"},{"id":"U_010434"}]},{"id":"K_O","text":"\uD801\uDC32","sk":[{"id":"U_01042c"},{"id":"U_010435"},{"id":"U_01044e"}]},{"id":"K_P","text":"\uD801\uDC39"},{"id":"K_LBRKT","text":"["},{"id":"K_RBRKT","text":"]"},{"width":"10","id":"T_new_136","sp":"10"}]},{"id":"3","key":[{"id":"K_A","pad":"115","text":"\uD801\uDC30","sk":[{"id":"U_01042a"},{"id":"U_01042b"},{"id":"U_010431"},{"id":"U_01044e"}]},{"id":"K_S","text":"\uD801\uDC45","sk":[{"id":"U_010447"}]},{"id":"K_D","text":"\uD801\uDC3C","sk":[{"id":"U_010444"}]},{"id":"K_F","text":"\uD801\uDC41"},{"id":"K_G","text":"\uD801\uDC40"},{"id":"K_H","text":"\uD801\uDC38"},{"id":"K_J","text":"\uD801\uDC3E"},{"id":"K_K","text":"\uD801\uDC3F"},{"id":"K_L","text":"\uD801\uDC4A"},{"id":"K_COLON","text":";"},{"id":"K_QUOTE","text":"'"},{"id":"K_BKSLASH","text":"\\"}]},{"id":"4","key":[{"nextlayer":"shift","width":"160","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"\uD801\uDC46","sk":[{"id":"U_010448"}]},{"id":"K_X"},{"id":"K_C","text":"\uD801\uDC3D"},{"id":"K_V","text":"\uD801\uDC42"},{"id":"K_B","text":"\uD801\uDC3A"},{"id":"K_N","text":"\uD801\uDC4C","sk":[{"id":"U_01044d"}]},{"id":"K_M","text":"\uD801\uDC4B"},{"id":"K_COMMA","text":","},{"id":"K_PERIOD","text":"."},{"id":"K_SLASH","text":"\/"},{"id":"K_BKQUOTE","text":"`"},{"width":"10","id":"T_new_162","sp":"10"}]},{"id":"5","key":[{"width":"140","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"930","id":"K_SPACE"},{"width":"145","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_1","text":"!"},{"id":"K_2","text":"@"},{"id":"K_3","text":"#"},{"id":"K_4","text":"$"},{"id":"K_5","text":"%"},{"id":"K_6","text":"^"},{"id":"K_7","text":"&"},{"id":"K_8","text":"*"},{"id":"K_9","text":"("},{"id":"K_0","text":")"},{"id":"K_HYPHEN","text":"_"},{"id":"K_EQUAL","text":"+"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"2","key":[{"id":"K_Q","pad":"75"},{"id":"K_W","text":"\uD801\uDC0E"},{"id":"K_E","text":"\uD801\uDC07","sk":[{"id":"U_010401"},{"id":"U_010427"}]},{"id":"K_R","text":"\uD801\uDC21"},{"id":"K_T","text":"\uD801\uDC13","sk":[{"id":"U_01041b"}]},{"id":"K_Y","text":"\uD801\uDC0F"},{"id":"K_U","text":"\uD801\uDC0B","sk":[{"id":"U_010405"}]},{"id":"K_I","text":"\uD801\uDC06","sk":[{"id":"U_010400"},{"id":"U_01040c"}]},{"id":"K_O","text":"\uD801\uDC0A","sk":[{"id":"U_010404"},{"id":"U_01040d"},{"id":"U_010426"}]},{"id":"K_P","text":"\uD801\uDC11"},{"id":"K_LBRKT","text":"{"},{"id":"K_RBRKT","text":"}"},{"width":"10","id":"T_new_245","sp":"10"}]},{"id":"3","key":[{"id":"K_A","pad":"115","text":"\uD801\uDC08","sk":[{"id":"U_010402"},{"id":"U_010403"},{"id":"U_010409"},{"id":"U_010426"}]},{"id":"K_S","text":"\uD801\uDC1D","sk":[{"id":"U_01041f"}]},{"id":"K_D","text":"\uD801\uDC14","sk":[{"id":"U_01041c"}]},{"id":"K_F","text":"\uD801\uDC19"},{"id":"K_G","text":"\uD801\uDC18"},{"id":"K_H","text":"\uD801\uDC10"},{"id":"K_J","text":"\uD801\uDC16"},{"id":"K_K","text":"\uD801\uDC17"},{"id":"K_L","text":"\uD801\uDC22"},{"id":"K_COLON","text":":"},{"id":"K_QUOTE","text":"\""},{"id":"K_BKSLASH","text":"|"}]},{"id":"4","key":[{"nextlayer":"default","width":"160","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"\uD801\uDC1E","sk":[{"id":"U_010420"}]},{"id":"K_X"},{"id":"K_C","text":"\uD801\uDC15"},{"id":"K_V","text":"\uD801\uDC1A"},{"id":"K_B","text":"\uD801\uDC12"},{"id":"K_N","text":"\uD801\uDC24","sk":[{"id":"U_010425"}]},{"id":"K_M","text":"\uD801\uDC23"},{"id":"K_COMMA","text":"<"},{"id":"K_PERIOD","text":">"},{"id":"K_SLASH","text":"?"},{"id":"K_BKQUOTE","text":"~"},{"width":"10","id":"T_new_271","sp":"10"}]},{"id":"5","key":[{"width":"140","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"930","id":"K_SPACE"},{"width":"145","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.s9="qxQX";this.s10="abcdefghijklmnoprstuvwyz";this.s11="𐐰𐐺𐐽𐐼𐐯𐑁𐑀𐐸𐐮𐐾𐐿𐑊𐑋𐑌𐐲𐐹𐑉𐑅𐐻𐐳𐑂𐐶𐐷𐑆";this.s12="aeghiouwy";this.s13="𐐰𐐯𐑀𐐸𐐮𐐲𐐳𐐶𐐷";this.s14="ABCDEFGHIJKLMNOPRSTUVWYZ";this.s15="𐐈𐐒𐐕𐐔𐐇𐐙𐐘𐐐𐐆𐐖𐐗𐐢𐐣𐐤𐐊𐐑𐐡𐐝𐐓𐐋𐐚𐐎𐐏𐐞";this.s16="AEGHIOUWY";this.s17="𐐈𐐇𐐘𐐐𐐆𐐊𐐋𐐎𐐏";this.s18="abcdefghijklmnoprstuvwyzABCDEFGHIJKLMNOPRSTUVWYZ";this.s19="𐐰𐐺𐐽𐐼𐐯𐑁𐑀𐐸𐐮𐐾𐐿𐑊𐑋𐑌𐐲𐐹𐑉𐑅𐐻𐐳𐑂𐐶𐐷𐑆𐐈𐐒𐐕𐐔𐐇𐐙𐐘𐐐𐐆𐐖𐐗𐐢𐐣𐐤𐐊𐐑𐐡𐐝𐐓𐐋𐐚𐐎𐐏𐐞";this.s20="aeghiouwyAEGHIOUWY";this.s21="𐐰𐐯𐑀𐐸𐐮𐐲𐐳𐐶𐐷𐐈𐐇𐐘𐐐𐐆𐐊𐐋𐐎𐐏";this.s22="𐐰𐐯𐐲";this.s23="𐐈𐐇𐐊";this.s24="𐐫𐑏𐐵";this.s25="𐐃𐐧𐐍";this.s26="𐐰𐐯𐐲";this.s27="𐐈𐐇𐐊";this.s28="𐐱𐑏𐐵";this.s29="𐐉𐐧𐐍";this.s30="𐐼𐐹𐑅𐐻𐑆";this.s31="𐐔𐐑𐐝𐐓𐐞";this.s32="𐑄𐑁𐑇𐑃𐑈";this.s33="𐐜𐐙𐐟𐐛𐐠";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16400,65)) {if(k.KFCM(1,t,['𐐈'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐂");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐈");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐈");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐒");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐕");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐔");}}else if(k.KKM(e,16400,69)) {if(k.KFCM(1,t,['𐐇'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐁");}else if(k.KFCM(1,t,['𐐆'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐌");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐇");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐇");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐙");}}else if(k.KKM(e,16400,71)) {if(k.KFCM(1,t,['𐐤'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐥");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐘");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐘");}}else if(k.KKM(e,16400,72)) {if(k.KFCM(1,t,[{t:'a',a:this.s31}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s33,1,t);}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐐");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐐");}}else if(k.KKM(e,16400,73)) {if(k.KFCM(1,t,['𐐆'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐀");}else if(k.KFCM(1,t,['𐐊'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐦");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐆");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐆");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐖");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐗");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐢");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐣");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐤");}}else if(k.KKM(e,16400,79)) {if(k.KFCM(1,t,['𐐊'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐄");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐊");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐊");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐑");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐡");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐝");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐓");}}else if(k.KKM(e,16400,85)) {if(k.KFCM(1,t,['𐐋'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐅");}else if(k.KFCM(1,t,[{t:'a',a:this.s27}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s29,1,t);}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐋");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐋");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐚");}}else if(k.KKM(e,16400,87)) {if(k.KFCM(1,t,[{t:'a',a:this.s23}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s25,1,t);}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐎");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐎");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,89)) {if(k.KFCM(1,t,['𐐊'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐦");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐏");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐏");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐞");}}else if(k.KKM(e,16384,65)) {if(k.KFCM(1,t,['𐐰'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐪");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐰");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐰");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐺");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐽");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐼");}}else if(k.KKM(e,16384,69)) {if(k.KFCM(1,t,['𐐯'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐩");}else if(k.KFCM(1,t,['𐐮'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐴");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐯");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐯");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑁");}}else if(k.KKM(e,16384,71)) {if(k.KFCM(1,t,['𐑌'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐑍");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐑀");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑀");}}else if(k.KKM(e,16384,72)) {if(k.KFCM(1,t,[{t:'a',a:this.s30}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s32,1,t);}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐸");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐸");}}else if(k.KKM(e,16384,73)) {if(k.KFCM(1,t,['𐐮'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐨");}else if(k.KFCM(1,t,['𐐲'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐑎");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐮");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐮");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐾");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐿");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑊");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑋");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑌");}}else if(k.KKM(e,16384,79)) {if(k.KFCM(1,t,['𐐲'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐬");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐲");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐲");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐹");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑉");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑅");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐻");}}else if(k.KKM(e,16384,85)) {if(k.KFCM(1,t,['𐐳'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐭");}else if(k.KFCM(1,t,[{t:'a',a:this.s26}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s28,1,t);}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐳");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐳");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑂");}}else if(k.KKM(e,16384,87)) {if(k.KFCM(1,t,[{t:'a',a:this.s22}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s24,1,t);}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐶");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐶");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,89)) {if(k.KFCM(1,t,['𐐲'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐑎");}else if(k.KFCM(1,t,['\\'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𐐷");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐐷");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𐑆");}}return r;};} \ No newline at end of file diff --git a/keyboard/fv_dene_zhatie/10.0.2/fv_dene_zhatie-10.0.2.js b/keyboard/fv_dene_zhatie/10.0.2/fv_dene_zhatie-10.0.2.js new file mode 100644 index 000000000..cd872db88 --- /dev/null +++ b/keyboard/fv_dene_zhatie/10.0.2/fv_dene_zhatie-10.0.2.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_fv_dene_zhatie());}function Keyboard_fv_dene_zhatie(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_fv_dene_zhatie";this.KN="Dene Zhatıé";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={"rightalt": ["`","","","","","","","","","«","»","","=","","","","","","","","","","","i","","","[","]","\\","","","","","","","","","","","","",";","","","","","","","","","","","","","","","","","/","","","","","",""],"rightalt-shift": ["~","","","","","","","","","‹","›","","+","","","","","","","","","","","I","","","","","|","","","","","","","","","","","","",":","","","","","","","","","","","","","","","","","?","","","","","",""],"default": ["´","1","2","3","4","5","6","7","8","9","0","-","ṉ","","","","q","w","e","r","t","y","u","ı","o","p","˛","˛́","\\","","","","a","s","d","f","g","h","j","k","l","ł","’","","","","","","","z","x","c","v","b","n","m",",",".","ɂ","","","","","",""],"shift": ["~","!","@","#","$","%","^","&","*","(",")","+","Ṉ","","","","Q","W","E","R","T","Y","U","I","O","P","{","}","|","","","","A","S","D","F","G","H","J","K","L","Ł","\"","","","","","","","Z","X","C","V","B","N","M","<",">","ʔ","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH=' Dene Zhatıé
  • The special characters of Dene Zhatıé have been assigned to a mix of both number and punctuation keys.
  • All accents are typed after the base character: ų is typed u then Left Bracket [
  • To type the acute accent use the Backquote key ` — á is typed a then backquote `
  • To type the ogonek accent use the the Left Bracket key [ — ų is typed u then Left Bracket [
  • To type the acute and ogonek accent at the same time use the Right Bracket key ] — ǫ́ is typed o then Right Bracket ]
  • To type the underlined n ṉ use the Equal key. To type the capital underlined N Ṉ use the Plus key
  • To type the underlined double e e̲e̲ use Right-Alt (Windows) / Option (Mac) + the e key
  • All changed numbers and punctuation can type their original value by holding down the Right-Alt or Option key. The Semicolon ; is typed Right-Alt+Semicolon (Windows) Option+Semicolon (Mac).
';this.KM=0;this.KBVER="10.0.2";this.KMBM=0x0318;this.KVKD="T_Q T_F T_W T_E_0 T_E_1 T_E_2 T_E_3 T_E T_R T_T T_Y T_U_0 T_U_1 T_U_2 T_U T_I_0 T_I_1 T_I_2 T_I T_O_0 T_O_1 T_O_2 T_O T_P T_A_0 T_A_1 T_A_2 T_A T_S T_D T_G T_H T_J T_K T_L T_COLON_0 T_COLON T_Z T_X T_C T_V T_B T_N_0 T_N T_M";this.KVKL={"tablet":{"displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"width":"105","id":"T_Q","pad":"21","sp":"8","text":"\u00B4"},{"width":"105","id":"T_W","text":"w"},{"width":"105","id":"T_E","text":"e","sk":[{"id":"T_E_0","text":"\u00E9"},{"id":"T_E_1","text":"\u0119"},{"id":"T_E_2","text":"\u0119\u0301"},{"id":"T_E_3","text":"e\u0332e\u0332"}]},{"width":"105","id":"T_R","text":"r"},{"width":"105","id":"T_T","text":"t"},{"width":"105","id":"T_Y","text":"y"},{"width":"105","id":"T_U","text":"u","sk":[{"id":"T_U_0","text":"\u00FA"},{"id":"T_U_1","text":"\u0173"},{"id":"T_U_2","text":"\u0173\u0301"}]},{"width":"105","id":"T_I","text":"\u0131","sk":[{"id":"T_I_0","text":"\u0131\u0301"},{"id":"T_I_1","text":"\u0131\u0328"},{"id":"T_I_2","text":"\u0131\u0328\u0301"}]},{"width":"105","id":"T_O","text":"o","sk":[{"id":"T_O_0","text":"\u00F3"},{"id":"T_O_1","text":"\u01EB"},{"id":"T_O_2","text":"\u01EB\u0301"}]},{"width":"105","id":"T_P","text":"\u0142"}]},{"id":"2","key":[{"width":"105","id":"T_A","pad":"21","text":"a","sk":[{"id":"T_A_0","text":"\u00E1"},{"id":"T_A_1","text":"\u0105"},{"id":"T_A_2","text":"\u0105\u0301"}]},{"width":"105","id":"T_S","text":"s"},{"width":"105","id":"T_D","text":"d"},{"width":"105","id":"T_F","sp":"8","text":"\u02DB"},{"width":"105","id":"T_G","text":"g"},{"width":"105","id":"T_H","text":"h"},{"width":"105","id":"T_J","text":"j"},{"width":"105","id":"T_K","text":"k"},{"width":"105","id":"T_L","text":"l"},{"width":"105","id":"T_COLON","text":"'","sk":[{"id":"T_COLON_0","text":"\""}]}]},{"id":"3","key":[{"nextlayer":"shift","width":"155","id":"K_SHIFT","pad":"28","sp":"1","text":"*Shift*"},{"width":"105","id":"T_Z","text":"z"},{"width":"105","id":"T_X","text":"x"},{"width":"105","id":"T_C","text":"c"},{"width":"105","id":"T_V","text":"\u0242"},{"width":"105","id":"T_B","text":"b"},{"width":"105","id":"T_N","text":"n","sk":[{"id":"T_N_0","text":"\u1E49"}]},{"width":"105","id":"T_M","text":"m"},{"width":"155","id":"K_BKSP","sp":"1","text":"*BkSp*"},{"width":"2","id":"T_new_9457","pad":"1","sp":"10"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"136","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"136","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"500","id":"K_SPACE"},{"width":"105","id":"U_002E","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_003B","text":";"},{"id":"U_003A","text":":"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_0060","text":"`"},{"id":"U_007E","text":"~"}]},{"width":"250","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"width":"105","id":"T_Q","pad":"21","sp":"8","text":"\u00B4"},{"width":"105","id":"T_W","text":"W"},{"width":"105","id":"T_E","text":"E","sk":[{"id":"T_E_0","text":"\u00C9"},{"id":"T_E_1","text":"\u0118"},{"id":"T_E_2","text":"\u0118\u0301"},{"id":"T_E_3","text":"E\u0332E\u0332"}]},{"width":"105","id":"T_R","text":"R"},{"width":"105","id":"T_T","text":"T"},{"width":"105","id":"T_Y","text":"Y"},{"width":"105","id":"T_U","text":"U","sk":[{"id":"T_U_0","text":"\u00DA"},{"id":"T_U_1","text":"\u0172"},{"id":"T_U_2","text":"\u0172\u0301"}]},{"width":"105","id":"T_I","text":"I","sk":[{"id":"T_I_0","text":"\u00CD"},{"id":"T_I_1","text":"\u012E"},{"id":"T_I_2","text":"\u012E\u0301"}]},{"width":"105","id":"T_O","text":"O","sk":[{"id":"T_O_0","text":"\u00D3"},{"id":"T_O_1","text":"\u01EA"},{"id":"T_O_2","text":"\u01EA\u0301"}]},{"width":"105","id":"T_P","text":"\u0141"}]},{"id":"2","key":[{"width":"105","id":"T_A","pad":"21","text":"A","sk":[{"id":"T_A_0","text":"\u00C1"},{"id":"T_A_1","text":"\u0104"},{"id":"T_A_2","text":"\u0104\u0301"}]},{"width":"105","id":"T_S","text":"S"},{"width":"105","id":"T_D","text":"D"},{"width":"105","id":"T_F","sp":"8","text":"\u02DB"},{"width":"105","id":"T_G","text":"G"},{"width":"105","id":"T_H","text":"H"},{"width":"105","id":"T_J","text":"J"},{"width":"105","id":"T_K","text":"K"},{"width":"105","id":"T_L","text":"L"},{"width":"105","id":"T_COLON","text":"'","sk":[{"id":"T_COLON_0","text":"\""}]}]},{"id":"3","key":[{"nextlayer":"default","width":"155","id":"K_SHIFT","pad":"28","sp":"1","text":"*Shift*"},{"width":"105","id":"T_Z","text":"Z"},{"width":"105","id":"T_X","text":"X"},{"width":"105","id":"T_C","text":"C"},{"width":"105","id":"T_V","text":"\u0241"},{"width":"105","id":"T_B","text":"B"},{"width":"105","id":"T_N","text":"N","sk":[{"id":"T_N_0","text":"\u1E48"}]},{"width":"105","id":"T_M","text":"M"},{"width":"155","id":"K_BKSP","sp":"1","text":"*BkSp*"},{"width":"2","id":"T_new_12332","pad":"1","sp":"10"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"136","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"136","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"500","id":"K_SPACE"},{"width":"105","id":"U_002E","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_003B","text":";"},{"id":"U_003A","text":":"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_0060","text":"`"},{"id":"U_007E","text":"~"}]},{"width":"250","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"U_0031","text":"1"},{"id":"U_0032","text":"2"},{"id":"U_0033","text":"3"},{"id":"U_0034","text":"4"},{"id":"U_0035","text":"5"},{"id":"U_0036","text":"6"},{"id":"U_0037","text":"7"},{"id":"U_0038","text":"8"},{"id":"U_0039","text":"9"},{"id":"U_0030","text":"0"}]},{"id":"2","key":[{"layer":"shift","id":"U_0024","pad":"50","text":"$"},{"layer":"shift","id":"U_0040","text":"@"},{"layer":"shift","id":"U_0023","text":"#"},{"layer":"shift","id":"U_0025","text":"%"},{"layer":"shift","id":"U_0026","text":"&"},{"layer":"shift","id":"U_005F","text":"_"},{"layer":"default","id":"U_003D","text":"="},{"layer":"shift","id":"U_007C","text":"|"},{"layer":"default","id":"U_005C","text":"\\"},{"width":"10","id":"T_new_122","sp":"10"}]},{"id":"3","key":[{"id":"U_005B","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"U_003C","text":"<"},{"layer":"shift","id":"U_007B","text":"{"}]},{"layer":"shift","id":"U_0028","text":"("},{"layer":"shift","id":"U_0029","text":")"},{"id":"U_005D","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"U_003E","text":">"},{"layer":"shift","id":"U_007D","text":"}"}]},{"layer":"shift","id":"U_002B","text":"+"},{"id":"U_002D","text":"-"},{"layer":"shift","id":"U_002A","text":"*"},{"id":"U_002F","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"505","id":"K_SPACE"},{"width":"100","id":"U_002E","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_003B","text":";"},{"id":"U_003A","text":":"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_0060","text":"`"},{"id":"U_007E","text":"~"}]},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.s12="aeiouAEIOU";this.s13="áéíóúÁÉÍÓÚ";this.s14=['','',''];this.s15="ąęįǫųĄĘĮǪŲ";this.s16=['','',''];this.s17=[''];this.s18=['',''];this.s21=[''];this.s22=[''];this.s23="ą́ę́ı̨́ǫ́ų́Ą́Ę́Į́Ǫ́Ų́";this.s24=['','',''];this.s25="1234567890-=[];,./`~!@#$%^&*()+{}|:\"<>?“”‹›«»'";this.s27="default";this.s28="default";this.s29="default";this.s30="default";this.s31="default";this.s32="default";this.s33="default";this.s34="default";this.s35="default";this.s36="default";this.s37="default";this.s38="default";this.s39="default";this.s40="default";this.s41="default";this.s42="default";this.s43="default";this.s44="default";this.s45="default";this.s46="default";this.s47="default";this.s48="default";this.s49="default";this.s50="default";this.s51="default";this.s52="default";this.s53="default";this.s54="default";this.s55="default";this.s56="default";this.s57="default";this.s58="default";this.s59="default";this.s60="default";this.s61="default";this.s62="default";this.s63="default";this.s64="default";this.s65="default";this.s66="default";this.s67="default";this.s68="default";this.s69="default";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16400,256)) {if(k.KFCM(2,t,['ı','̨'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ı̨́");}else if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"́");}else if(k.KFCM(1,t,['ı'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"í");}}else if(k.KKM(e,16384,256)) {if(k.KFCM(2,t,['ı','̨'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ı̨́");}else if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"́");}else if(k.KFCM(1,t,['ı'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"í");}}else if(k.KKM(e,16400,257)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"́");}else if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);}else if(k.KFCM(1,t,['ı'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ı̨");}else if(k.KFCM(1,t,['í'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ı̨́");}}else if(k.KKM(e,16384,257)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"́");}else if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);}else if(k.KFCM(1,t,['ı'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ı̨");}else if(k.KFCM(1,t,['í'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ı̨́");}}else if(k.KKM(e,16400,8)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s12,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s12,1,t);}}else if(k.KKM(e,16384,8)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s12,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s12,1,t);}}else if(k.KKM(e,16400,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"W");k.KSETS(33,this.s27,t);}}else if(k.KKM(e,16400,259)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"É");k.KSETS(33,this.s28,t);}}else if(k.KKM(e,16400,260)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ę");k.KSETS(33,this.s29,t);}}else if(k.KKM(e,16400,261)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ę́");k.KSETS(33,this.s30,t);}}else if(k.KKM(e,16400,262)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"E̲E̲");k.KSETS(33,this.s31,t);}}else if(k.KKM(e,16400,263)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"E");k.KSETS(33,this.s32,t);}}else if(k.KKM(e,16400,264)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"R");k.KSETS(33,this.s33,t);}}else if(k.KKM(e,16400,265)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"T");k.KSETS(33,this.s34,t);}}else if(k.KKM(e,16400,266)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Y");k.KSETS(33,this.s35,t);}}else if(k.KKM(e,16400,267)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ú");k.KSETS(33,this.s36,t);}}else if(k.KKM(e,16400,268)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ų");k.KSETS(33,this.s37,t);}}else if(k.KKM(e,16400,269)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ų́");k.KSETS(33,this.s38,t);}}else if(k.KKM(e,16400,270)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"U");k.KSETS(33,this.s39,t);}}else if(k.KKM(e,16400,271)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Í");k.KSETS(33,this.s40,t);}}else if(k.KKM(e,16400,272)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Į");k.KSETS(33,this.s41,t);}}else if(k.KKM(e,16400,273)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Į́");k.KSETS(33,this.s42,t);}}else if(k.KKM(e,16400,274)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"I");k.KSETS(33,this.s43,t);}}else if(k.KKM(e,16400,275)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ó");k.KSETS(33,this.s44,t);}}else if(k.KKM(e,16400,276)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ǫ");k.KSETS(33,this.s45,t);}}else if(k.KKM(e,16400,277)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ǫ́");k.KSETS(33,this.s46,t);}}else if(k.KKM(e,16400,278)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"O");k.KSETS(33,this.s47,t);}}else if(k.KKM(e,16400,279)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ł");k.KSETS(33,this.s48,t);}}else if(k.KKM(e,16400,280)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Á");k.KSETS(33,this.s49,t);}}else if(k.KKM(e,16400,281)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ą");k.KSETS(33,this.s50,t);}}else if(k.KKM(e,16400,282)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ą́");k.KSETS(33,this.s51,t);}}else if(k.KKM(e,16400,283)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"A");k.KSETS(33,this.s52,t);}}else if(k.KKM(e,16400,284)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"S");k.KSETS(33,this.s53,t);}}else if(k.KKM(e,16400,285)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"D");k.KSETS(33,this.s54,t);}}else if(k.KKM(e,16400,286)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"G");k.KSETS(33,this.s55,t);}}else if(k.KKM(e,16400,287)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"H");k.KSETS(33,this.s56,t);}}else if(k.KKM(e,16400,288)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"J");k.KSETS(33,this.s57,t);}}else if(k.KKM(e,16400,289)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"K");k.KSETS(33,this.s58,t);}}else if(k.KKM(e,16400,290)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"L");k.KSETS(33,this.s59,t);}}else if(k.KKM(e,16400,291)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\"");k.KSETS(33,this.s60,t);}}else if(k.KKM(e,16400,292)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"'");k.KSETS(33,this.s61,t);}}else if(k.KKM(e,16400,293)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Z");k.KSETS(33,this.s62,t);}}else if(k.KKM(e,16400,294)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"X");k.KSETS(33,this.s63,t);}}else if(k.KKM(e,16400,295)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"C");k.KSETS(33,this.s64,t);}}else if(k.KKM(e,16400,296)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ɂ");k.KSETS(33,this.s65,t);}}else if(k.KKM(e,16400,297)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"B");k.KSETS(33,this.s66,t);}}else if(k.KKM(e,16400,298)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ṉ");k.KSETS(33,this.s67,t);}}else if(k.KKM(e,16400,299)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"N");k.KSETS(33,this.s68,t);}}else if(k.KKM(e,16400,300)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"M");k.KSETS(33,this.s69,t);}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"w");}}else if(k.KKM(e,16384,259)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"é");}}else if(k.KKM(e,16384,260)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ę");}}else if(k.KKM(e,16384,261)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ę́");}}else if(k.KKM(e,16384,262)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"e̲e̲");}}else if(k.KKM(e,16384,263)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"e");}}else if(k.KKM(e,16384,264)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"r");}}else if(k.KKM(e,16384,265)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"t");}}else if(k.KKM(e,16384,266)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"y");}}else if(k.KKM(e,16384,267)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ú");}}else if(k.KKM(e,16384,268)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ų");}}else if(k.KKM(e,16384,269)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ų́");}}else if(k.KKM(e,16384,270)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"u");}}else if(k.KKM(e,16384,271)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"í");}}else if(k.KKM(e,16384,272)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ı̨");}}else if(k.KKM(e,16384,273)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ı̨́");}}else if(k.KKM(e,16384,274)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ı");}}else if(k.KKM(e,16384,275)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ó");}}else if(k.KKM(e,16384,276)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ǫ");}}else if(k.KKM(e,16384,277)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ǫ́");}}else if(k.KKM(e,16384,278)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"o");}}else if(k.KKM(e,16384,279)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ł");}}else if(k.KKM(e,16384,280)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"á");}}else if(k.KKM(e,16384,281)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ą");}}else if(k.KKM(e,16384,282)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ą́");}}else if(k.KKM(e,16384,283)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"a");}}else if(k.KKM(e,16384,284)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"s");}}else if(k.KKM(e,16384,285)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"d");}}else if(k.KKM(e,16384,286)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"g");}}else if(k.KKM(e,16384,287)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"h");}}else if(k.KKM(e,16384,288)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"j");}}else if(k.KKM(e,16384,289)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"k");}}else if(k.KKM(e,16384,290)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"l");}}else if(k.KKM(e,16384,291)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\"");}}else if(k.KKM(e,16384,292)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"'");}}else if(k.KKM(e,16384,293)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"z");}}else if(k.KKM(e,16384,294)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"x");}}else if(k.KKM(e,16384,295)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"c");}}else if(k.KKM(e,16384,296)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ɂ");}}else if(k.KKM(e,16384,297)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"b");}}else if(k.KKM(e,16384,298)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ṉ");}}else if(k.KKM(e,16384,299)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"n");}}else if(k.KKM(e,16384,300)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"m");}}else if(k.KKM(e,16392,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"`");}}else if(k.KKM(e,16408,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"~");}}else if(k.KKM(e,16904,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"=");}}else if(k.KKM(e,16664,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"=");}}else if(k.KKM(e,16648,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"+");}}else if(k.KKM(e,16920,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"+");}}else if(k.KKM(e,16664,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,";");}}else if(k.KKM(e,16904,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,";");}}if(m) {}else if(k.KKM(e,16648,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,":");}}else if(k.KKM(e,16920,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,":");}}else if(k.KKM(e,16664,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"/");}}else if(k.KKM(e,16904,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"/");}}else if(k.KKM(e,16648,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"?");}}else if(k.KKM(e,16920,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"?");}}else if(k.KKM(e,16392,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\\");}}else if(k.KKM(e,16408,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"|");}}else if(k.KKM(e,16392,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"[");}}else if(k.KKM(e,16408,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"{");}}else if(k.KKM(e,16392,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"]");}}else if(k.KKM(e,16408,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"}");}}else if(k.KKM(e,16408,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"›");}}else if(k.KKM(e,16408,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‹");}}else if(k.KKM(e,16392,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"»");}}else if(k.KKM(e,16392,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"«");}}else if(k.KKM(e,16664,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"i");}}else if(k.KKM(e,16904,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"i");}}else if(k.KKM(e,16648,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"I");}}else if(k.KKM(e,16920,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"I");}}else if(k.KKM(e,16904,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"e̲e̲");}}else if(k.KKM(e,16664,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"e̲e̲");}}else if(k.KKM(e,16920,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"E̲E̲");}}else if(k.KKM(e,16648,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"E̲E̲");}}else if(k.KKM(e,16400,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}}else if(k.KKM(e,16400,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"#");}}else if(k.KKM(e,16400,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"$");}}else if(k.KKM(e,16400,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"%");}}else if(k.KKM(e,16400,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"&");}}else if(k.KKM(e,16384,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"'");}}else if(k.KKM(e,16400,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"(");}}else if(k.KKM(e,16400,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,")");}}else if(k.KKM(e,16400,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"*");}}else if(k.KKM(e,16656,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ṉ");}}else if(k.KKM(e,16912,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ṉ");}}else if(k.KKM(e,16896,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ɂ");}}else if(k.KKM(e,16640,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʔ");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"0");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"1");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"2");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"3");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"4");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"5");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"6");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"7");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"8");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"9");}}else if(k.KKM(e,16656,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ł");}}else if(k.KKM(e,16912,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ł");}}else if(k.KKM(e,16896,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ł");}}else if(k.KKM(e,16640,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ł");}}else if(k.KKM(e,16896,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ṉ");}}else if(k.KKM(e,16640,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ṉ");}}else if(k.KKM(e,16656,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ɂ");}}else if(k.KKM(e,16912,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʔ");}}else if(k.KKM(e,16400,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"@");}}else if(k.KKM(e,16640,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"I");}}else if(k.KKM(e,16912,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"I");}}else if(k.KKM(e,16384,219)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"́");}else if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);}else if(k.KFCM(1,t,['ı'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ı̨");}else if(k.KFCM(1,t,['í'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ı̨́");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KB(t);}else if(k.KFCM(1,t,['̨'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"̨");k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s25}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s25,1,t);k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s23}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s23,1,t);k.KB(t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"̨");}}else if(k.KKM(e,16384,221)) {if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"́");}else if(k.KFCM(1,t,['ı'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ı̨́");}else if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KB(t);}else if(k.KFCM(1,t,['́'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"́");k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KB(t);}else if(k.KFCM(1,t,['̨'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"̨");k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s25}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s25,1,t);k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s23}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s23,1,t);k.KB(t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"̨́");}}else if(k.KKM(e,16400,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"^");}}else if(k.KKM(e,16384,192)) {if(k.KFCM(2,t,['ı','̨'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ı̨́");}else if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"́");}else if(k.KFCM(1,t,['ı'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"í");}else if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KB(t);}else if(k.KFCM(1,t,['́'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"́");k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s25}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s25,1,t);k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s23}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s23,1,t);k.KB(t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"́");}}else if(k.KKM(e,16896,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ı");}}else if(k.KKM(e,16656,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ı");}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"{");}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"}");}}else if(k.KKM(e,16400,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"~");}}return r;};} \ No newline at end of file diff --git a/keyboard/fv_kwakwala_liqwala/9.2.5/fv_kwakwala_liqwala-9.2.5.js b/keyboard/fv_kwakwala_liqwala/9.2.5/fv_kwakwala_liqwala-9.2.5.js new file mode 100644 index 000000000..8d29d8ea4 --- /dev/null +++ b/keyboard/fv_kwakwala_liqwala/9.2.5/fv_kwakwala_liqwala-9.2.5.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_fv_kwakwala_liqwala());}function Keyboard_fv_kwakwala_liqwala(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_fv_kwakwala_liqwala";this.KN="Kʷak̓ʷala";this.KMINVER="10.0";this.KV={F:' 1em "Aboriginal Sans"',K102:0};this.KV.KLS={"shift": ["~","!","ᵂ","Ə","X̌","Ǧ","","","","Ɫ","Ē","_","+","","","","Q","W","E","R","T","Y","U","I","O","P","“","”","|","","","","A","S","D","F","G","H","J","K","L",":","\"","","","","","","","Z","X","C","V","B","N","M","<",">","?","","","","","",""],"default": ["`","!","ʷ","ə","x̌","ǧ","ᶻ","λ","ƛ","ɫ","ē","-","=","","","","q","w","e","r","t","y","u","i","o","p","‘","’","\\","","","","a","s","d","f","g","h","j","k","l",";","’","","","","","","","z","x","c","v","b","n","m",",",".","ʔ","","","","","",""],"rightalt-shift": ["","!","@","#","$","%","^","&","*","(",")","‹","›","","","","","","","","","","","","","","{","}","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"rightalt": ["","1","2","3","4","5","6","7","8","9","0","«","»","","","","","","","","","","","","","","[","]","","","","","","","","","","","","","","","'","","","","","","","","","","","","","","","","/","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=1;this.KH=' Kʷak̓ʷala
  • To type the apostrophe accent use the Apostrophe key \' — k̓ is typed k then Apostrophe \'
  • The original values of the punctuation keys can be typed by holding down the Right-Alt or Option key. The Semicolon ; is typed Right-Alt+Semicolon (Windows) Option+Semicolon (Mac).
';this.KM=0;this.KBVER="9.2.5";this.KMBM=0x0318;this.KVKD="T_V T_Q_0 T_Q T_W_0 T_W T_E_0 T_E T_R T_T_0 T_T T_Y_0 T_Y T_U T_I T_O T_P_0 T_P T_A T_S T_D_0 T_D T_F T_G_0 T_G T_H T_J T_K_0 T_K T_L_0 T_L T_COLON T_Z_0 T_Z T_X_0 T_X T_C_0 T_C T_B T_N T_M_0 T_M T_COMMA_0 T_COMMA";this.KVKL={"tablet":{"displayUnderlying":false,"layer":[{"id":"shift","row":[{"id":"1","key":[{"width":"100","id":"T_Q","pad":"45","text":"Q","sk":[{"id":"T_Q_0","text":"Q\u0313"}]},{"width":"100","id":"T_W","text":"W","sk":[{"id":"T_W_0","text":"W\u0313"}]},{"width":"100","id":"T_E","text":"E","sk":[{"id":"T_E_0","text":"E\u0304"}]},{"width":"100","id":"T_R","text":"\u018F"},{"width":"100","id":"T_T","text":"T","sk":[{"id":"T_T_0","text":"T\u0313"}]},{"width":"100","id":"T_Y","text":"Y","sk":[{"id":"T_Y_0","text":"Y\u0313"}]},{"width":"100","id":"T_U","text":"U"},{"width":"100","id":"T_I","text":"I"},{"width":"100","id":"T_O","text":"O"},{"width":"100","id":"T_P","text":"P","sk":[{"id":"T_P_0","text":"P\u0313"}]},{"width":"20","id":"T_new_12265","pad":"1","sp":"10"}]},{"id":"2","key":[{"width":"100","id":"T_A","pad":"45","text":"A"},{"width":"100","id":"T_S","text":"S"},{"width":"100","id":"T_D","text":"D","sk":[{"id":"T_D_0","text":"D\u1DBB"}]},{"width":"100","id":"T_F","text":"\u0294"},{"width":"100","id":"T_G","text":"G","sk":[{"id":"T_G_0","text":"G\u030C"}]},{"width":"100","id":"T_H","text":"H"},{"width":"100","id":"T_J","text":"\u1D42"},{"width":"100","id":"T_K","text":"K","sk":[{"id":"T_K_0","text":"K\u0313"}]},{"width":"100","id":"T_L","text":"L","sk":[{"id":"T_L_0","text":"L\u0313"}]},{"width":"100","id":"T_COLON","text":"\u0141"},{"width":"20","id":"T_new_12226","pad":"1","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","width":"130","id":"K_SHIFT","pad":"15","sp":"1","text":"*Shift*"},{"width":"100","id":"T_Z","text":"\u019B","sk":[{"id":"T_Z_0","text":"\u019B\u0313"}]},{"width":"100","id":"T_X","text":"X","sk":[{"id":"T_X_0","text":"X\u030C"}]},{"width":"100","id":"T_C","text":"C","sk":[{"id":"T_C_0","text":"C\u0313"}]},{"width":"100","id":"T_V","sp":"8","text":"\u02BC"},{"width":"100","id":"T_B","text":"\u03BB"},{"width":"100","id":"T_N","text":"B"},{"width":"100","id":"T_M","text":"N","sk":[{"id":"T_M_0","text":"N\u0313"}]},{"width":"100","id":"T_COMMA","text":"M","sk":[{"id":"T_COMMA_0","text":"M\u0313"}]},{"width":"130","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"136","id":"K_NUMLOCK","pad":"35","sp":"1","text":"*123*"},{"width":"136","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"500","id":"K_SPACE"},{"width":"105","id":"U_002E","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_003B","text":";"},{"id":"U_003A","text":":"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_0060","text":"`"},{"id":"U_007E","text":"~"}]},{"width":"220","id":"K_ENTER","sp":"1","text":"*Enter*"},{"width":"5","id":"T_new_12629","pad":"1","sp":"10"}]}]},{"id":"default","row":[{"id":"1","key":[{"width":"100","id":"T_Q","pad":"45","text":"q","sk":[{"id":"T_Q_0","text":"q\u0313"}]},{"width":"100","id":"T_W","text":"w","sk":[{"id":"T_W_0","text":"w\u0313"}]},{"width":"100","id":"T_E","text":"e","sk":[{"id":"T_E_0","text":"e\u0304"}]},{"width":"100","id":"T_R","text":"\u0259"},{"width":"100","id":"T_T","text":"t","sk":[{"id":"T_T_0","text":"t\u0313"}]},{"width":"100","id":"T_Y","text":"y","sk":[{"id":"T_Y_0","text":"y\u0313"}]},{"width":"100","id":"T_U","text":"u"},{"width":"100","id":"T_I","text":"i"},{"width":"100","id":"T_O","text":"o"},{"width":"100","id":"T_P","text":"p","sk":[{"id":"T_P_0","text":"p\u0313"}]},{"width":"20","id":"T_new_5569","pad":"1","sp":"10"}]},{"id":"2","key":[{"width":"100","id":"T_A","pad":"45","text":"a"},{"width":"100","id":"T_S","text":"s"},{"width":"100","id":"T_D","text":"d","sk":[{"id":"T_D_0","text":"d\u1DBB"}]},{"width":"100","id":"T_F","text":"\u0294"},{"width":"100","id":"T_G","text":"g","sk":[{"id":"T_G_0","text":"g\u030C"}]},{"width":"100","id":"T_H","text":"h"},{"width":"100","id":"T_J","text":"\u02B7"},{"width":"100","id":"T_K","text":"k","sk":[{"id":"T_K_0","text":"k\u0313"}]},{"width":"100","id":"T_L","text":"l","sk":[{"id":"T_L_0","text":"l\u0313"}]},{"width":"100","id":"T_COLON","text":"\u0142"},{"width":"20","id":"T_new_5792","pad":"1","sp":"10"}]},{"id":"3","key":[{"nextlayer":"shift","width":"130","id":"K_SHIFT","pad":"15","sp":"1","text":"*Shift*"},{"width":"100","id":"T_Z","text":"\u019B","sk":[{"id":"T_Z_0","text":"\u019B\u0313"}]},{"width":"100","id":"T_X","text":"x","sk":[{"id":"T_X_0","text":"x\u030C"}]},{"width":"100","id":"T_C","text":"c","sk":[{"id":"T_C_0","text":"c\u0313"}]},{"width":"100","id":"T_V","sp":"8","text":"\u02BC"},{"width":"100","id":"T_B","text":"\u03BB"},{"width":"100","id":"T_N","text":"b"},{"width":"100","id":"T_M","text":"n","sk":[{"id":"T_M_0","text":"n\u0313"}]},{"width":"100","id":"T_COMMA","text":"m","sk":[{"id":"T_COMMA_0","text":"m\u0313"}]},{"width":"130","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"136","id":"K_NUMLOCK","pad":"35","sp":"1","text":"*123*"},{"width":"136","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"500","id":"K_SPACE"},{"width":"105","id":"U_002E","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_003B","text":";"},{"id":"U_003A","text":":"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_0060","text":"`"},{"id":"U_007E","text":"~"}]},{"width":"220","id":"K_ENTER","sp":"1","text":"*Enter*"},{"width":"10","id":"T_new_6083","pad":"1","sp":"10"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"U_0031","text":"1"},{"id":"U_0032","text":"2"},{"id":"U_0033","text":"3"},{"id":"U_0034","text":"4"},{"id":"U_0035","text":"5"},{"id":"U_0036","text":"6"},{"id":"U_0037","text":"7"},{"id":"U_0038","text":"8"},{"id":"U_0039","text":"9"},{"id":"U_0030","text":"0"}]},{"id":"2","key":[{"layer":"shift","id":"U_0024","pad":"50","text":"$"},{"layer":"shift","id":"U_0040","text":"@"},{"layer":"shift","id":"U_0023","text":"#"},{"layer":"shift","id":"U_0025","text":"%"},{"layer":"shift","id":"U_0026","text":"&"},{"layer":"shift","id":"U_005F","text":"_"},{"layer":"default","id":"U_003D","text":"="},{"layer":"shift","id":"U_007C","text":"|"},{"layer":"default","id":"U_005C","text":"\\"},{"width":"10","id":"T_new_122","sp":"10"}]},{"id":"3","key":[{"id":"U_005B","pad":"110","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"layer":"shift","id":"U_003C","text":"<"},{"layer":"shift","id":"U_007B","text":"{"}]},{"layer":"shift","id":"U_0028","text":"("},{"layer":"shift","id":"U_0029","text":")"},{"id":"U_005D","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"layer":"shift","id":"U_003E","text":">"},{"layer":"shift","id":"U_007D","text":"}"}]},{"layer":"shift","id":"U_002B","text":"+"},{"id":"U_002D","text":"-"},{"layer":"shift","id":"U_002A","text":"*"},{"id":"U_002F","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"505","id":"K_SPACE"},{"width":"100","id":"U_002E","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_003B","text":";"},{"id":"U_003A","text":":"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_0060","text":"`"},{"id":"U_007E","text":"~"}]},{"width":"150","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.s13=['',''];this.s14="cklmnpqtwyCKLMNPQTWYƛ̓";this.s15="̓";this.s16=[''];this.s17="1234567890-=[]\\;,./`~!@#$%^&*()_+{}|:\"<>?‘’“”‹›«»'";this.s20="default";this.s21="default";this.s22="default";this.s23="default";this.s24="default";this.s25="default";this.s26="default";this.s27="default";this.s28="default";this.s29="default";this.s30="default";this.s31="default";this.s32="default";this.s33="default";this.s34="default";this.s35="default";this.s36="default";this.s37="default";this.s38="default";this.s39="default";this.s40="default";this.s41="default";this.s42="default";this.s43="default";this.s44="default";this.s45="default";this.s46="default";this.s47="default";this.s48="default";this.s49="default";this.s50="default";this.s51="default";this.s52="default";this.s53="default";this.s54="default";this.s55="default";this.s56="default";this.s57="default";this.s58="default";this.s59="default";this.s60="default";this.s61="default";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16400,256)) {if(k.KFCM(1,t,[{t:'a',a:this.s14}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s14,1,t);k.KO(-1,t,"̓");}}else if(k.KKM(e,16384,256)) {if(k.KFCM(1,t,[{t:'a',a:this.s14}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s14,1,t);k.KO(-1,t,"̓");}}else if(k.KKM(e,16400,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Q̓");k.KSETS(33,this.s20,t);}}else if(k.KKM(e,16400,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Q");k.KSETS(33,this.s21,t);}}else if(k.KKM(e,16400,259)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"W̓");k.KSETS(33,this.s22,t);}}else if(k.KKM(e,16400,260)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"W");k.KSETS(33,this.s23,t);}}else if(k.KKM(e,16400,261)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ē");k.KSETS(33,this.s24,t);}}else if(k.KKM(e,16400,262)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"E");k.KSETS(33,this.s25,t);}}else if(k.KKM(e,16400,263)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ə");k.KSETS(33,this.s26,t);}}else if(k.KKM(e,16400,264)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"T̓");k.KSETS(33,this.s27,t);}}else if(k.KKM(e,16400,265)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"T");k.KSETS(33,this.s28,t);}}else if(k.KKM(e,16400,266)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Y̓");k.KSETS(33,this.s29,t);}}else if(k.KKM(e,16400,267)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Y");k.KSETS(33,this.s30,t);}}else if(k.KKM(e,16400,268)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"U");k.KSETS(33,this.s31,t);}}else if(k.KKM(e,16400,269)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"I");k.KSETS(33,this.s32,t);}}else if(k.KKM(e,16400,270)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"O");k.KSETS(33,this.s33,t);}}else if(k.KKM(e,16400,271)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"P̓");k.KSETS(33,this.s34,t);}}else if(k.KKM(e,16400,272)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"P");k.KSETS(33,this.s35,t);}}else if(k.KKM(e,16400,273)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"A");k.KSETS(33,this.s36,t);}}else if(k.KKM(e,16400,274)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"S");k.KSETS(33,this.s37,t);}}else if(k.KKM(e,16400,275)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Dᶻ");k.KSETS(33,this.s38,t);}}else if(k.KKM(e,16400,276)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"D");k.KSETS(33,this.s39,t);}}else if(k.KKM(e,16400,277)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʔ");k.KSETS(33,this.s40,t);}}else if(k.KKM(e,16400,278)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ǧ");k.KSETS(33,this.s41,t);}}else if(k.KKM(e,16400,279)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"G");k.KSETS(33,this.s42,t);}}else if(k.KKM(e,16400,280)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"H");k.KSETS(33,this.s43,t);}}else if(k.KKM(e,16400,281)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᵂ");k.KSETS(33,this.s44,t);}}else if(k.KKM(e,16400,282)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"K̓");k.KSETS(33,this.s45,t);}}else if(k.KKM(e,16400,283)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"K");k.KSETS(33,this.s46,t);}}else if(k.KKM(e,16400,284)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"L̓");k.KSETS(33,this.s47,t);}}else if(k.KKM(e,16400,285)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"L");k.KSETS(33,this.s48,t);}}else if(k.KKM(e,16400,286)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ł");k.KSETS(33,this.s49,t);}}else if(k.KKM(e,16400,287)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ƛ̓");k.KSETS(33,this.s50,t);}}else if(k.KKM(e,16400,288)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ƛ");k.KSETS(33,this.s51,t);}}else if(k.KKM(e,16400,289)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"X̌");k.KSETS(33,this.s52,t);}}else if(k.KKM(e,16400,290)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"X");k.KSETS(33,this.s53,t);}}else if(k.KKM(e,16400,291)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"C̓");k.KSETS(33,this.s54,t);}}else if(k.KKM(e,16400,292)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"C");k.KSETS(33,this.s55,t);}}else if(k.KKM(e,16400,293)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"λ");k.KSETS(33,this.s56,t);}}else if(k.KKM(e,16400,294)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"B");k.KSETS(33,this.s57,t);}}else if(k.KKM(e,16400,295)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"N̓");k.KSETS(33,this.s58,t);}}else if(k.KKM(e,16400,296)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"N");k.KSETS(33,this.s59,t);}}else if(k.KKM(e,16400,297)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"M̓");k.KSETS(33,this.s60,t);}}else if(k.KKM(e,16400,298)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"M");k.KSETS(33,this.s61,t);}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"q̓");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"q");}}else if(k.KKM(e,16384,259)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"w̓");}}else if(k.KKM(e,16384,260)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"w");}}else if(k.KKM(e,16384,261)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ē");}}else if(k.KKM(e,16384,262)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"e");}}else if(k.KKM(e,16384,263)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ə");}}else if(k.KKM(e,16384,264)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"t̓");}}else if(k.KKM(e,16384,265)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"t");}}else if(k.KKM(e,16384,266)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"y̓");}}else if(k.KKM(e,16384,267)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"y");}}else if(k.KKM(e,16384,268)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"u");}}else if(k.KKM(e,16384,269)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"i");}}else if(k.KKM(e,16384,270)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"o");}}else if(k.KKM(e,16384,271)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"p̓");}}else if(k.KKM(e,16384,272)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"p");}}else if(k.KKM(e,16384,273)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"a");}}else if(k.KKM(e,16384,274)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"s");}}else if(k.KKM(e,16384,275)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"dᶻ");}}else if(k.KKM(e,16384,276)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"d");}}else if(k.KKM(e,16384,277)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʔ");}}else if(k.KKM(e,16384,278)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ǧ");}}else if(k.KKM(e,16384,279)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"g");}}else if(k.KKM(e,16384,280)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"h");}}else if(k.KKM(e,16384,281)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʷ");}}else if(k.KKM(e,16384,282)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"k̓");}}else if(k.KKM(e,16384,283)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"k");}}else if(k.KKM(e,16384,284)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"l̓");}}else if(k.KKM(e,16384,285)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"l");}}else if(k.KKM(e,16384,286)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ł");}}else if(k.KKM(e,16384,287)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ƛ̓");}}else if(k.KKM(e,16384,288)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ƛ");}}else if(k.KKM(e,16384,289)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"x̌");}}else if(k.KKM(e,16384,290)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"x");}}else if(k.KKM(e,16384,291)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"c̓");}}else if(k.KKM(e,16384,292)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"c");}}else if(k.KKM(e,16384,293)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"λ");}}else if(k.KKM(e,16384,294)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"b");}}else if(k.KKM(e,16384,295)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"n̓");}}else if(k.KKM(e,16384,296)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"n");}}else if(k.KKM(e,16384,297)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"m̓");}}else if(k.KKM(e,16384,298)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"m");}}else if(k.KKM(e,16408,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"}");}}else if(k.KKM(e,16408,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"{");}}else if(k.KKM(e,16392,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"[");}}else if(k.KKM(e,16392,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"]");}}else if(k.KKM(e,16408,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"›");}}else if(k.KKM(e,16408,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‹");}}else if(k.KKM(e,16392,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"»");}}else if(k.KKM(e,16392,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"«");}}else if(k.KKM(e,16920,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,")");}}else if(k.KKM(e,16920,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"(");}}else if(k.KKM(e,16920,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"*");}}else if(k.KKM(e,16920,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"&");}}else if(k.KKM(e,16920,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"^");}}else if(k.KKM(e,16920,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"%");}}if(m) {}else if(k.KKM(e,16920,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"$");}}else if(k.KKM(e,16920,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"#");}}else if(k.KKM(e,16920,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"@");}}else if(k.KKM(e,16920,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}}else if(k.KKM(e,16904,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"0");}}else if(k.KKM(e,16904,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"9");}}else if(k.KKM(e,16904,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"8");}}else if(k.KKM(e,16904,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"7");}}else if(k.KKM(e,16904,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"6");}}else if(k.KKM(e,16904,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"5");}}else if(k.KKM(e,16904,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"4");}}else if(k.KKM(e,16904,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"3");}}else if(k.KKM(e,16904,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"2");}}else if(k.KKM(e,16904,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"1");}}else if(k.KKM(e,16392,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"'");}}else if(k.KKM(e,16392,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"/");}}else if(k.KKM(e,16912,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}}else if(k.KKM(e,16656,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}}else if(k.KKM(e,16912,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ə");}}else if(k.KKM(e,16656,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ə");}}else if(k.KKM(e,16912,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"X̌");}}else if(k.KKM(e,16656,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"x̌");}}else if(k.KKM(e,16912,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ǧ");}}else if(k.KKM(e,16656,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ǧ");}}else if(k.KKM(e,16912,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"");}}else if(k.KKM(e,16656,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"λ");}}else if(k.KKM(e,16384,222)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KB(t);}else if(k.KFCM(1,t,[{t:'a',a:this.s17}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s17,1,t);k.KB(t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"̓");}}else if(k.KKM(e,16912,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ɫ");}}else if(k.KKM(e,16656,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ɫ");}}else if(k.KKM(e,16912,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ē");}}else if(k.KKM(e,16656,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ē");}}else if(k.KKM(e,16912,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"");}}else if(k.KKM(e,16656,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ƛ");}}else if(k.KKM(e,16384,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʔ");}}else if(k.KKM(e,16640,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ē");}}else if(k.KKM(e,16896,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ē");}}else if(k.KKM(e,16640,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}}else if(k.KKM(e,16896,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}}else if(k.KKM(e,16640,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᵂ");}}else if(k.KKM(e,16896,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʷ");}}else if(k.KKM(e,16640,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ə");}}else if(k.KKM(e,16896,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ə");}}else if(k.KKM(e,16640,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"X̌");}}else if(k.KKM(e,16896,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"x̌");}}else if(k.KKM(e,16640,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ǧ");}}else if(k.KKM(e,16896,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ǧ");}}else if(k.KKM(e,16640,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᶻ");}}else if(k.KKM(e,16896,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᶻ");}}else if(k.KKM(e,16640,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"");}}else if(k.KKM(e,16896,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"λ");}}else if(k.KKM(e,16640,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"");}}else if(k.KKM(e,16896,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ƛ");}}else if(k.KKM(e,16640,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ɫ");}}else if(k.KKM(e,16896,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ɫ");}}else if(k.KKM(e,16912,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᵂ");}}else if(k.KKM(e,16656,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ʷ");}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‘");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"’");}}else if(k.KKM(e,16912,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᶻ");}}else if(k.KKM(e,16656,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᶻ");}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"“");}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"”");}}if(!m&&k.KIK(e)) {r=1;k.KDC(-1,t);r=this.g1(t,e);m=2;}return r;};this.g1=function(t,e) {var k=KeymanWeb,r=0,m=0;return r;};} \ No newline at end of file diff --git a/keyboard/gff_tigrinya_ethiopia/2.0.3/gff_tigrinya_ethiopia-2.0.3.js b/keyboard/gff_tigrinya_ethiopia/2.0.3/gff_tigrinya_ethiopia-2.0.3.js new file mode 100644 index 000000000..d4845bc9f --- /dev/null +++ b/keyboard/gff_tigrinya_ethiopia/2.0.3/gff_tigrinya_ethiopia-2.0.3.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_gff_tigrinya_ethiopia());}function Keyboard_gff_tigrinya_ethiopia(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_gff_tigrinya_ethiopia";this.KN="ትግርኛ (Tigrinya)";this.KMINVER="15.0";this.KV={F:' 1em "Abyssinica SIL"',K102:0};this.KV.KLS={"shift": ["~","!","@","#","$","%","^","&","*","(",")","፟","+","","","","ቕ","ው","ዕ","ር","ጥ","ይ","ዑ","ዒ","ዖ","ጵ","{","}","|","","","","ዐ","ጽፅ","ድ","ፍ","ግ","ሕ","ጅ","ኽ","ል","፡","\"","","","","","","","ዥ","ሽ","ጭ","ቭ","ብ","ኝ","ም","‹","›","?","","","","","",""],"default": ["`","1","2","3","4","5","6","7","8","9","0","-","=","","","","ቅ","ው","እ","ር","ት","ይ","ኡ","ኢ","ኦ","ፕ","[","]","\\","","","","ኣ","ስሥ","ድ","ፍ","ግ","ህኅ","ጅ","ክ","ል","፤","'","","","","","","","ዝ","ሽ","ች","ቭ","ብ","ን","ም","፣፥","።","/","","","","","",""],"ctrl": ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","◌፞","","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=1;this.KH='';this.KM=0;this.KBVER="2.0.3";this.KMBM=0x0010;this.KS=1;this.KVKD="T_ግዕዝ T_ኃምስ T_ካዕብ T_ሣልስ T_ራብዕ T_ሳብዕ T_WWA T_ዘመደ_ግዕዝ T_ዘመደ_ካዕብ T_ዘመደ_ሣልስ T_ዘመደ_ራብዕ T_ዘመደ_ኃምስ U_135E U_135F U_135D T_THOUSAND T_BACK";this.KVKL={"phone":{"font":"Abyssinica SIL","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12A0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12A1"},{"id":"T_\u1223\u120D\u1235","text":"\u12A2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12A3"},{"id":"T_\u1283\u121D\u1235","text":"\u12A4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12A6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1200-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1200"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1201"},{"id":"T_\u1223\u120D\u1235","text":"\u1202"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1203","hint":"\u128B","sk":[{"id":"T_WWA","text":"\u128B"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1204"},{"id":"T_\u1233\u1265\u12D5","text":"\u1206"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1208-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1208"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1209"},{"id":"T_\u1223\u120D\u1235","text":"\u120A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u120B","hint":"\u120F","sk":[{"id":"T_WWA","text":"\u120F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u120C"},{"id":"T_\u1233\u1265\u12D5","text":"\u120E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1210-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1210"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1211"},{"id":"T_\u1223\u120D\u1235","text":"\u1212"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1213","hint":"\u1217","sk":[{"id":"T_WWA","text":"\u1217"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1214"},{"id":"T_\u1233\u1265\u12D5","text":"\u1216"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1218-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1218"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1219"},{"id":"T_\u1223\u120D\u1235","text":"\u121A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u121B","hint":"\u121F","sk":[{"id":"T_WWA","text":"\u121F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u121C"},{"id":"T_\u1233\u1265\u12D5","text":"\u121E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1220-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1220"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1221"},{"id":"T_\u1223\u120D\u1235","text":"\u1222"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1223","hint":"\u1227","sk":[{"id":"T_WWA","text":"\u1227"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1224"},{"id":"T_\u1233\u1265\u12D5","text":"\u1226"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1228-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1228"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1229"},{"id":"T_\u1223\u120D\u1235","text":"\u122A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u122B","hint":"\u122F","sk":[{"id":"T_WWA","text":"\u122F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u122C"},{"id":"T_\u1233\u1265\u12D5","text":"\u122E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1230-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1230"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1231"},{"id":"T_\u1223\u120D\u1235","text":"\u1232"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1233","hint":"\u1237","sk":[{"id":"T_WWA","text":"\u1237"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1234"},{"id":"T_\u1233\u1265\u12D5","text":"\u1236"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1238-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1238"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1239"},{"id":"T_\u1223\u120D\u1235","text":"\u123A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u123B","hint":"\u123F","sk":[{"id":"T_WWA","text":"\u123F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u123C"},{"id":"T_\u1233\u1265\u12D5","text":"\u123E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1240-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1240"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1241"},{"id":"T_\u1223\u120D\u1235","text":"\u1242"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u1248-layer","id":"T_\u122B\u1265\u12D5","text":"\u1243","hint":"\u124B"},{"id":"T_\u1283\u121D\u1235","text":"\u1244"},{"id":"T_\u1233\u1265\u12D5","text":"\u1246"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1248-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1248"},{"nextlayer":"\u1240-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u124A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u124B"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u124C"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u124D"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1250-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1250"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1251"},{"id":"T_\u1223\u120D\u1235","text":"\u1252"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u1258-layer","id":"T_\u122B\u1265\u12D5","text":"\u1253","hint":"\u125B"},{"id":"T_\u1283\u121D\u1235","text":"\u1254"},{"id":"T_\u1233\u1265\u12D5","text":"\u1256"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1258-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1258"},{"nextlayer":"\u1250-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u125A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u125B"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u125C"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u125D"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1260-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1260"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1261"},{"id":"T_\u1223\u120D\u1235","text":"\u1262"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1263","hint":"\u1267","sk":[{"id":"T_WWA","text":"\u1267"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1264"},{"id":"T_\u1233\u1265\u12D5","text":"\u1266"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1268-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1268"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1269"},{"id":"T_\u1223\u120D\u1235","text":"\u126A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u126B","hint":"\u126F","sk":[{"id":"T_WWA","text":"\u126F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u126C"},{"id":"T_\u1233\u1265\u12D5","text":"\u126E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1270-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1270"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1271"},{"id":"T_\u1223\u120D\u1235","text":"\u1272"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1273","hint":"\u1277","sk":[{"id":"T_WWA","text":"\u1277"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1274"},{"id":"T_\u1233\u1265\u12D5","text":"\u1276"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1278-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1278"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1279"},{"id":"T_\u1223\u120D\u1235","text":"\u127A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u127B","hint":"\u127F","sk":[{"id":"T_WWA","text":"\u127F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u127C"},{"id":"T_\u1233\u1265\u12D5","text":"\u127E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1280-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1280"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1281"},{"id":"T_\u1223\u120D\u1235","text":"\u1282"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u1288-layer","id":"T_\u122B\u1265\u12D5","text":"\u1283","hint":"\u128B"},{"id":"T_\u1283\u121D\u1235","text":"\u1284"},{"id":"T_\u1233\u1265\u12D5","text":"\u1286"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1288-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1288"},{"nextlayer":"\u1280-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u128A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u128B"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u128C"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u128D"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1290-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1290"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1291"},{"id":"T_\u1223\u120D\u1235","text":"\u1292"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1293","hint":"\u1297","sk":[{"id":"T_WWA","text":"\u1297"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1294"},{"id":"T_\u1233\u1265\u12D5","text":"\u1296"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1298-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"default","id":"T_\u130D\u12D5\u12DD","text":"\u1298"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1299"},{"id":"T_\u1223\u120D\u1235","text":"\u129A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u129B","hint":"\u129F","sk":[{"id":"T_WWA","text":"\u129F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u129C"},{"id":"T_\u1233\u1265\u12D5","text":"\u129E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12A0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12A0","hint":"\u12A7","sk":[{"id":"T_WWA","text":"\u12A7"}]},{"id":"T_\u12AB\u12D5\u1265","text":"\u12A1"},{"id":"T_\u1223\u120D\u1235","text":"\u12A2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12A3"},{"id":"T_\u1283\u121D\u1235","text":"\u12A4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12A6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12A8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12A8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12A9"},{"id":"T_\u1223\u120D\u1235","text":"\u12AA"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u12B0-layer","id":"T_\u122B\u1265\u12D5","text":"\u12AB","hint":"\u12B3"},{"id":"T_\u1283\u121D\u1235","text":"\u12AC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12AE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12B0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u12B0"},{"nextlayer":"\u12A8-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u12B2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u12B3"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u12B4"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u12B5"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12B8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12B8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12B9"},{"id":"T_\u1223\u120D\u1235","text":"\u12BA"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u12C0-layer","id":"T_\u122B\u1265\u12D5","text":"\u12BB","hint":"\u12C3"},{"id":"T_\u1283\u121D\u1235","text":"\u12BC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12BE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12C0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u12C0"},{"nextlayer":"\u12B8-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u12C2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u12C3"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u12C4"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u12C5"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12C8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12C8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12C9"},{"id":"T_\u1223\u120D\u1235","text":"\u12CA"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12CB"},{"id":"T_\u1283\u121D\u1235","text":"\u12CC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12CE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12D0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12D0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12D1"},{"id":"T_\u1223\u120D\u1235","text":"\u12D2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12D3"},{"id":"T_\u1283\u121D\u1235","text":"\u12D4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12D6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12D8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12D8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12D9"},{"id":"T_\u1223\u120D\u1235","text":"\u12DA"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12DB","hint":"\u12DF","sk":[{"id":"T_WWA","text":"\u12DF"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12DC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12DE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12E0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12E0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12E1"},{"id":"T_\u1223\u120D\u1235","text":"\u12E2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12E3","hint":"\u12E7","sk":[{"id":"T_WWA","text":"\u12E7"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12E4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12E6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12E8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"\u12E8-layer","id":"T_\u130D\u12D5\u12DD","text":"\u12E8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12E9"},{"id":"T_\u1223\u120D\u1235","text":"\u12EA"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12EB"},{"id":"T_\u1283\u121D\u1235","text":"\u12EC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12EE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12F0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"\u12F0-layer","id":"T_\u130D\u12D5\u12DD","text":"\u12F0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12F1"},{"id":"T_\u1223\u120D\u1235","text":"\u12F2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12F3","hint":"\u12F7","sk":[{"id":"T_WWA","text":"\u12F7"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12F4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12F6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12F8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"\u12F8-layer","id":"T_\u130D\u12D5\u12DD","text":"\u12F8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12F9"},{"id":"T_\u1223\u120D\u1235","text":"\u12FA"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12FB","hint":"\u12FF","sk":[{"id":"T_WWA","text":"\u12FF"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12FC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12FE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1300-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"\u1300-layer","id":"T_\u130D\u12D5\u12DD","text":"\u1300"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1301"},{"id":"T_\u1223\u120D\u1235","text":"\u1302"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1303","hint":"\u1307","sk":[{"id":"T_WWA","text":"\u1307"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1304"},{"id":"T_\u1233\u1265\u12D5","text":"\u1306"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1308-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"\u1308-layer","id":"T_\u130D\u12D5\u12DD","text":"\u1308"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1309"},{"id":"T_\u1223\u120D\u1235","text":"\u130A"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u1310-layer","id":"T_\u122B\u1265\u12D5","text":"\u130B","hint":"\u1313"},{"id":"T_\u1283\u121D\u1235","text":"\u130C"},{"id":"T_\u1233\u1265\u12D5","text":"\u130E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1310-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"nextlayer":"\u1310-layer","id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1310"},{"nextlayer":"\u1308-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u1312"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u1313"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u1314"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u1315"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1320-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1320"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1321"},{"id":"T_\u1223\u120D\u1235","text":"\u1322"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1323","hint":"\u1327","sk":[{"id":"T_WWA","text":"\u1327"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1324"},{"id":"T_\u1233\u1265\u12D5","text":"\u1326"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1328-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1328"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1329"},{"id":"T_\u1223\u120D\u1235","text":"\u132A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u132B","hint":"\u132F","sk":[{"id":"T_WWA","text":"\u132F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u132C"},{"id":"T_\u1233\u1265\u12D5","text":"\u132E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1330-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1330"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1331"},{"id":"T_\u1223\u120D\u1235","text":"\u1332"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1333","hint":"\u1337","sk":[{"id":"T_WWA","text":"\u1337"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1334"},{"id":"T_\u1233\u1265\u12D5","text":"\u1336"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1338-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1338"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1339"},{"id":"T_\u1223\u120D\u1235","text":"\u133A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u133B","hint":"\u133F","sk":[{"id":"T_WWA","text":"\u133F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u133C"},{"id":"T_\u1233\u1265\u12D5","text":"\u133E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1340-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1340"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1341"},{"id":"T_\u1223\u120D\u1235","text":"\u1342"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1343"},{"id":"T_\u1283\u121D\u1235","text":"\u1344"},{"id":"T_\u1233\u1265\u12D5","text":"\u1346"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1348-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1348"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1349"},{"id":"T_\u1223\u120D\u1235","text":"\u134A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u134B","hint":"\u134F","sk":[{"id":"T_WWA","text":"\u134F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u134C"},{"id":"T_\u1233\u1265\u12D5","text":"\u134E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1350-layer","row":[{"id":"1","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u1300-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D","hint":"\u1345","sk":[{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"}]},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355","hint":"\u1335","sk":[{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"}]}]},{"id":"2","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235","hint":"\u1225","sk":[{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"}]},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205","hint":"\u1285","sk":[{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275","hint":"\u127D","sk":[{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"}]},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325","hint":"\u132D","sk":[{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"}]}]},{"id":"3","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD","hint":"\u12E5","sk":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"}]},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265","hint":"\u126D","sk":[{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295","hint":"\u129D","sk":[{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1350"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1351"},{"id":"T_\u1223\u120D\u1235","text":"\u1352"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1353","hint":"\u1357","sk":[{"id":"T_WWA","text":"\u1357"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1354"},{"id":"T_\u1233\u1265\u12D5","text":"\u1356"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"punctuation","row":[{"id":"1","key":[{"id":"K_1","text":"1","hint":"\u1369\u1372","sk":[{"id":"U_1369","text":"\u1369"},{"id":"U_1372","text":"\u1372"},{"id":"U_137B","text":"\u137B"}]},{"id":"K_2","text":"2","hint":"\u136A\u1373","sk":[{"id":"U_136A","text":"\u136A"},{"id":"U_1373","text":"\u1373"}]},{"id":"K_3","text":"3","hint":"\u136B\u1374","sk":[{"id":"U_136B","text":"\u136B"},{"id":"U_1374","text":"\u1374"}]},{"id":"K_4","text":"4","hint":"\u136C\u1375","sk":[{"id":"U_136C","text":"\u136C"},{"id":"U_1375","text":"\u1375"}]},{"id":"K_5","text":"5","hint":"\u136D\u1376","sk":[{"id":"U_136D","text":"\u136D"},{"id":"U_1376","text":"\u1376"}]},{"id":"K_6","text":"6","hint":"\u136E\u1377","sk":[{"id":"U_136E","text":"\u136E"},{"id":"U_1377","text":"\u1377"}]},{"id":"K_7","text":"7","hint":"\u136F\u1378","sk":[{"id":"U_136F","text":"\u136F"},{"id":"U_1378","text":"\u1378"}]},{"id":"K_8","text":"8","hint":"\u1370\u1379","sk":[{"id":"U_1370","text":"\u1370"},{"id":"U_1379","text":"\u1379"}]},{"id":"K_9","text":"9","hint":"\u1371\u137A","sk":[{"id":"U_1371","text":"\u1371"},{"id":"U_137A","text":"\u137A"}]},{"id":"K_0","text":"0","hint":"\u1372\u137B","sk":[{"id":"U_00B0","text":"\u00B0"},{"layer":"shift","id":"U_1372","text":"\u1372"},{"id":"U_137B","text":"\u137B"},{"id":"T_THOUSAND","text":"\u1372\u137B"},{"id":"U_137C","text":"\u137C"}]}]},{"id":"2","key":[{"layer":"default","id":"K_HYPHEN","text":"-","hint":"\u2013","sk":[{"id":"U_2013","text":"\u2013"},{"id":"U_2014","text":"\u2014"},{"id":"U_2022","text":"\u2022"}]},{"layer":"default","id":"K_SLASH","text":"\/","hint":"\\","sk":[{"id":"K_BKSLASH","text":"\\"}]},{"id":"U_002C","text":","},{"id":"U_003B","text":";"},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"layer":"shift","id":"K_4","text":"$","hint":"\u20AC","sk":[{"id":"U_20BD","text":"\u20BD"},{"id":"U_00A5","text":"\u00A5"},{"id":"U_20AC","text":"\u20AC"},{"id":"U_A2","text":"\u00A2"},{"id":"U_A3","text":"\u00A3"},{"id":"U_20A9","text":"\u20A9"}]},{"layer":"shift","id":"K_7","text":"&","hint":"\u00A7","sk":[{"id":"U_00A7","text":"\u00A7"}]},{"id":"U_0027","text":"'","hint":"\u2018\u2019","sk":[{"id":"U_0060","text":"`"},{"id":"U_2018","text":"\u2018"},{"id":"U_2019","text":"\u2019"}]},{"layer":"shift","id":"K_QUOTE","text":"\"","hint":"\u00AB\u00BB","sk":[{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"},{"id":"U_201E","text":"\u201E"},{"id":"U_201C","text":"\u201C"},{"id":"U_201D","text":"\u201D"},{"layer":"shift","id":"K_QUOTE","text":"\""}]}]},{"id":"3","key":[{"nextlayer":"punctuation-2","width":"170","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"width":"120","id":"U_002E","pad":"70","text":".","hint":"\u2026","sk":[{"id":"U_2026","text":"\u2026"}]},{"width":"120","id":"U_003A","text":":"},{"layer":"shift","width":"120","id":"K_2","text":"@"},{"layer":"shift","width":"120","id":"K_1","text":"!","hint":"\u00A1","sk":[{"id":"U_00A1","text":"\u00A1"}]},{"layer":"shift","width":"120","id":"K_SLASH","text":"?","hint":"\u00BF","sk":[{"id":"U_00BF","text":"\u00BF"}]},{"width":"170","id":"K_BKSP","pad":"65","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"170","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE","pad":"85"},{"width":"170","id":"K_ENTER","pad":"80","sp":"1","text":"*Enter*"}]}]},{"id":"punctuation-2","row":[{"id":"1","key":[{"id":"K_LBRKT","text":"["},{"id":"K_RBRKT","text":"]"},{"layer":"shift","id":"K_LBRKT","text":"{"},{"layer":"shift","id":"K_RBRKT","text":"}"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%","hint":"\u2030","sk":[{"id":"U_2030","text":"\u2030"}]},{"layer":"shift","id":"K_6","text":"^"},{"layer":"shift","id":"K_8","text":"*"},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"K_EQUAL","text":"="}]},{"id":"2","key":[{"id":"U_005F","text":"_"},{"layer":"default","id":"K_BKSLASH","text":"\\"},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"layer":"shift","id":"K_BKQUOTE","text":"~"},{"id":"U_003C","text":"<"},{"id":"U_003E","text":">"},{"id":"U_20AC","text":"\u20AC"},{"id":"U_00A3","text":"\u00A3"},{"id":"U_00A5","text":"\u00A5"},{"id":"U_2022","text":"\u2022"}]},{"id":"3","key":[{"nextlayer":"ethiopic-punctuation","width":"170","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B","sk":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"*123*"},{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298"}]},{"width":"120","id":"U_002E","pad":"70","text":".","hint":"\u2026","sk":[{"id":"U_2026","text":"\u2026"}]},{"width":"120","id":"U_003A","text":":"},{"layer":"shift","width":"120","id":"K_2","text":"@"},{"layer":"shift","width":"120","id":"K_1","text":"!","hint":"\u00A1","sk":[{"id":"U_00A1","text":"\u00A1"}]},{"layer":"shift","width":"120","id":"K_SLASH","text":"?","hint":"\u00BF","sk":[{"id":"U_00BF","text":"\u00BF"}]},{"width":"170","id":"K_BKSP","pad":"65","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"170","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE","pad":"85"},{"width":"170","id":"K_ENTER","pad":"80","sp":"1","text":"*Enter*"}]}]},{"id":"ethiopic-punctuation","row":[{"id":"1","key":[{"id":"U_1372","text":"\u1372"},{"id":"U_1373","text":"\u1373"},{"id":"U_1374","text":"\u1374"},{"id":"U_1375","text":"\u1375"},{"id":"U_1376","text":"\u1376"},{"id":"U_1377","text":"\u1377"},{"id":"U_1378","text":"\u1378"},{"id":"U_1379","text":"\u1379"},{"id":"U_137A","text":"\u137A"},{"id":"U_137B","text":"\u137B"}]},{"id":"2","key":[{"id":"U_1369","text":"\u1369"},{"id":"U_136A","text":"\u136A"},{"id":"U_136B","text":"\u136B"},{"id":"U_136C","text":"\u136C"},{"id":"U_136D","text":"\u136D"},{"id":"U_136E","text":"\u136E"},{"id":"U_136F","text":"\u136F"},{"id":"U_1370","text":"\u1370"},{"id":"U_1371","text":"\u1371"},{"id":"U_137C","text":"\u137C"}]},{"id":"3","key":[{"nextlayer":"tigrinya-extra","id":"K_SHIFT","sp":"1","text":"\u1268\u1278\u1298","sk":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"}]},{"id":"U_1367","text":"\u1367"},{"id":"U_1360","text":"\u1360"},{"id":"U_1368","text":"\u1368"},{"id":"U_1361","text":"\u1361"},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"id":"U_1365","text":"\u1365"},{"id":"U_1366","text":"\u1366"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"U_00AB","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"id":"U_2039","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"id":"U_135E","text":"\u25CC\u135E"},{"width":"215","id":"K_SPACE"},{"id":"U_135F","text":"\u25CC\u135F","sk":[{"id":"U_135D","text":"\u25CC\u135D"}]},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"tigrinya-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12A0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12A1"},{"id":"T_\u1223\u120D\u1235","text":"\u12A2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12A3"},{"id":"T_\u1283\u121D\u1235","text":"\u12A4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12A6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1220-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1220-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1220"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1221"},{"id":"T_\u1223\u120D\u1235","text":"\u1222"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1223","hint":"\u1227","sk":[{"id":"T_WWA","text":"\u1227"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1224"},{"id":"T_\u1233\u1265\u12D5","text":"\u1226"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1268-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1268-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1268"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1269"},{"id":"T_\u1223\u120D\u1235","text":"\u126A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u126B","hint":"\u126F","sk":[{"id":"T_WWA","text":"\u126F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u126C"},{"id":"T_\u1233\u1265\u12D5","text":"\u126E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1278-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1278-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1278"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1279"},{"id":"T_\u1223\u120D\u1235","text":"\u127A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u127B","hint":"\u127F","sk":[{"id":"T_WWA","text":"\u127F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u127C"},{"id":"T_\u1233\u1265\u12D5","text":"\u127E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1280-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1280-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1280"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1281"},{"id":"T_\u1223\u120D\u1235","text":"\u1282"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u1288-extra","id":"T_\u122B\u1265\u12D5","text":"\u1283","hint":"\u128B"},{"id":"T_\u1283\u121D\u1235","text":"\u1284"},{"id":"T_\u1233\u1265\u12D5","text":"\u1286"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1288-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1280-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1288"},{"nextlayer":"\u1280-extra","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u128A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u128B"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u128C"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u128D"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1298-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1298-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1298"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1299"},{"id":"T_\u1223\u120D\u1235","text":"\u129A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u129B","hint":"\u129F","sk":[{"id":"T_WWA","text":"\u129F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u129C"},{"id":"T_\u1233\u1265\u12D5","text":"\u129E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12E0-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u12E0-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12E0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12E1"},{"id":"T_\u1223\u120D\u1235","text":"\u12E2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12E3","hint":"\u12E7","sk":[{"id":"T_WWA","text":"\u12E7"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12E4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12E6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12F8-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u12F8-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12F8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12F9"},{"id":"T_\u1223\u120D\u1235","text":"\u12FA"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12FB","hint":"\u12FF","sk":[{"id":"T_WWA","text":"\u12FF"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12FC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12FE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1318-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1318-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1318"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1319"},{"id":"T_\u1223\u120D\u1235","text":"\u131A"},{"width":"215","id":"K_SPACE"},{"nextlayer":"\u2D93-extra","id":"T_\u122B\u1265\u12D5","text":"\u131B","hint":"\u131F"},{"id":"T_\u1283\u121D\u1235","text":"\u131C"},{"id":"T_\u1233\u1265\u12D5","text":"\u131E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u2D93-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1318-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u2D93"},{"nextlayer":"\u1318-extra","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u2D94"},{"width":"215","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u131F"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u2D95"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u2D96"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1328-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1328-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1328"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1329"},{"id":"T_\u1223\u120D\u1235","text":"\u132A"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u132B","hint":"\u132F","sk":[{"id":"T_WWA","text":"\u132F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u132C"},{"id":"T_\u1233\u1265\u12D5","text":"\u132E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1330-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1330-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1330"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1331"},{"id":"T_\u1223\u120D\u1235","text":"\u1332"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1333","hint":"\u1337","sk":[{"id":"T_WWA","text":"\u1337"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1334"},{"id":"T_\u1233\u1265\u12D5","text":"\u1336"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1340-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\u1340-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1340"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1341"},{"id":"T_\u1223\u120D\u1235","text":"\u1342"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1343"},{"id":"T_\u1283\u121D\u1235","text":"\u1344"},{"id":"T_\u1233\u1265\u12D5","text":"\u1346"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\uD839\uDFE0-extra","row":[{"id":"1","key":[{"id":"U_00AB","pad":"130","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"nextlayer":"\u12E0-extra","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1340-extra","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-extra","layer":"shift","id":"K_P","text":"\u1335"},{"nextlayer":"\u1318-extra","id":"U_131D","text":"\u131D"},{"nextlayer":"\uD839\uDFE0-extra","id":"U_1E7E5","text":"\uD839\uDFE5"},{"nextlayer":"\u1328-extra","layer":"shift","id":"K_C","text":"\u132D"},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_2039","pad":"130","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"nextlayer":"\u1280-extra","id":"U_1285","text":"\u1285"},{"nextlayer":"\u1220-extra","id":"U_1225","text":"\u1225"},{"nextlayer":"\u12F8-extra","id":"U_12FD","text":"\u12FD"},{"nextlayer":"\u1298-extra","layer":"shift","id":"K_N","text":"\u129D"},{"nextlayer":"\u1268-extra","id":"K_V","text":"\u126D"},{"nextlayer":"\u1278-extra","id":"K_C","text":"\u127D"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_2019","text":"\u2019"},{"id":"U_1361","text":"\u1361"},{"id":"U_1366","text":"\u1366"},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"\uD839\uDFE0-extra","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\uD839\uDFE0"},{"id":"T_\u12AB\u12D5\u1265","text":"\uD839\uDFE1"},{"id":"T_\u1223\u120D\u1235","text":"\uD839\uDFE2"},{"width":"215","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\uD839\uDFE3"},{"id":"T_\u1283\u121D\u1235","text":"\uD839\uDFE4"},{"id":"T_\u1233\u1265\u12D5","text":"\uD839\uDFE6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]},"tablet":{"font":"Abyssinica SIL","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12A0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12A1"},{"id":"T_\u1223\u120D\u1235","text":"\u12A2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12A3"},{"id":"T_\u1283\u121D\u1235","text":"\u12A4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12A6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1200-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1200"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1201"},{"id":"T_\u1223\u120D\u1235","text":"\u1202"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1203","hint":"\u128B","sk":[{"id":"T_WWA","text":"\u128B"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1204"},{"id":"T_\u1233\u1265\u12D5","text":"\u1206"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1208-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1208"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1209"},{"id":"T_\u1223\u120D\u1235","text":"\u120A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u120B","hint":"\u120F","sk":[{"id":"T_WWA","text":"\u120F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u120C"},{"id":"T_\u1233\u1265\u12D5","text":"\u120E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1210-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1210"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1211"},{"id":"T_\u1223\u120D\u1235","text":"\u1212"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1213","hint":"\u1217","sk":[{"id":"T_WWA","text":"\u1217"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1214"},{"id":"T_\u1233\u1265\u12D5","text":"\u1216"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1218-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1218"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1219"},{"id":"T_\u1223\u120D\u1235","text":"\u121A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u121B","hint":"\u121F","sk":[{"id":"T_WWA","text":"\u121F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u121C"},{"id":"T_\u1233\u1265\u12D5","text":"\u121E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1220-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1220"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1221"},{"id":"T_\u1223\u120D\u1235","text":"\u1222"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1223","hint":"\u1227","sk":[{"id":"T_WWA","text":"\u1227"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1224"},{"id":"T_\u1233\u1265\u12D5","text":"\u1226"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1228-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1228"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1229"},{"id":"T_\u1223\u120D\u1235","text":"\u122A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u122B","hint":"\u122F","sk":[{"id":"T_WWA","text":"\u122F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u122C"},{"id":"T_\u1233\u1265\u12D5","text":"\u122E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1230-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1230"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1231"},{"id":"T_\u1223\u120D\u1235","text":"\u1232"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1233","hint":"\u1237","sk":[{"id":"T_WWA","text":"\u1237"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1234"},{"id":"T_\u1233\u1265\u12D5","text":"\u1236"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1238-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1238"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1239"},{"id":"T_\u1223\u120D\u1235","text":"\u123A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u123B","hint":"\u123F","sk":[{"id":"T_WWA","text":"\u123F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u123C"},{"id":"T_\u1233\u1265\u12D5","text":"\u123E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1240-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1240"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1241"},{"id":"T_\u1223\u120D\u1235","text":"\u1242"},{"width":"560","id":"K_SPACE"},{"nextlayer":"\u1248-layer","id":"T_\u122B\u1265\u12D5","text":"\u1243","hint":"\u124B"},{"id":"T_\u1283\u121D\u1235","text":"\u1244"},{"id":"T_\u1233\u1265\u12D5","text":"\u1246"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1248-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1248"},{"nextlayer":"\u1240-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u124A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u124B"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u124C"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u124D"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1250-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1250"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1251"},{"id":"T_\u1223\u120D\u1235","text":"\u1252"},{"width":"560","id":"K_SPACE"},{"nextlayer":"\u1258-layer","id":"T_\u122B\u1265\u12D5","text":"\u1253","hint":"\u125B"},{"id":"T_\u1283\u121D\u1235","text":"\u1254"},{"id":"T_\u1233\u1265\u12D5","text":"\u1256"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1258-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1258"},{"nextlayer":"\u1250-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u125A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u125B"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u125C"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u125D"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1260-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1260"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1261"},{"id":"T_\u1223\u120D\u1235","text":"\u1262"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1263","hint":"\u1267","sk":[{"id":"T_WWA","text":"\u1267"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1264"},{"id":"T_\u1233\u1265\u12D5","text":"\u1266"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1268-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1268"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1269"},{"id":"T_\u1223\u120D\u1235","text":"\u126A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u126B","hint":"\u126F","sk":[{"id":"T_WWA","text":"\u126F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u126C"},{"id":"T_\u1233\u1265\u12D5","text":"\u126E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1270-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1270"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1271"},{"id":"T_\u1223\u120D\u1235","text":"\u1272"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1273","hint":"\u1277","sk":[{"id":"T_WWA","text":"\u1277"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1274"},{"id":"T_\u1233\u1265\u12D5","text":"\u1276"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1278-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1278"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1279"},{"id":"T_\u1223\u120D\u1235","text":"\u127A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u127B","hint":"\u127F","sk":[{"id":"T_WWA","text":"\u127F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u127C"},{"id":"T_\u1233\u1265\u12D5","text":"\u127E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1280-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1280"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1281"},{"id":"T_\u1223\u120D\u1235","text":"\u1282"},{"width":"560","id":"K_SPACE"},{"nextlayer":"\u1288-layer","id":"T_\u122B\u1265\u12D5","text":"\u1283","hint":"\u128B"},{"id":"T_\u1283\u121D\u1235","text":"\u1284"},{"id":"T_\u1233\u1265\u12D5","text":"\u1286"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1288-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1288"},{"nextlayer":"\u1280-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u128A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u128B"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u128C"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u128D"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1290-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1290"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1291"},{"id":"T_\u1223\u120D\u1235","text":"\u1292"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1293","hint":"\u1297","sk":[{"id":"T_WWA","text":"\u1297"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1294"},{"id":"T_\u1233\u1265\u12D5","text":"\u1296"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1298-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1298"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1299"},{"id":"T_\u1223\u120D\u1235","text":"\u129A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u129B","hint":"\u129F","sk":[{"id":"T_WWA","text":"\u129F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u129C"},{"id":"T_\u1233\u1265\u12D5","text":"\u129E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12A0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12A0","hint":"\u12A7","sk":[{"id":"U_12A7","text":"\u12A7"}]},{"id":"T_\u12AB\u12D5\u1265","text":"\u12A1","hint":"\u12A7"},{"id":"T_\u1223\u120D\u1235","text":"\u12A2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12A3"},{"id":"T_\u1283\u121D\u1235","text":"\u12A4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12A6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12A8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12A8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12A9"},{"id":"T_\u1223\u120D\u1235","text":"\u12AA"},{"width":"560","id":"K_SPACE"},{"nextlayer":"\u12B0-layer","id":"T_\u122B\u1265\u12D5","text":"\u12AB","hint":"\u12B3"},{"id":"T_\u1283\u121D\u1235","text":"\u12AC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12AE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12B0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u12B0"},{"nextlayer":"\u12A8-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u12B2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u12B3"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u12B4"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u12B5"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12B8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12B8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12B9"},{"id":"T_\u1223\u120D\u1235","text":"\u12BA"},{"width":"560","id":"K_SPACE"},{"nextlayer":"\u12C0-layer","id":"T_\u122B\u1265\u12D5","text":"\u12BB","hint":"\u12C3"},{"id":"T_\u1233\u1265\u12D5","text":"\u12BE"},{"id":"T_\u1283\u121D\u1235","text":"\u12BC"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12C0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u12C0"},{"nextlayer":"\u12B8-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u12C2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u12C3"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u12C4"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u12C5"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12C8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12C8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12C9"},{"id":"T_\u1223\u120D\u1235","text":"\u12CA"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12CB"},{"id":"T_\u1283\u121D\u1235","text":"\u12CC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12CE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12D0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12D0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12D1"},{"id":"T_\u1223\u120D\u1235","text":"\u12D2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12D3"},{"id":"T_\u1283\u121D\u1235","text":"\u12D4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12D6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12D8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12D8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12D9"},{"id":"T_\u1223\u120D\u1235","text":"\u12DA"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12DB","hint":"\u12DF","sk":[{"id":"T_WWA","text":"\u12DF"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12DC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12DE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12E0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12E0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12E1"},{"id":"T_\u1223\u120D\u1235","text":"\u12E2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12E3","hint":"\u12E7","sk":[{"id":"T_WWA","text":"\u12E7"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12E4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12E6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12E8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12E8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12E9"},{"id":"T_\u1223\u120D\u1235","text":"\u12EA"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12EB"},{"id":"T_\u1283\u121D\u1235","text":"\u12EC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12EE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12F0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12F0"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12F1"},{"id":"T_\u1223\u120D\u1235","text":"\u12F2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12F3","hint":"\u12F7","sk":[{"id":"T_WWA","text":"\u12F7"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12F4"},{"id":"T_\u1233\u1265\u12D5","text":"\u12F6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u12F8-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u12F8"},{"id":"T_\u12AB\u12D5\u1265","text":"\u12F9"},{"id":"T_\u1223\u120D\u1235","text":"\u12FA"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u12FB","hint":"\u12FF","sk":[{"id":"T_WWA","text":"\u12FF"}]},{"id":"T_\u1283\u121D\u1235","text":"\u12FC"},{"id":"T_\u1233\u1265\u12D5","text":"\u12FE"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1300-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1300"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1301"},{"id":"T_\u1223\u120D\u1235","text":"\u1302"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1303","hint":"\u1307","sk":[{"id":"T_WWA","text":"\u1307"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1304"},{"id":"T_\u1233\u1265\u12D5","text":"\u1306"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1308-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1308"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1309"},{"id":"T_\u1223\u120D\u1235","text":"\u130A"},{"width":"560","id":"K_SPACE"},{"nextlayer":"\u1310-layer","id":"T_\u122B\u1265\u12D5","text":"\u130B","hint":"\u1313"},{"id":"T_\u1283\u121D\u1235","text":"\u130C"},{"id":"T_\u1233\u1265\u12D5","text":"\u130E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1310-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u1310"},{"nextlayer":"\u1308-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u1312"},{"width":"560","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u1313"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u1314"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u1315"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1318-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1318"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1319"},{"id":"T_\u1223\u120D\u1235","text":"\u131A"},{"width":"560","id":"K_SPACE"},{"nextlayer":"\u2D93-layer","id":"T_\u122B\u1265\u12D5","text":"\u131B","hint":"\u131F"},{"id":"T_\u1283\u121D\u1235","text":"\u131C"},{"id":"T_\u1233\u1265\u12D5","text":"\u131E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1320-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1320"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1321"},{"id":"T_\u1223\u120D\u1235","text":"\u1322"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1323","hint":"\u1327","sk":[{"id":"T_WWA","text":"\u1327"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1324"},{"id":"T_\u1233\u1265\u12D5","text":"\u1326"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1328-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1328"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1329"},{"id":"T_\u1223\u120D\u1235","text":"\u132A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u132B","hint":"\u132F","sk":[{"id":"T_WWA","text":"\u132F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u132C"},{"id":"T_\u1233\u1265\u12D5","text":"\u132E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1330-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1330"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1331"},{"id":"T_\u1223\u120D\u1235","text":"\u1332"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1333","hint":"\u1337","sk":[{"id":"T_WWA","text":"\u1337"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1334"},{"id":"T_\u1233\u1265\u12D5","text":"\u1336"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1338-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1338"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1339"},{"id":"T_\u1223\u120D\u1235","text":"\u133A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u133B","hint":"\u133F","sk":[{"id":"T_WWA","text":"\u133F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u133C"},{"id":"T_\u1233\u1265\u12D5","text":"\u133E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1340-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1340"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1341"},{"id":"T_\u1223\u120D\u1235","text":"\u1342"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1343"},{"id":"T_\u1283\u121D\u1235","text":"\u1344"},{"id":"T_\u1233\u1265\u12D5","text":"\u1346"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1348-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1348"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1349"},{"id":"T_\u1223\u120D\u1235","text":"\u134A"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u134B","hint":"\u134F","sk":[{"id":"T_WWA","text":"\u134F"}]},{"id":"T_\u1283\u121D\u1235","text":"\u134C"},{"id":"T_\u1233\u1265\u12D5","text":"\u134E"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u1350-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\u1350"},{"id":"T_\u12AB\u12D5\u1265","text":"\u1351"},{"id":"T_\u1223\u120D\u1235","text":"\u1352"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\u1353","hint":"\u1357","sk":[{"id":"T_WWA","text":"\u1357"}]},{"id":"T_\u1283\u121D\u1235","text":"\u1354"},{"id":"T_\u1233\u1265\u12D5","text":"\u1356"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\u2D93-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u12D8\u1218\u12F0_\u130D\u12D5\u12DD","text":"\u2D93"},{"nextlayer":"\u1318-layer","id":"T_BACK","text":"\u27F2"},{"id":"T_\u12D8\u1218\u12F0_\u1223\u120D\u1235","text":"\u2D94"},{"width":"560","id":"K_SPACE"},{"id":"T_\u12D8\u1218\u12F0_\u122B\u1265\u12D5","text":"\u131F"},{"id":"T_\u12D8\u1218\u12F0_\u1283\u121D\u1235","text":"\u2D95"},{"id":"T_\u12D8\u1218\u12F0_\u12AB\u12D5\u1265","text":"\u2D96"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"\uD839\uDFE0-layer","row":[{"id":"1","key":[{"nextlayer":"\u12E0-layer","layer":"shift","id":"K_Z","text":"\u12E5"},{"nextlayer":"\u1220-layer","id":"U_1225","text":"\u1225"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"nextlayer":"\u1280-layer","id":"U_1285","text":"\u1285"}]},{"id":"2","key":[{"nextlayer":"\u12D0-layer","id":"U_12D5","pad":"70","text":"\u12D5"},{"nextlayer":"\u1238-layer","id":"K_X","text":"\u123D"},{"nextlayer":"\u12F0-layer","id":"K_J","text":"\u1305"},{"nextlayer":"\u1348-layer","id":"K_F","text":"\u134D"},{"nextlayer":"\u12B8-layer","layer":"shift","id":"K_K","text":"\u12BD"},{"nextlayer":"\u1210-layer","layer":"shift","id":"K_H","text":"\u1215"},{"nextlayer":"\u12E8-layer","id":"K_Y","text":"\u12ED"},{"nextlayer":"\u1250-layer","layer":"shift","id":"K_Q","text":"\u1255"},{"nextlayer":"\u1278-layer","id":"K_C","text":"\u127D"},{"nextlayer":"\u1328-layer","layer":"shift","id":"K_C","text":"\u132D"},{"nextlayer":"\u1340-layer","id":"U_1345","text":"\u1345"},{"nextlayer":"\u1330-layer","layer":"shift","id":"K_P","text":"\u1335"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"\u12A0-layer","id":"U_12A5","pad":"70","text":"\u12A5"},{"nextlayer":"\u1230-layer","id":"K_S","text":"\u1235"},{"nextlayer":"\u12F0-layer","id":"K_D","text":"\u12F5"},{"nextlayer":"\u1228-layer","id":"K_R","text":"\u122D"},{"nextlayer":"\u12A8-layer","id":"K_K","text":"\u12AD"},{"nextlayer":"\u1200-layer","id":"K_H","text":"\u1205"},{"nextlayer":"\u1308-layer","id":"K_G","text":"\u130D"},{"nextlayer":"\u1240-layer","id":"K_Q","text":"\u1245"},{"nextlayer":"\u1270-layer","id":"K_T","text":"\u1275"},{"nextlayer":"\u1320-layer","layer":"shift","id":"K_T","text":"\u1325"},{"nextlayer":"\u1338-layer","layer":"shift","id":"K_S","text":"\u133D"},{"nextlayer":"\u1350-layer","id":"K_P","text":"\u1355"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"4","key":[{"nextlayer":"punctuation","id":"K_SHIFT","sp":"1","text":"@","sk":[{"nextlayer":"ethiopic-punctuation","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B"}]},{"layer":"shift","id":"K_1","text":"!","hint":"?","sk":[{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_SLASH","text":"\/"},{"id":"U_002E","text":"."},{"id":"U_002C","text":","},{"id":"U_002D","text":"-"},{"id":"U_003A","text":":"},{"id":"U_2019","text":"\u2019"}]},{"nextlayer":"\u12D8-layer","id":"K_Z","text":"\u12DD"},{"nextlayer":"\u12C8-layer","id":"K_W","text":"\u12CD"},{"nextlayer":"\u1268-layer","id":"K_V","text":"\u126D"},{"nextlayer":"\u1260-layer","id":"K_B","text":"\u1265"},{"nextlayer":"\u1208-layer","id":"K_L","text":"\u120D"},{"nextlayer":"\u1218-layer","id":"K_M","text":"\u121D"},{"nextlayer":"\u1290-layer","id":"K_N","text":"\u1295"},{"nextlayer":"\u1298-layer","layer":"shift","id":"K_N","text":"\u129D"},{"id":"U_2019","text":"\u2019"},{"id":"U_1362","text":"\u1362","hint":"\u1361","sk":[{"layer":"shift","id":"K_COLON","text":"\u1361"},{"id":"K_COMMA","text":"\u1363"},{"id":"K_COLON","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"}]},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"T_\u130D\u12D5\u12DD","text":"\uD839\uDFE0"},{"id":"T_\u12AB\u12D5\u1265","text":"\uD839\uDFE1"},{"id":"T_\u1223\u120D\u1235","text":"\uD839\uDFE2"},{"width":"560","id":"K_SPACE"},{"id":"T_\u122B\u1265\u12D5","text":"\uD839\uDFE3"},{"id":"T_\u1283\u121D\u1235","text":"\uD839\uDFE4"},{"id":"T_\u1233\u1265\u12D5","text":"\uD839\uDFE6"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"punctuation","row":[{"id":"1","key":[{"layer":"shift","id":"K_5","text":"%","hint":"\u2030","sk":[{"id":"U_2030","text":"\u2030"}]},{"layer":"shift","id":"K_3","text":"#"},{"id":"U_003C","text":"<"},{"id":"U_003E","text":">"},{"layer":"shift","id":"K_LBRKT","text":"{"},{"layer":"shift","id":"K_RBRKT","text":"}"},{"id":"U_00A3","text":"\u00A3"},{"id":"U_00A5","text":"\u00A5"},{"layer":"shift","id":"K_8","text":"*"},{"id":"K_EQUAL","text":"="}]},{"id":"2","key":[{"layer":"shift","id":"K_6","text":"^"},{"layer":"shift","id":"K_BKQUOTE","text":"~"},{"id":"U_003B","text":";"},{"id":"K_BKSLASH","text":"\\"},{"id":"K_LBRKT","text":"["},{"id":"K_RBRKT","text":"]"},{"id":"U_20AC","text":"\u20AC"},{"layer":"shift","id":"K_QUOTE","text":"\"","hint":"\u00AB\u00BB","sk":[{"id":"U_00AB","text":"\u00AB"},{"id":"U_00BB","text":"\u00BB"},{"id":"U_201E","text":"\u201E"},{"id":"U_201C","text":"\u201C"},{"id":"U_201D","text":"\u201D"}]},{"id":"U_2022","text":"\u2022"},{"id":"K_HYPHEN","text":"-","hint":"\u2013","sk":[{"id":"U_2013","text":"\u2013"},{"id":"U_2014","text":"\u2014"}]}]},{"id":"3","key":[{"layer":"shift","id":"K_7","text":"&","hint":"\u00A7","sk":[{"id":"U_00A7","text":"\u00A7"}]},{"layer":"shift","id":"K_BKSLASH","text":"|"},{"id":"U_002C","text":","},{"id":"K_SLASH","text":"\/"},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"layer":"shift","id":"K_4","text":"$","sk":[{"id":"U_20BD","text":"\u20BD"},{"id":"U_00A5","text":"\u00A5"},{"id":"U_20AC","text":"\u20AC"},{"id":"U_A2","text":"\u00A2"},{"id":"U_A3","text":"\u00A3"},{"id":"U_20A9","text":"\u20A9"}]},{"id":"U_0027","text":"'","hint":"\u2018\u2019","sk":[{"id":"U_0060","text":"`"},{"id":"U_2018","text":"\u2018"},{"id":"U_2019","text":"\u2019"}]},{"id":"U_00B0","text":"\u00B0"},{"layer":"shift","id":"K_EQUAL","text":"+"}]},{"id":"4","key":[{"nextlayer":"ethiopic-punctuation","width":"170","id":"K_SHIFT","sp":"1","text":"\u1369\u136A\u136B","sk":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"}]},{"width":"120","id":"U_002E","pad":"70","text":".","hint":"\u2026","sk":[{"id":"U_2026","text":"\u2026"}]},{"width":"120","id":"U_003A","text":":"},{"layer":"shift","width":"120","id":"K_2","text":"@"},{"layer":"shift","width":"120","id":"K_1","text":"!","hint":"\u00A1","sk":[{"id":"U_00A1","text":"\u00A1"}]},{"layer":"shift","width":"120","id":"K_SLASH","text":"?","hint":"\u00BF","sk":[{"id":"U_00BF","text":"\u00BF"}]},{"width":"170","id":"K_BKSP","pad":"65","sp":"1","text":"*BkSp*"}]},{"id":"5","key":[{"nextlayer":"default","width":"170","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE","pad":"85"},{"width":"170","id":"K_ENTER","pad":"80","sp":"1","text":"*Enter*"}]}]},{"id":"ethiopic-punctuation","row":[{"id":"1","key":[{"id":"U_1369","pad":"70","text":"\u1369"},{"id":"U_136A","text":"\u136A"},{"id":"U_136B","text":"\u136B"},{"id":"U_136C","text":"\u136C"},{"id":"U_136D","text":"\u136D"},{"id":"U_136E","text":"\u136E"},{"id":"U_136F","text":"\u136F"},{"id":"U_1370","text":"\u1370"},{"id":"U_1371","text":"\u1371"},{"id":"U_137B","text":"\u137B"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"2","key":[{"id":"U_1372","pad":"70","text":"\u1372"},{"id":"U_1373","text":"\u1373"},{"id":"U_1374","text":"\u1374"},{"id":"U_1375","text":"\u1375"},{"id":"U_1376","text":"\u1376"},{"id":"U_1377","text":"\u1377"},{"id":"U_1378","text":"\u1378"},{"id":"U_1379","text":"\u1379"},{"id":"U_137A","text":"\u137A"},{"id":"U_137C","text":"\u137C"},{"width":"20","id":"T_SPACER","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"1","text":"\u1200\u1208\u1210"},{"id":"U_1367","text":"\u1367"},{"id":"U_1360","text":"\u1360"},{"id":"U_1368","text":"\u1368"},{"id":"U_1361","text":"\u1361"},{"id":"U_1363","text":"\u1363"},{"id":"U_1364","text":"\u1364"},{"id":"U_1366","text":"\u1366"},{"id":"U_1365","text":"\u1365"},{"id":"U_1362","text":"\u1362"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"U_00AB","text":"\u00AB","hint":"\u201C","sk":[{"id":"U_201C","text":"\u201C"}]},{"id":"U_2039","text":"\u2039","hint":"\u2018","sk":[{"id":"U_2018","text":"\u2018"}]},{"id":"U_135E","text":"\u25CC\u135E"},{"width":"330","id":"K_SPACE"},{"id":"U_135F","text":"\u25CC\u135F"},{"id":"U_203A","text":"\u203A","hint":"\u2019","sk":[{"id":"U_2019","text":"\u2019"}]},{"width":"100","id":"U_00BB","text":"\u00BB","hint":"\u201D","sk":[{"id":"U_201D","text":"\u201D"}]},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KCSS="/*\n * Pastel colors for GFF Keyboards\n * Primarily from: https://www.behance.net/gallery/125405749/Top-10-trending-pastel-color-palettes-in-2021\n */\n \n /* functional keys */\n .phone div.kmw-key.kmw-key-shift[id$='K_LOPT'], .tablet div.kmw-key.kmw-key-shift[id$='K_LOPT'],\n .phone div.kmw-key.kmw-key-shift[id$='K_BKSP'], .tablet div.kmw-key.kmw-key-shift[id$='K_BKSP'],\n .phone div.kmw-key.kmw-key-shift[id$='K_ENTER'], .tablet div.kmw-key.kmw-key-shift[id$='K_ENTER'],\n .phone div.kmw-key.kmw-key-shift[id$='K_SHIFT'], .tablet div.kmw-key.kmw-key-shift[id$='K_SHIFT'],\n .phone div.kmw-key.kmw-key-special[id$='K_SHIFT'], .tablet div.kmw-key.kmw-key-special[id$='K_SHIFT'],\n .phone div.kmw-key.kmw-key-shift[id$='T_EMPTY'], .tablet div.kmw-key.kmw-key-shift[id$='T_EMPTY']\n /* { background: #f3d6ce ; color: black; } */\n { background: #ece1d5 ; color: black ; }\n \n /* default layers: latin punctuation */\n .phone div.kmw-key.kmw-key-default[id$='K_SPACE'], .tablet div.kmw-key.kmw-key-default[id$='K_SPACE']\n { background: #f4eee7 ; color: #f4eee7 ; } /* eceae4 */\n \n .phone div.kmw-key.kmw-key-default[id$='K_1+shift'], .tablet div.kmw-key.kmw-key-default[id$='K_1+shift'], /* ! */\n .phone div.kmw-key.kmw-key-default[id$='U_1362'], .tablet div.kmw-key.kmw-key-default[id$='U_1362'], /* ። */\n .tablet div.kmw-key.kmw-key-default[id$='U_2019'] \n { background: #f4eee7 ; color: black ; }\n \n /* tigrinya-extra layer: punctuation */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_2039'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_2039'], /* ‹ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_203A'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_203A'], /* › */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_00AB'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_00AB'], /* « */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_00BB'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_00BB'] /* » */\n { background: #ebece6 ; color: black ; } \n \n /* ethiopic-punctuation layer: punctuation */\n .phone div.kmw-key.kmw-key-default[id$='punctuation-U_2039'], .tablet div.kmw-key.kmw-key-default[id$='punctuation-U_2039'], /* ‹ */\n .phone div.kmw-key.kmw-key-default[id$='punctuation-U_203A'], .tablet div.kmw-key.kmw-key-default[id$='punctuation-U_203A'], /* › */\n .phone div.kmw-key.kmw-key-default[id$='punctuation-U_00AB'], .tablet div.kmw-key.kmw-key-default[id$='punctuation-U_00AB'], /* « */\n .phone div.kmw-key.kmw-key-default[id$='punctuation-U_00BB'], .tablet div.kmw-key.kmw-key-default[id$='punctuation-U_00BB'] /* » */\n { background: #ebece6 ; color: black ; } \n \n \n /* tigrinya-extra layer: ethiopic punctuation */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1361'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1361'], /* ፡ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1362'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1362'], /* ። */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1363'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1363'], /* ፣ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1364'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1364'], /* ፤ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1365'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1365'], /* ፥ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1366'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1366'], /* ፦ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1367'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1367'], /* ፧ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1360'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1360'], /* ፠ */\n .phone div.kmw-key.kmw-key-default[id$='extra-U_1368'], .tablet div.kmw-key.kmw-key-default[id$='extra-U_1368'] /* ፨ */\n { background: #f4eee7 ; color: black ; }\n \n /* tigrinya-extra layer: western numerals */\n .phone div.kmw-key.kmw-key-default[id$='K_1'], .tablet div.kmw-key.kmw-key-default[id$='K_1'], /* 1 */\n .phone div.kmw-key.kmw-key-default[id$='K_2'], .tablet div.kmw-key.kmw-key-default[id$='K_2'], /* 2 */\n .phone div.kmw-key.kmw-key-default[id$='K_3'], .tablet div.kmw-key.kmw-key-default[id$='K_3'], /* 3 */\n .phone div.kmw-key.kmw-key-default[id$='K_4'], .tablet div.kmw-key.kmw-key-default[id$='K_4'], /* 4 */\n .phone div.kmw-key.kmw-key-default[id$='K_5'], .tablet div.kmw-key.kmw-key-default[id$='K_5'], /* 5 */\n .phone div.kmw-key.kmw-key-default[id$='K_6'], .tablet div.kmw-key.kmw-key-default[id$='K_6'], /* 6 */\n .phone div.kmw-key.kmw-key-default[id$='K_7'], .tablet div.kmw-key.kmw-key-default[id$='K_7'], /* 7 */\n .phone div.kmw-key.kmw-key-default[id$='K_8'], .tablet div.kmw-key.kmw-key-default[id$='K_8'], /* 8 */\n .phone div.kmw-key.kmw-key-default[id$='K_9'], .tablet div.kmw-key.kmw-key-default[id$='K_9'], /* 9 */\n .phone div.kmw-key.kmw-key-default[id$='K_0'], .tablet div.kmw-key.kmw-key-default[id$='K_0'], /* 0 */\n .tablet div.kmw-key.kmw-key-default[id$='K_HYPHEN'], .tablet div.kmw-key.kmw-key-default[id$='K_EQUAL'], \n .kmw-keyboard-gff_tigrinya_ethiopia #tigrinya-etens-extra-T_MORE /* ▶ */\n { background: #ebece6 ; color: black ; }\n \n /* tigrinya-extra layer: ge'ez numerals */\n .phone div.kmw-key.kmw-key-default[id$='K_SPACE'], .tablet div.kmw-key.kmw-key-default[id$='K_SPACE'],\n .phone div.kmw-key.kmw-key-default[id$='U_1369'], .tablet div.kmw-key.kmw-key-default[id$='U_1369'], /* ፩ */\n .phone div.kmw-key.kmw-key-default[id$='U_136A'], .tablet div.kmw-key.kmw-key-default[id$='U_136A'], /* ፪ */\n .phone div.kmw-key.kmw-key-default[id$='U_136B'], .tablet div.kmw-key.kmw-key-default[id$='U_136B'], /* ፫ */\n .phone div.kmw-key.kmw-key-default[id$='U_136C'], .tablet div.kmw-key.kmw-key-default[id$='U_136C'], /* ፬ */\n .phone div.kmw-key.kmw-key-default[id$='U_136D'], .tablet div.kmw-key.kmw-key-default[id$='U_136D'], /* ፭ */\n .phone div.kmw-key.kmw-key-default[id$='U_136E'], .tablet div.kmw-key.kmw-key-default[id$='U_136E'], /* ፮ */\n .phone div.kmw-key.kmw-key-default[id$='U_136F'], .tablet div.kmw-key.kmw-key-default[id$='U_136F'], /* ፯ */\n .phone div.kmw-key.kmw-key-default[id$='U_1370'], .tablet div.kmw-key.kmw-key-default[id$='U_1370'], /* ፰ */\n .phone div.kmw-key.kmw-key-default[id$='U_1371'], .tablet div.kmw-key.kmw-key-default[id$='U_1371'], /* ፱ */\n .phone div.kmw-key.kmw-key-default[id$='U_1372+shift'], .tablet div.kmw-key.kmw-key-default[id$='U_1372'], /* ፲ */\n .kmw-keyboard-gff_tigrinya_ethiopia #tigrinya-tens-extra-T_MORE /* ▶ */\n { background: #ece1d5 ; color: black ; }\n \n .phone div.kmw-key.kmw-key-default[id$='U_1372'], .tablet div.kmw-key.kmw-key-default[id$='U_1372'], /* ፲ */\n .phone div.kmw-key.kmw-key-default[id$='U_1373'], .tablet div.kmw-key.kmw-key-default[id$='U_1373'], /* ፳ */\n .phone div.kmw-key.kmw-key-default[id$='U_1374'], .tablet div.kmw-key.kmw-key-default[id$='U_1374'], /* ፴ */\n .phone div.kmw-key.kmw-key-default[id$='U_1375'], .tablet div.kmw-key.kmw-key-default[id$='U_1375'], /* ፵ */\n .phone div.kmw-key.kmw-key-default[id$='U_1376'], .tablet div.kmw-key.kmw-key-default[id$='U_1376'], /* ፶ */\n .phone div.kmw-key.kmw-key-default[id$='U_1377'], .tablet div.kmw-key.kmw-key-default[id$='U_1377'], /* ፷ */\n .phone div.kmw-key.kmw-key-default[id$='U_1378'], .tablet div.kmw-key.kmw-key-default[id$='U_1378'], /* ፸ */\n .phone div.kmw-key.kmw-key-default[id$='U_1379'], .tablet div.kmw-key.kmw-key-default[id$='U_1379'], /* ፹ */\n .phone div.kmw-key.kmw-key-default[id$='U_137A'], .tablet div.kmw-key.kmw-key-default[id$='U_137A'], /* ፺ */\n .phone div.kmw-key.kmw-key-default[id$='U_137B'], .tablet div.kmw-key.kmw-key-default[id$='U_137B'], /* ፻ */\n .phone div.kmw-key.kmw-key-default[id$='T_THOUSAND'], .tablet div.kmw-key.kmw-key-default[id$='T_THOUSAND'], /* ፲፻ */ \n .phone div.kmw-key.kmw-key-default[id$='U_137C'], .tablet div.kmw-key.kmw-key-default[id$='U_137C'], /* ፼ */\n /* .kmw-keyboard-gff_tigrinya_ethiopia #tigrinya-extra-T_MORE, */\n .phone div.kmw-key.kmw-key-special[id$='extra-T_MORE'] /* ▶ */\n { background: #f3d6ce ; color: black ; }\n \n /* default layer ግዕዝ */\n \n .phone div.kmw-key.kmw-key-default[id$='T_ግዕዝ'], .tablet div.kmw-key.kmw-key-default[id$='T_ግዕዝ']\n { background: #e2f0cb ; color: black; } /*#baed91 */\n \n /* default layer ካዕብ */\n .phone div.kmw-key.kmw-key-default[id$='T_ካዕብ'], .tablet div.kmw-key.kmw-key-default[id$='T_ካዕብ']\n { background: #ffffb5 ; color: black; } /* #faf884 */ \n \n /* default layer ሣልስ */\n .phone div.kmw-key.kmw-key-default[id$='T_ሣልስ'], .tablet div.kmw-key.kmw-key-default[id$='T_ሣልስ']\n { background: #fea3aa ; color: black; }\n \n /* default layer ራብዕ */\n .phone div.kmw-key.kmw-key-default[id$='T_ራብዕ'], .tablet div.kmw-key.kmw-key-default[id$='T_ራብዕ']\n { background: #ccf1ff ; color: black; } /* #b2cefe */\n \n /* default layer ኃምስ */\n .phone div.kmw-key.kmw-key-default[id$='T_ኃምስ'], .tablet div.kmw-key.kmw-key-default[id$='T_ኃምስ']\n { background: #e0d7ff ; color: black; } /* #f2a2e8 */\n \n /* default layer ሳድስ - used primarily when a sadis letter appears in a popup or on the -extra layers */\n /*\n .phone div.kmw-key.kmw-key-default[id$='T_ሳድስ'], .tablet div.kmw-key.kmw-key-default[id$='T_ሳድስ']\n { background: #eceae4; color: black; }\n */\n \n /* default layer ሳብዕ */\n .phone div.kmw-key.kmw-key-default[id$='T_ሳብዕ'], .tablet div.kmw-key.kmw-key-default[id$='T_ሳብዕ']\n { background: #fad6b6 ; color: black; } /* f8b88b*/\n \n /* ዘመደ-ግዕዝ */\n .phone div.kmw-key.kmw-key-default[id$='T_ዘመደ_ግዕዝ'], .tablet div.kmw-key.kmw-key-default[id$='T_ዘመደ_ግዕዝ']\n {\n background: #ffffff; color: black ;\n background: linear-gradient(180deg, #ffffff 0%, #e2f0cb 100%);\n }\n \n /* ዘመደ-ካዕብ */\n .phone div.kmw-key.kmw-key-default[id$='T_ዘመደ_ካዕብ'], .tablet div.kmw-key.kmw-key-default[id$='T_ዘመደ_ካዕብ']\n {\n background: #ffffff; color: black ;\n background: linear-gradient(180deg, #ffffff 0%, #ffffb5 100%);\n }\n \n /* ዘመደ-ሣልስ */\n .phone div.kmw-key.kmw-key-default[id$='T_ዘመደ_ሣልስ'], .tablet div.kmw-key.kmw-key-default[id$='T_ዘመደ_ሣልስ']\n {\n background: #ffffff; color: black ;\n background: linear-gradient(180deg, #ffffff 0%, #fea3aa 100%);\n }\n \n /* ዘመደ-ራብዕ */\n .phone div.kmw-key.kmw-key-default[id$='T_ዘመደ_ራብዕ'], .tablet div.kmw-key.kmw-key-default[id$='T_ዘመደ_ራብዕ'],\n .phone div.kmw-key.kmw-key-default[id$='T_WWA'], .tablet div.kmw-key.kmw-key-default[id$='T_WWA']\n {\n background: #ffffff; color: black ;\n background: linear-gradient(180deg, #ffffff 0%, #ccf1ff 100%);\n }\n \n /* ዘመደ-ኃምስ */\n .phone div.kmw-key.kmw-key-default[id$='T_ዘመደ_ኃምስ'], .tablet div.kmw-key.kmw-key-default[id$='T_ዘመደ_ኃምስ']\n {\n background: #ffffff; color: black ;\n background: linear-gradient(180deg, #ffffff 0%, #e0d7ff 100%);\n }\n \n /* resets sadis letters that appear in popups of the default layers, this is needed for when the keys appear on the -extra layer */\n .tablet.ios .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-K_HYPHEN, .tablet.ios .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-K_EQUAL, \n .ios .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-K_1\\+shift, .phone.ios .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-2-K_1\\+shift,\n .tablet.ios .kmw-keyboard-gff_tigrinya_ethiopia #ethiopic-punctuation-U_1362,\n .phone.ios .kmw-key.kmw-key-default[id^='popup'][id$='U_1366'], .tablet.ios .kmw-key.kmw-key-default[id^='popup'][id$='U_1366'],\n .phone.ios .kmw-key.kmw-key-default[id^='popup'][id$='U_00AB'], .tablet.ios .kmw-key.kmw-key-default[id^='popup'][id$='U_00AB'],\n .phone.ios .kmw-key.kmw-key-default[id^='popup'][id$='U_00BB'], .tablet.ios .kmw-key.kmw-key-default[id^='popup'][id$='U_00BB']\n {background: #fdfdfe ; color: black ; }\n \n .tablet.android .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-K_HYPHEN, .tablet.android .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-K_EQUAL, \n .android .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-K_1\\+shift, .phone.android .kmw-keyboard-gff_tigrinya_ethiopia #punctuation-2-K_1\\+shift,\n .tablet.android .kmw-keyboard-gff_tigrinya_ethiopia #ethiopic-punctuation-U_1362,\n .phone.android .kmw-key.kmw-key-default[id^='popup'][id$='U_1366'], .tablet.android .kmw-key.kmw-key-default[id^='popup'][id$='U_1366'],\n .phone.android .kmw-key.kmw-key-default[id^='popup'][id$='U_00AB'], .tablet.android .kmw-key.kmw-key-default[id^='popup'][id$='U_00AB'],\n .phone.android .kmw-key.kmw-key-default[id^='popup'][id$='U_00BB'], .tablet.android .kmw-key.kmw-key-default[id^='popup'][id$='U_00BB']\n {background: #777 ; color: white ; }\n \n .phone div.kmw-key.kmw-key-default[id$='U_135D'], .tablet div.kmw-key.kmw-key-default[id$='U_135D'],\n .phone div.kmw-key.kmw-key-default[id$='U_135E'], .tablet div.kmw-key.kmw-key-default[id$='U_135E'],\n .phone div.kmw-key.kmw-key-default[id$='U_135F'], .tablet div.kmw-key.kmw-key-default[id$='U_135F']\n {background: #E2EADA ; color: black ; }\n ";this.s15="ሀሁሂሃሄህሆሇለሉሊላሌልሎሏሐሑሒሓሔሕሖሗመሙሚማሜምሞሟሠሡሢሣሤሥሦሧረሩሪራሬርሮሯሰሱሲሳሴስሶሷሸሹሺሻሼሽሾሿቀቁቂቃቄቅቆቇቈ቉ቊቋቌቍ቎቏ቐቑቒቓቔቕቖ቗ቘ቙ቚቛቜቝ቞቟በቡቢባቤብቦቧቨቩቪቫቬቭቮቯተቱቲታቴትቶቷቸቹቺቻቼችቾቿኀኁኂኃኄኅኆኇኈ኉ኊኋኌኍ኎኏ነኑኒናኔንኖኗኘኙኚኛኜኝኞኟአኡኢኣኤእኦኧከኩኪካኬክኮኯኰ኱ኲኳኴኵ኶኷ኸኹኺኻኼኽኾ኿ዀ዁ዂዃዄዅ዆዇ወዉዊዋዌውዎዏዐዑዒዓዔዕዖ዗ዘዙዚዛዜዝዞዟዠዡዢዣዤዥዦዧየዩዪያዬይዮዯደዱዲዳዴድዶዷዸዹዺዻዼዽዾዿጀጁጂጃጄጅጆጇገጉጊጋጌግጎጏጐ጑ጒጓጔጕ጖጗ጘጙጚጛጜጝጞጟጠጡጢጣጤጥጦጧጨጩጪጫጬጭጮጯጰጱጲጳጴጵጶጷጸጹጺጻጼጽጾጿፀፁፂፃፄፅፆፇፈፉፊፋፌፍፎፏፐፑፒፓፔፕፖፗፘፙፚ፛፜፝፞፟፠፡።፣፤፥፦፧፨፩፪፫፬፭፮፯፰፱፲፳፴፵፶፷፸፹፺፻፼፽፾፿ᎀᎁᎂᎃᎄᎅᎆᎇᎈᎉᎊᎋᎌᎍᎎᎏ᎐᎑᎒᎓᎔᎕᎖᎗᎘᎙ⶀⶁⶂⶃⶄⶅⶆⶇⶈⶉⶊⶋⶌⶍⶎⶏⶐⶑⶒⶓⶔⶕⶖ⶗⶘⶙⶚⶛⶜⶝⶞⶟ⶠⶡⶢⶣⶤⶥⶦ⶧ⶨⶩⶪⶫⶬⶭⶮ⶯ⶰⶱⶲⶳⶴⶵⶶ⶷ⶸⶹⶺⶻⶼⶽⶾ⶿ⷀⷁⷂⷃⷄⷅⷆ⷇ⷈⷉⷊⷋⷌⷍⷎ⷏ⷐⷑⷒⷓⷔⷕⷖ⷗ⷘⷙⷚⷛⷜⷝⷞꬁꬂꬃꬄꬅꬆ꬇꬈ꬉꬊꬋꬌꬍꬎ꬏꬐ꬑꬒꬓꬔꬕꬖ꬗꬘꬙꬚꬛꬜꬝꬞꬟ꬠꬡꬢꬣꬤꬥꬦ꬧ꬨꬩꬪꬫꬬꬭꬮ𞟠𞟡𞟢𞟣𞟤𞟥𞟦𞟧𞟨𞟩𞟪𞟫𞟬𞟭𞟮𞟯𞟰𞟱𞟲𞟳𞟴𞟵𞟶𞟷𞟸𞟹𞟺𞟻𞟼𞟽𞟾";this.s16="ሀለሐ𞟠መሠረሰሸቀቐበቨተቸኀነኘከኸወዐዘዠየደዸጀገጘጠጨጰጸፀፈፐ";this.s17="ሁሉሑ𞟡ሙሡሩሱሹቁቑቡቩቱቹኁኑኙኩኹዉዑዙዡዩዱዹጁጉጙጡጩጱጹፁፉፑ";this.s18="ሂሊሒ𞟢ሚሢሪሲሺቂቒቢቪቲቺኂኒኚኪኺዊዒዚዢዪዲዺጂጊጚጢጪጲጺፂፊፒ";this.s19="ሃላሓ𞟣ማሣራሳሻቃቓባቫታቻኃናኛካኻዋዓዛዣያዳዻጃጋጛጣጫጳጻፃፋፓ";this.s20="ሄሌሔ𞟤ሜሤሬሴሼቄቔቤቬቴቼኄኔኜኬኼዌዔዜዤዬዴዼጄጌጜጤጬጴጼፄፌፔ";this.s21="ህልሕ𞟥ምሥርስሽቅቕብቭትችኅንኝክኽውዕዝዥይድዽጅግጝጥጭጵጽፅፍፕ";this.s22="ሆሎሖ𞟦ሞሦሮሶሾቆቖቦቮቶቾኅኖኞኮኾዎዖዞዦዮዶዾጆጎጞጦጮጶጾፆፎፖ";this.s23="hlHmrsxqQbvtcnNkKwzZydjgTCPSfp";this.s24="ህልሕምርስሽቅቕብቭትችንኝክኽውዝዥይድጅግጥጭጵጽፍፕ";this.s25="LMRXBVWYDJGF";this.s26="ልምርሽብቭውይድጅግፍ";this.s27=['',"a","A","u","U","i","I","e","E","o","O",''];this.s28="እኣዐኡዑኢዒእዕኦዖኤ";this.s29="ኣኢዐዒ";this.s30="ልሕምሥርስሽብቭትችንኝዝዥድዽጅጥጭጵጽፍፕ";this.s31="ሉሑሙሡሩሱሹቡቩቱቹኑኙዙዡዱዹጁጡጩጱጹፉፑ";this.s32="ሏሗሟሧሯሷሿቧቯቷቿኗኟዟዧዷዿጇጧጯጷጿፏፗ";this.s33="ሁኁኩኹቁቑጉጙ";this.s34="ሃኃካኻቃቓጋጛ";this.s35="ኈኈኰዀቈቘጐⶓ";this.s36="ኍኍኵዅቍቝጕⶖ";this.s37="ኊኊኲዂቊቚጒⶔ";this.s38="ኋኋኳዃቋቛጓጟ";this.s39="ኌኌኴዄቌቜጔⶕ";this.s40="23456789";this.s41="፪፫፬፭፮፯፰፱";this.s42="፳፴፵፶፷፸፹፺";this.s43="123456789";this.s44="፩፪፫፬፭፮፯፰፱፲፳፴፵፶፷፸፹፺፻፼";this.s45="0123456789";this.s46=":,";this.s47="፡፣";this.s48="eE";this.s49="uU";this.s50="iI";this.s51="aA";this.s52="oO";this.s53=['','','','','','',''];this.s54="ሀሁሂሃሄሆኋ";this.s55="ለሉሊላሌሎሏ";this.s56="ሐሑሒሓሔሖሗ";this.s57="መሙሚማሜሞሟ";this.s58="ሠሡሢሣሤሦሧ";this.s59="ረሩሪራሬሮሯ";this.s60="ሰሱሲሳሴሶሷ";this.s61="ሸሹሺሻሼሾሿ";this.s62="ቀቁቂቃቄቆ!";this.s63="ቐቑቒቓቔቖ!";this.s64="በቡቢባቤቦቧ";this.s65="ቨቩቪቫቬቮቯ";this.s66="ተቱቲታቴቶቷ";this.s67="ቸቹቺቻቼቾቿ";this.s68="ኀኁኂኃኄኆ!";this.s69="ነኑኒናኔኖኗ";this.s70="ኘኙኚኛኜኞኟ";this.s71="አኡኢኣኤኦኧ";this.s72="ከኩኪካኬኮ!";this.s73="ኸኹኺኻኼኾ!";this.s74="ወዉዊዋዌዎ!";this.s75="ዐዑዒዓዔዖ!";this.s76="ዘዙዚዛዜዞዟ";this.s77="ዠዡዢዣዤዦዧ";this.s78="የዩዪያዬዮ!";this.s79="ደዱዲዳዴዶዷ";this.s80="ዸዹዺዻዼዾዿ";this.s81="ጀጁጂጃጄጆጇ";this.s82="ገጉጊጋጌጎ!";this.s83="ጘጙጚጛጜጞ!";this.s84="ጠጡጢጣጤጦጧ";this.s85="ጨጩጪጫጬጮጯ";this.s86="ጰጱጲጳጴጶጷ";this.s87="ጸጹጺጻጼጾጿ";this.s88="ፀፁፂፃፄፆ!";this.s89="ፈፉፊፋፌፎፏ";this.s90="ፐፑፒፓፔፖፗ";this.s91="𞟠𞟡𞟢𞟣𞟤𞟥𞟦!";this.s92=['','','','',''];this.s93="ቈቍቊቋቌ";this.s94="ቘቝቚቛቜ";this.s95="ኈኍኊኋኌ";this.s96="ኰኵኲኳኴ";this.s97="ዀዅዂዃዄ";this.s98="ጐጕጒጓጔ";this.s99="ⶓⶖⶔጟⶕ";this.s102="default";this.s103="ሀ-layer";this.s104="ሀ-layer";this.s105="ለ-layer";this.s106="ሐ-layer";this.s107="መ-layer";this.s108="ሠ-layer";this.s109="ሠ-extra";this.s110="ረ-layer";this.s111="ሰ-layer";this.s112="ሰ-layer";this.s113="ሸ-layer";this.s114="ቀ-layer";this.s115="ቐ-layer";this.s116="በ-layer";this.s117="ቨ-layer";this.s118="ቨ-extra";this.s119="ተ-layer";this.s120="ቸ-layer";this.s121="ቸ-extra";this.s122="ኀ-layer";this.s123="ኀ-extra";this.s124="ነ-layer";this.s125="ኘ-layer";this.s126="ኘ-extra";this.s127="አ-layer";this.s128="አ-layer";this.s129="ከ-layer";this.s130="ኸ-layer";this.s131="ዐ-layer";this.s132="ዐ-layer";this.s133="ዐ-layer";this.s134="ወ-layer";this.s135="ዘ-extra";this.s136="ዠ-layer";this.s137="ዠ-extra";this.s138="የ-layer";this.s139="ደ-layer";this.s140="ዸ-extra";this.s141="ጀ-layer";this.s142="ገ-layer";this.s143="ጘ-extra";this.s144="ጠ-layer";this.s145="ጨ-layer";this.s146="ጨ-extra";this.s147="ጰ-layer";this.s148="ጰ-extra";this.s149="ጸ-layer";this.s150="ጸ-layer";this.s151="ፀ-layer";this.s152="ፀ-extra";this.s153="ፈ-layer";this.s154="ፐ-layer";this.s155="𞟠-extra";this.s156="ቈ-layer";this.s157="ቘ-layer";this.s158="ኈ-extra";this.s159="ኰ-layer";this.s160="ዀ-layer";this.s161="ጐ-layer";this.s162="ⶓ-extra";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,256)) {if(k.KFCM(1,t,['እ'])&&k.KIFS(33,this.s127,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"አ");}else if(k.KFCM(1,t,['ዕ'])&&k.KIFS(33,this.s131,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐ");}else if(k.KFCM(1,t,['ዐ'])&&k.KIFS(33,this.s132,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐዐ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s16,1,t);}else if(k.KIFS(33,this.s102,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"አ");}else if(k.KIFS(33,this.s103,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሀ");}else if(k.KIFS(33,this.s105,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ለ");}else if(k.KIFS(33,this.s106,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሐ");}else if(k.KIFS(33,this.s107,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"መ");}else if(k.KIFS(33,this.s108,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሠ");}else if(k.KIFS(33,this.s109,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሠ");}else if(k.KIFS(33,this.s110,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ረ");}else if(k.KIFS(33,this.s111,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሰ");}else if(k.KIFS(33,this.s113,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሸ");}else if(k.KIFS(33,this.s114,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቀ");}else if(k.KIFS(33,this.s115,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቐ");}else if(k.KIFS(33,this.s116,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"በ");}else if(k.KIFS(33,this.s117,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቨ");}else if(k.KIFS(33,this.s118,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቨ");}else if(k.KIFS(33,this.s119,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ተ");}else if(k.KIFS(33,this.s120,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቸ");}else if(k.KIFS(33,this.s121,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቸ");}else if(k.KIFS(33,this.s122,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኀ");}else if(k.KIFS(33,this.s123,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኀ");}else if(k.KIFS(33,this.s124,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ነ");}else if(k.KIFS(33,this.s125,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኘ");}else if(k.KIFS(33,this.s126,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኘ");}else if(k.KIFS(33,this.s128,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"አ");}else if(k.KIFS(33,this.s129,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ከ");}else if(k.KIFS(33,this.s130,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኸ");}else if(k.KIFS(33,this.s133,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዐ");}else if(k.KIFS(33,this.s134,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ወ");}else if(k.KIFS(33,this.s135,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዘ");}else if(k.KIFS(33,this.s136,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዠ");}else if(k.KIFS(33,this.s137,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዠ");}else if(k.KIFS(33,this.s138,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"የ");}else if(k.KIFS(33,this.s139,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ደ");}else if(k.KIFS(33,this.s140,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዸ");}else if(k.KIFS(33,this.s141,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጀ");}else if(k.KIFS(33,this.s142,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ገ");}else if(k.KIFS(33,this.s143,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጘ");}else if(k.KIFS(33,this.s144,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጠ");}else if(k.KIFS(33,this.s145,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጨ");}else if(k.KIFS(33,this.s146,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጨ");}else if(k.KIFS(33,this.s147,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጰ");}else if(k.KIFS(33,this.s148,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጰ");}else if(k.KIFS(33,this.s149,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጸ");}else if(k.KIFS(33,this.s151,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፀ");}else if(k.KIFS(33,this.s152,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፀ");}else if(k.KIFS(33,this.s153,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፈ");}else if(k.KIFS(33,this.s154,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፐ");}else if(k.KIFS(33,this.s155,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"𞟠");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"እ");}}else if(k.KKM(e,16384,258)) {if(k.KFCM(1,t,['እ'])&&k.KIFS(33,this.s127,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኡ");}else if(k.KFCM(1,t,['ዕ'])&&k.KIFS(33,this.s131,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዑ");}else if(k.KFCM(1,t,['ዐ'])&&k.KIFS(33,this.s132,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐዑ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s17,1,t);}else if(k.KIFS(33,this.s102,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኡ");}else if(k.KIFS(33,this.s103,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሁ");}else if(k.KIFS(33,this.s105,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሉ");}else if(k.KIFS(33,this.s106,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሑ");}else if(k.KIFS(33,this.s107,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሙ");}else if(k.KIFS(33,this.s108,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሡ");}else if(k.KIFS(33,this.s109,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሡ");}else if(k.KIFS(33,this.s110,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሩ");}else if(k.KIFS(33,this.s111,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሱ");}else if(k.KIFS(33,this.s113,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሹ");}else if(k.KIFS(33,this.s114,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቁ");}else if(k.KIFS(33,this.s115,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቑ");}else if(k.KIFS(33,this.s116,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቡ");}else if(k.KIFS(33,this.s117,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቩ");}else if(k.KIFS(33,this.s118,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቩ");}else if(k.KIFS(33,this.s119,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቱ");}else if(k.KIFS(33,this.s120,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቹ");}else if(k.KIFS(33,this.s121,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቹ");}else if(k.KIFS(33,this.s122,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኁ");}else if(k.KIFS(33,this.s123,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኁ");}else if(k.KIFS(33,this.s124,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኑ");}else if(k.KIFS(33,this.s125,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኙ");}else if(k.KIFS(33,this.s126,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኙ");}else if(k.KIFS(33,this.s128,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኡ");}else if(k.KIFS(33,this.s129,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኩ");}else if(k.KIFS(33,this.s130,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኹ");}else if(k.KIFS(33,this.s133,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዑ");}else if(k.KIFS(33,this.s134,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዉ");}else if(k.KIFS(33,this.s135,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዙ");}else if(k.KIFS(33,this.s136,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዡ");}else if(k.KIFS(33,this.s137,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዡ");}else if(k.KIFS(33,this.s138,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዩ");}else if(k.KIFS(33,this.s139,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዱ");}else if(k.KIFS(33,this.s140,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዹ");}else if(k.KIFS(33,this.s141,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጁ");}else if(k.KIFS(33,this.s142,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጉ");}else if(k.KIFS(33,this.s143,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጙ");}else if(k.KIFS(33,this.s144,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጡ");}else if(k.KIFS(33,this.s145,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጩ");}else if(k.KIFS(33,this.s146,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጩ");}else if(k.KIFS(33,this.s147,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጱ");}else if(k.KIFS(33,this.s148,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጱ");}else if(k.KIFS(33,this.s149,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጹ");}else if(k.KIFS(33,this.s151,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፁ");}else if(k.KIFS(33,this.s152,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፁ");}else if(k.KIFS(33,this.s153,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፉ");}else if(k.KIFS(33,this.s154,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፑ");}else if(k.KIFS(33,this.s155,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"𞟡");}}else if(k.KKM(e,16384,259)) {if(k.KFCM(1,t,['እ'])&&k.KIFS(33,this.s127,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኢ");}else if(k.KFCM(1,t,['ዕ'])&&k.KIFS(33,this.s131,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዒ");}else if(k.KFCM(1,t,['ዐ'])&&k.KIFS(33,this.s132,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐዒ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s18,1,t);}else if(k.KIFS(33,this.s102,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኢ");}else if(k.KIFS(33,this.s103,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሂ");}else if(k.KIFS(33,this.s105,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሊ");}else if(k.KIFS(33,this.s106,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሒ");}else if(k.KIFS(33,this.s107,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሚ");}else if(k.KIFS(33,this.s108,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሢ");}else if(k.KIFS(33,this.s109,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሢ");}else if(k.KIFS(33,this.s110,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሪ");}else if(k.KIFS(33,this.s111,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሲ");}else if(k.KIFS(33,this.s113,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሺ");}else if(k.KIFS(33,this.s114,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቂ");}else if(k.KIFS(33,this.s115,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቒ");}else if(k.KIFS(33,this.s116,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቢ");}else if(k.KIFS(33,this.s117,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቪ");}else if(k.KIFS(33,this.s118,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቪ");}else if(k.KIFS(33,this.s119,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቲ");}else if(k.KIFS(33,this.s120,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቺ");}else if(k.KIFS(33,this.s121,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቺ");}else if(k.KIFS(33,this.s122,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኂ");}else if(k.KIFS(33,this.s123,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኂ");}else if(k.KIFS(33,this.s124,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኒ");}else if(k.KIFS(33,this.s125,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኚ");}else if(k.KIFS(33,this.s126,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኚ");}else if(k.KIFS(33,this.s128,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኢ");}else if(k.KIFS(33,this.s129,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኪ");}else if(k.KIFS(33,this.s130,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኺ");}else if(k.KIFS(33,this.s133,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዒ");}else if(k.KIFS(33,this.s134,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዊ");}else if(k.KIFS(33,this.s135,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዚ");}else if(k.KIFS(33,this.s136,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዢ");}else if(k.KIFS(33,this.s137,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዢ");}else if(k.KIFS(33,this.s138,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዪ");}else if(k.KIFS(33,this.s139,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዲ");}else if(k.KIFS(33,this.s140,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዺ");}else if(k.KIFS(33,this.s141,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጂ");}else if(k.KIFS(33,this.s142,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጊ");}else if(k.KIFS(33,this.s143,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጚ");}else if(k.KIFS(33,this.s144,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጢ");}else if(k.KIFS(33,this.s145,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጪ");}else if(k.KIFS(33,this.s146,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጪ");}else if(k.KIFS(33,this.s147,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጲ");}else if(k.KIFS(33,this.s148,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጲ");}else if(k.KIFS(33,this.s149,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጺ");}else if(k.KIFS(33,this.s151,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፂ");}else if(k.KIFS(33,this.s152,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፂ");}else if(k.KIFS(33,this.s153,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፊ");}else if(k.KIFS(33,this.s154,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፒ");}else if(k.KIFS(33,this.s155,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"𞟢");}}else if(k.KKM(e,16384,260)) {if(k.KFCM(1,t,['እ'])&&k.KIFS(33,this.s127,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኣ");}else if(k.KFCM(1,t,['ዕ'])&&k.KIFS(33,this.s131,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዓ");}else if(k.KFCM(1,t,['ዐ'])&&k.KIFS(33,this.s132,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐዓ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s19,1,t);}else if(k.KIFS(33,this.s102,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኣ");}else if(k.KIFS(33,this.s103,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሃ");}else if(k.KIFS(33,this.s105,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ላ");}else if(k.KIFS(33,this.s106,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሓ");}else if(k.KIFS(33,this.s107,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ማ");}else if(k.KIFS(33,this.s108,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሣ");}else if(k.KIFS(33,this.s109,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሣ");}else if(k.KIFS(33,this.s110,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ራ");}else if(k.KIFS(33,this.s111,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሳ");}else if(k.KIFS(33,this.s113,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሻ");}else if(k.KIFS(33,this.s114,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቃ");}else if(k.KIFS(33,this.s115,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቓ");}else if(k.KIFS(33,this.s116,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ባ");}else if(k.KIFS(33,this.s117,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቫ");}else if(k.KIFS(33,this.s118,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቫ");}else if(k.KIFS(33,this.s119,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ታ");}else if(k.KIFS(33,this.s120,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቻ");}else if(k.KIFS(33,this.s121,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቻ");}else if(k.KIFS(33,this.s122,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኃ");}else if(k.KIFS(33,this.s123,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኃ");}else if(k.KIFS(33,this.s124,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ና");}else if(k.KIFS(33,this.s125,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኛ");}else if(k.KIFS(33,this.s126,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኛ");}else if(k.KIFS(33,this.s128,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኣ");}else if(k.KIFS(33,this.s129,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ካ");}else if(k.KIFS(33,this.s130,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኻ");}else if(k.KIFS(33,this.s133,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዓ");}else if(k.KIFS(33,this.s134,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዋ");}else if(k.KIFS(33,this.s135,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዛ");}else if(k.KIFS(33,this.s136,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዣ");}else if(k.KIFS(33,this.s137,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዣ");}else if(k.KIFS(33,this.s138,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ያ");}else if(k.KIFS(33,this.s139,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዳ");}else if(k.KIFS(33,this.s140,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዻ");}else if(k.KIFS(33,this.s141,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጃ");}else if(k.KIFS(33,this.s142,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጋ");}else if(k.KIFS(33,this.s143,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጛ");}else if(k.KIFS(33,this.s144,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጣ");}else if(k.KIFS(33,this.s145,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጫ");}else if(k.KIFS(33,this.s146,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጫ");}else if(k.KIFS(33,this.s147,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጳ");}else if(k.KIFS(33,this.s148,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጳ");}else if(k.KIFS(33,this.s149,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጻ");}else if(k.KIFS(33,this.s151,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፃ");}else if(k.KIFS(33,this.s152,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፃ");}else if(k.KIFS(33,this.s153,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፋ");}else if(k.KIFS(33,this.s154,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፓ");}else if(k.KIFS(33,this.s155,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"𞟣");}}else if(k.KKM(e,16384,257)) {if(k.KFCM(1,t,['እ'])&&k.KIFS(33,this.s127,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኤ");}else if(k.KFCM(1,t,['ዕ'])&&k.KIFS(33,this.s131,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዔ");}else if(k.KFCM(1,t,['ዐ'])&&k.KIFS(33,this.s132,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐዔ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s20,1,t);}else if(k.KIFS(33,this.s102,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኤ");}else if(k.KIFS(33,this.s103,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሄ");}else if(k.KIFS(33,this.s105,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሌ");}else if(k.KIFS(33,this.s106,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሔ");}else if(k.KIFS(33,this.s107,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሜ");}else if(k.KIFS(33,this.s108,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሤ");}else if(k.KIFS(33,this.s109,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሤ");}else if(k.KIFS(33,this.s110,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሬ");}else if(k.KIFS(33,this.s111,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሴ");}else if(k.KIFS(33,this.s113,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሼ");}else if(k.KIFS(33,this.s114,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቄ");}else if(k.KIFS(33,this.s115,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቔ");}else if(k.KIFS(33,this.s116,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቤ");}else if(k.KIFS(33,this.s117,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቬ");}else if(k.KIFS(33,this.s118,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቬ");}else if(k.KIFS(33,this.s119,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቴ");}else if(k.KIFS(33,this.s120,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቼ");}else if(k.KIFS(33,this.s121,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቼ");}else if(k.KIFS(33,this.s122,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኄ");}else if(k.KIFS(33,this.s123,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኄ");}else if(k.KIFS(33,this.s124,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኔ");}else if(k.KIFS(33,this.s125,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኜ");}else if(k.KIFS(33,this.s126,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኜ");}else if(k.KIFS(33,this.s128,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኤ");}else if(k.KIFS(33,this.s129,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኬ");}else if(k.KIFS(33,this.s130,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኼ");}else if(k.KIFS(33,this.s133,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዔ");}else if(k.KIFS(33,this.s134,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዌ");}else if(k.KIFS(33,this.s135,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዜ");}else if(k.KIFS(33,this.s136,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዤ");}else if(k.KIFS(33,this.s137,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዤ");}else if(k.KIFS(33,this.s138,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዬ");}else if(k.KIFS(33,this.s139,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዴ");}else if(k.KIFS(33,this.s140,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዼ");}else if(k.KIFS(33,this.s141,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጄ");}else if(k.KIFS(33,this.s142,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጌ");}else if(k.KIFS(33,this.s143,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጜ");}else if(k.KIFS(33,this.s144,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጤ");}else if(k.KIFS(33,this.s145,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጬ");}else if(k.KIFS(33,this.s146,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጬ");}else if(k.KIFS(33,this.s147,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጴ");}else if(k.KIFS(33,this.s148,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጴ");}else if(k.KIFS(33,this.s149,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጼ");}else if(k.KIFS(33,this.s151,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፄ");}else if(k.KIFS(33,this.s152,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፄ");}else if(k.KIFS(33,this.s153,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፌ");}else if(k.KIFS(33,this.s154,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፔ");}else if(k.KIFS(33,this.s155,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"𞟤");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኤ");}}else if(k.KKM(e,16384,261)) {if(k.KFCM(1,t,['እ'])&&k.KIFS(33,this.s127,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኦ");}else if(k.KFCM(1,t,['ዕ'])&&k.KIFS(33,this.s131,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዖ");}else if(k.KFCM(1,t,['ዐ'])&&k.KIFS(33,this.s132,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐዖ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s22,1,t);}else if(k.KIFS(33,this.s102,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኦ");}else if(k.KIFS(33,this.s103,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሆ");}else if(k.KIFS(33,this.s105,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሎ");}else if(k.KIFS(33,this.s106,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሖ");}else if(k.KIFS(33,this.s107,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሞ");}else if(k.KIFS(33,this.s108,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሦ");}else if(k.KIFS(33,this.s109,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሦ");}else if(k.KIFS(33,this.s110,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሮ");}else if(k.KIFS(33,this.s111,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሶ");}else if(k.KIFS(33,this.s113,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሾ");}else if(k.KIFS(33,this.s114,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቆ");}else if(k.KIFS(33,this.s115,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቖ");}else if(k.KIFS(33,this.s116,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቦ");}else if(k.KIFS(33,this.s117,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቮ");}else if(k.KIFS(33,this.s118,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቮ");}else if(k.KIFS(33,this.s119,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቶ");}else if(k.KIFS(33,this.s120,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቾ");}else if(k.KIFS(33,this.s121,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቾ");}else if(k.KIFS(33,this.s122,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኆ");}else if(k.KIFS(33,this.s123,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኆ");}else if(k.KIFS(33,this.s124,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኖ");}else if(k.KIFS(33,this.s125,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኞ");}else if(k.KIFS(33,this.s126,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኞ");}else if(k.KIFS(33,this.s128,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኦ");}else if(k.KIFS(33,this.s129,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኮ");}else if(k.KIFS(33,this.s130,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኾ");}else if(k.KIFS(33,this.s133,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዖ");}else if(k.KIFS(33,this.s134,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዎ");}else if(k.KIFS(33,this.s135,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዞ");}else if(k.KIFS(33,this.s136,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዦ");}else if(k.KIFS(33,this.s137,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዦ");}else if(k.KIFS(33,this.s138,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዮ");}else if(k.KIFS(33,this.s139,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዶ");}else if(k.KIFS(33,this.s140,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዾ");}else if(k.KIFS(33,this.s141,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጆ");}else if(k.KIFS(33,this.s142,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጎ");}else if(k.KIFS(33,this.s143,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጞ");}else if(k.KIFS(33,this.s144,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጦ");}else if(k.KIFS(33,this.s145,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጮ");}else if(k.KIFS(33,this.s146,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጮ");}else if(k.KIFS(33,this.s147,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጶ");}else if(k.KIFS(33,this.s148,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጶ");}else if(k.KIFS(33,this.s149,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጾ");}else if(k.KIFS(33,this.s151,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፆ");}else if(k.KIFS(33,this.s152,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፆ");}else if(k.KIFS(33,this.s153,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፎ");}else if(k.KIFS(33,this.s154,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፖ");}else if(k.KIFS(33,this.s155,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"𞟥");}}else if(k.KKM(e,16384,262)) {if(k.KFCM(1,t,['እ'])&&k.KIFS(33,this.s127,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኧ");}else if(k.KFCM(1,t,['ዕ'])&&k.KIFS(33,this.s131,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"!");}else if(k.KFCM(1,t,['ዐ'])&&k.KIFS(33,this.s132,t)){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዐ!");}else if(k.KFCM(1,t,[{t:'a',a:this.s30}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s32,1,t);}else if(k.KIFS(33,this.s102,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኧ");}else if(k.KIFS(33,this.s103,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኋ");}else if(k.KIFS(33,this.s105,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሏ");}else if(k.KIFS(33,this.s106,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሗ");}else if(k.KIFS(33,this.s107,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሟ");}else if(k.KIFS(33,this.s108,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሧ");}else if(k.KIFS(33,this.s109,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሧ");}else if(k.KIFS(33,this.s110,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሯ");}else if(k.KIFS(33,this.s111,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሷ");}else if(k.KIFS(33,this.s113,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሿ");}else if(k.KIFS(33,this.s114,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s115,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s116,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቧ");}else if(k.KIFS(33,this.s117,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቯ");}else if(k.KIFS(33,this.s118,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቯ");}else if(k.KIFS(33,this.s119,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቷ");}else if(k.KIFS(33,this.s120,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቿ");}else if(k.KIFS(33,this.s121,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቿ");}else if(k.KIFS(33,this.s122,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s123,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s124,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኗ");}else if(k.KIFS(33,this.s125,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኟ");}else if(k.KIFS(33,this.s126,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኟ");}else if(k.KIFS(33,this.s128,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኧ");}else if(k.KIFS(33,this.s129,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s130,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s133,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s134,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s135,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዟ");}else if(k.KIFS(33,this.s136,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዧ");}else if(k.KIFS(33,this.s137,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዧ");}else if(k.KIFS(33,this.s138,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s139,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዷ");}else if(k.KIFS(33,this.s140,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዿ");}else if(k.KIFS(33,this.s141,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጇ");}else if(k.KIFS(33,this.s142,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s143,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s144,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጧ");}else if(k.KIFS(33,this.s145,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጯ");}else if(k.KIFS(33,this.s146,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጯ");}else if(k.KIFS(33,this.s147,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጷ");}else if(k.KIFS(33,this.s148,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጷ");}else if(k.KIFS(33,this.s149,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጿ");}else if(k.KIFS(33,this.s151,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s152,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}else if(k.KIFS(33,this.s153,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፏ");}else if(k.KIFS(33,this.s154,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፗ");}else if(k.KIFS(33,this.s155,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"𞟦");}}else if(k.KKM(e,16384,268)) {if(k.KFCM(1,t,['፞'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፟");}else if(k.KFCM(1,t,['፟'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፝");}else if(k.KFCM(1,t,['፝'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፝");k.KB(t);}}else if(k.KKM(e,16384,269)) {if(k.KFCM(1,t,['፞'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፝");}else if(k.KFCM(1,t,['፟'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፟");k.KB(t);}else if(k.KFCM(1,t,['፝'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፝");k.KB(t);}}else if(k.KKM(e,16384,270)) {if(k.KFCM(1,t,['፞'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፞");k.KB(t);}else if(k.KFCM(1,t,['፟'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፟");k.KB(t);}else if(k.KFCM(1,t,['፝'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፝");k.KB(t);}}else if(k.KKM(e,16384,263)) {if(k.KFCM(1,t,[{t:'a',a:this.s34}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s35,1,t);}else if(k.KIFS(33,this.s156,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቈ");}else if(k.KIFS(33,this.s157,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቘ");}else if(k.KIFS(33,this.s158,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኈ");}else if(k.KIFS(33,this.s159,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኰ");}else if(k.KIFS(33,this.s160,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዀ");}else if(k.KIFS(33,this.s161,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጐ");}else if(k.KIFS(33,this.s162,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ⶓ");}}else if(k.KKM(e,16384,265)) {if(k.KFCM(1,t,[{t:'a',a:this.s34}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s37,1,t);}else if(k.KIFS(33,this.s156,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቊ");}else if(k.KIFS(33,this.s157,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቚ");}else if(k.KIFS(33,this.s158,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኊ");}else if(k.KIFS(33,this.s159,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኲ");}else if(k.KIFS(33,this.s160,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዂ");}else if(k.KIFS(33,this.s161,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጒ");}else if(k.KIFS(33,this.s162,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ⶔ");}}else if(k.KKM(e,16384,266)) {if(k.KFCM(1,t,[{t:'a',a:this.s34}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s38,1,t);}else if(k.KIFS(33,this.s156,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቋ");}else if(k.KIFS(33,this.s157,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቛ");}else if(k.KIFS(33,this.s158,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኋ");}else if(k.KIFS(33,this.s159,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኳ");}else if(k.KIFS(33,this.s160,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዃ");}else if(k.KIFS(33,this.s161,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጓ");}else if(k.KIFS(33,this.s162,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጟ");}}else if(k.KKM(e,16384,267)) {if(k.KFCM(1,t,[{t:'a',a:this.s34}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s39,1,t);}else if(k.KIFS(33,this.s156,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቌ");}else if(k.KIFS(33,this.s157,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቜ");}else if(k.KIFS(33,this.s158,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኌ");}else if(k.KIFS(33,this.s159,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኴ");}else if(k.KIFS(33,this.s160,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዄ");}else if(k.KIFS(33,this.s161,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጔ");}else if(k.KIFS(33,this.s162,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ⶕ");}}else if(k.KKM(e,16384,264)) {if(k.KFCM(1,t,[{t:'a',a:this.s34}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s36,1,t);}else if(k.KIFS(33,this.s156,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቍ");}else if(k.KIFS(33,this.s157,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቝ");}else if(k.KIFS(33,this.s158,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኍ");}else if(k.KIFS(33,this.s159,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኵ");}else if(k.KIFS(33,this.s160,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዅ");}else if(k.KIFS(33,this.s161,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጕ");}else if(k.KIFS(33,this.s162,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ⶖ");}}else if(k.KKM(e,16384,271)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"፲፻");}}else if(k.KKM(e,16384,272)) {if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,1);}}else if(k.KKM(e,16384,32)) {if(k.KFCM(2,t,[{t:'a',a:this.s45},':'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KO(-1,t,"፡ ");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},'.'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KO(-1,t,"። ");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},','])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KO(-1,t,"፣ ");}}else if(k.KKM(e,16400,51)) {if(k.KFCM(1,t,['፡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፨");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"#");}}else if(k.KKM(e,16384,222)) {if(k.KFCM(1,t,[{t:'a',a:this.s29}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s29,1,t);k.KDO(-1,t,0);}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s21,1,t);k.KDO(-1,t,1);}else if(k.KFCM(1,t,[{t:'a',a:this.s31}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s31,1,t);k.KDO(-1,t,1);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s33,1,t);k.KDO(-1,t,1);}else if(k.KFCM(1,t,[{t:'a',a:this.s37}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s37,1,t);k.KDO(-1,t,1);}else if(k.KFCM(1,t,[{t:'a',a:this.s18}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s18,1,t);k.KDO(-1,t,1);}}else if(k.KKM(e,16400,187)) {if(k.KFCM(1,t,['፡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፠");}}else if(k.KKM(e,16384,188)) {if(k.KFCM(1,t,[{t:'a',a:this.s45}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s45,1,t);k.KO(-1,t,",");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፥");}else if(k.KFCM(1,t,['፥'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",");}else if(k.KFCM(1,t,[','])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፣");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"፣");}}else if(k.KKM(e,16384,189)) {if(k.KFCM(1,t,['፡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፦");}}else if(k.KKM(e,16384,190)) {if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"።");}}else if(k.KKM(e,16384,48)) {if(k.KFCM(3,t,['፲','፻','፼'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"፼፼");}else if(k.KFCM(3,t,[{t:'a',a:this.s41},'፻','፼'])){r=m=1;k.KDC(3,t);k.KIO(-1,this.s42,1,t);k.KO(-1,t,"፻፼");}else if(k.KFCM(3,t,[{t:'a',a:this.s42},'፻','፼'])){r=m=1;k.KDC(3,t);k.KIO(-1,this.s41,1,t);k.KO(-1,t,"፼፼");}else if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣0");}else if(k.KFCM(2,t,['፲','፻'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"፼");}else if(k.KFCM(2,t,['፲','፼'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"፻፼");}else if(k.KFCM(2,t,['፻','፼'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"፲፻፼");}else if(k.KFCM(2,t,['፼','፼'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"፼፼");k.KB(t);}else if(k.KFCM(2,t,[{t:'a',a:this.s41},'፻'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s42,1,t);k.KO(-1,t,"፻");}else if(k.KFCM(2,t,[{t:'a',a:this.s42},'፻'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s41,1,t);k.KO(-1,t,"፼");}else if(k.KFCM(2,t,[{t:'a',a:this.s41},'፼'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s42,1,t);k.KO(-1,t,"፼");}else if(k.KFCM(2,t,[{t:'a',a:this.s42},'፼'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s41,1,t);k.KO(-1,t,"፻፼");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".0");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",0");}else if(k.KFCM(1,t,['፩'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፲");}else if(k.KFCM(1,t,['፲'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፻");}else if(k.KFCM(1,t,['፻'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፲፻");}else if(k.KFCM(1,t,['፼'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፲፼");}else if(k.KFCM(1,t,[{t:'a',a:this.s41}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s42,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s42}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s41,1,t);k.KO(-1,t,"፻");}}else if(k.KKM(e,16384,49)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣1");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"1");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".1");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",1");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፩");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፩");}}else if(k.KKM(e,16384,50)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣2");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"2");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".2");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",2");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፪");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፪");}}else if(k.KKM(e,16384,51)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣3");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"3");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".3");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",3");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፫");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፫");}}else if(k.KKM(e,16384,52)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣4");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"4");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".4");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",4");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፬");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፬");}}else if(k.KKM(e,16384,53)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣5");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"5");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".5");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",5");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፭");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፭");}}else if(k.KKM(e,16384,54)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣6");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"6");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".6");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",6");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፮");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፮");}}else if(k.KKM(e,16384,55)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣7");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"7");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".7");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",7");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፯");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፯");}}else if(k.KKM(e,16384,56)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣8");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"8");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".8");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",8");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፰");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፰");}}else if(k.KKM(e,16384,57)) {if(k.KFCM(2,t,[{t:'a',a:this.s45,n:1},'፣'])){r=m=1;k.KDC(2,t);k.KCXO(-1,t,2,1);k.KO(-1,t,"፣9");}else if(k.KFCM(2,t,[{t:'a',a:this.s45},{t:'a',a:this.s47}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s45,1,t);k.KIO(-1,this.s46,2,t);k.KO(-1,t,"9");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,".9");}else if(k.KFCM(1,t,['፣'])){r=m=1;k.KDC(1,t);k.KO(-1,t,",9");}else if(k.KFCM(1,t,['#'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፱");}else if(k.KFCM(1,t,[{t:'a',a:this.s44}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s44,1,t);k.KO(-1,t,"፱");}}else if(k.KKM(e,16400,186)) {if(k.KFCM(1,t,[{t:'a',a:this.s45}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s45,1,t);k.KO(-1,t,":");}else if(k.KFCM(1,t,['፡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"።");}else if(k.KFCM(1,t,['።'])){r=m=1;k.KDC(1,t);k.KO(-1,t,":");}else if(k.KFCM(1,t,[':'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፡");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"፡");}}else if(k.KKM(e,16384,186)) {if(k.KFCM(1,t,['፤'])){r=m=1;k.KDC(1,t);k.KO(-1,t,";");}else if(k.KFCM(1,t,[';'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፤");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"፤");}}else if(k.KKM(e,16400,188)) {if(k.KFCM(1,t,['‹'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"«");}else if(k.KFCM(1,t,['«'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"<");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‹");}}else if(k.KKM(e,16400,190)) {if(k.KFCM(1,t,['›'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"»");}else if(k.KFCM(1,t,['»'])){r=m=1;k.KDC(1,t);k.KO(-1,t,">");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"›");}}else if(k.KKM(e,16400,191)) {if(k.KFCM(1,t,['?'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"፧");}}else if(k.KKM(e,16400,65)) {if(k.KFCM(1,t,['ኣ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"አ");}else if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዓ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s19,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s31}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s32,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s38,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዐ");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ብ");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጭ");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ድ");}}else if(k.KKM(e,16400,69)) {if(k.KFCM(1,t,['እ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኧ");}else if(k.KFCM(1,t,['ኢ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኤ");}else if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዕ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s16,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s18}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s20,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s35,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s37}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s39,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዕ");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፍ");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ግ");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሕ");}}else if(k.KKM(e,16400,73)) {if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዒ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s18,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s37,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዒ");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጅ");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኽ");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ል");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ም");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኝ");}}else if(k.KKM(e,16400,79)) {if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዖ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s22,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዖ");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጵ");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቕ");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ር");}}else if(k.KKM(e,16400,83)) {if(k.KIFS(33,this.s150,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጽ");}else if(k.KFCM(1,t,['ጽ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ፅ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጽ");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጥ");}}else if(k.KKM(e,16400,85)) {if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዑ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s17,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s36,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዑ");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቭ");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ው");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሽ");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ይ");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዥ");}}else if(k.KKM(e,16384,65)) {if(k.KFCM(1,t,['ኣ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"አ");}else if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዓ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s19,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s31}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s32,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s38,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኣ");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ብ");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ች");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ድ");}}else if(k.KKM(e,16384,69)) {if(k.KFCM(1,t,['እ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኧ");}else if(k.KFCM(1,t,['ኢ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኤ");}else if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዕ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s16,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s18}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s20,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s35,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s37}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s39,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"እ");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፍ");}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ግ");}}else if(k.KKM(e,16384,72)) {if(k.KIFS(33,this.s104,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ህ");}else if(k.KFCM(1,t,['ህ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኅ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ህ");}}else if(k.KKM(e,16384,73)) {if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዒ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s18,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s37,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኢ");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ጅ");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ክ");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ል");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ም");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ን");}}else if(k.KKM(e,16384,79)) {if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዖ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s22,1,t);}else if(k.KFCM(1,t,['ኮ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኰ");}else if(k.KFCM(1,t,['ጎ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ጐ");}else if(k.KFCM(1,t,['ኰ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ኮ");}else if(k.KFCM(1,t,['ጐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ጎ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኦ");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ፕ");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቅ");}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ር");}}else if(k.KKM(e,16384,83)) {if(k.KIFS(33,this.s112,t)){r=m=1;k.KDC(0,t);k.KO(-1,t,"ስ");}else if(k.KFCM(1,t,['ስ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ሥ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ስ");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ት");}}else if(k.KKM(e,16384,85)) {if(k.KFCM(1,t,['ዐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ዑ");}else if(k.KFCM(1,t,[{t:'a',a:this.s21}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s17,1,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s33}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s36,1,t);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ኡ");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ቭ");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ው");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ሽ");}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ይ");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ዝ");}}return r;};} \ No newline at end of file diff --git a/keyboard/gondi_gunjala/1.1.2/gondi_gunjala-1.1.2.js b/keyboard/gondi_gunjala/1.1.2/gondi_gunjala-1.1.2.js new file mode 100644 index 000000000..3df41ebd0 --- /dev/null +++ b/keyboard/gondi_gunjala/1.1.2/gondi_gunjala-1.1.2.js @@ -0,0 +1 @@ +KeymanWeb.KR(new Keyboard_gondi_gunjala());function Keyboard_gondi_gunjala(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_gondi_gunjala";this.KN="Gondi Gunjala";this.KMINVER="9.0";this.KV={F:' 1em "Narnoor Regular"',K102:0};this.KV.KLS={"shift": ["~","!","@","#","$","%","^","&","*","(",")","_","+","","","","𑵴","𑶄","𑵧","","𑵾","𑵨","𑵥","𑵣","𑵪","𑶆","𑵹","]","|","","","","𑵡","","𑶃","","𑵷","𑶖","𑶁","𑵲","𑵿",":","\"","","","","","","","","","𑵼","𑵫","𑵯","𑶄","𑶕","‘","’","?","","","","","",""],"default": ["`","𑶡","𑶢","𑶣","𑶤","𑶥","𑶦","𑶧","𑶨","𑶩","𑶠","-","=","","","","𑵳","","𑵧","𑶈","𑵽","𑵬","𑵤","𑵢","𑵪","𑶅","𑵸","[","\\","","","","𑵠","𑶉","𑶂","","𑵶","𑶇","𑶀","𑵱","𑵵",";","'","","","","","","","","𑶗","𑵻","𑵭","𑵮","𑵺","𑵰",",",".","/","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=1;this.KH="Gondi Gunjala keyboard";this.KM=0;this.KBVER="1.1.2";this.KMBM=0x0010;this.KS=1;this.KVKD="T_0 T_1 T_2 T_3 T_4 T_5 T_6 T_7 T_8 T_9 T_GMAIL T_YAHOO";this.KVKL={"tablet":{"font":"Narnoor Regular","fontsize":"1.3em","displayUnderlying":true,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_A","text":"\uD807\uDD60"},{"layer":"shift","id":"K_A","text":"\uD807\uDD61"},{"id":"K_I","text":"\uD807\uDD62"},{"layer":"shift","id":"K_I","text":"\uD807\uDD63"},{"id":"K_U","text":"\uD807\uDD64"},{"layer":"shift","id":"K_U","text":"\uD807\uDD65"},{"id":"K_E","text":"\uD807\uDD67"},{"layer":"shift","width":"90","id":"K_Y","text":"\uD807\uDD68"},{"id":"K_O","text":"\uD807\uDD6A"},{"layer":"shift","width":"90","id":"K_V","text":"\uD807\uDD6B"},{"layer":"shift","width":"60","id":"K_M","text":"\uD807\uDD95"},{"width":"60","id":"K_X","text":"\uD807\uDD97"}]},{"id":"2","key":[{"id":"K_K","pad":"40","text":"\uD807\uDD71"},{"id":"K_G","text":"\uD807\uDD76"},{"layer":"shift","id":"K_N","text":"\uD807\uDD84"},{"id":"K_C","text":"\uD807\uDD7B"},{"id":"K_J","text":"\uD807\uDD80"},{"id":"K_T","text":"\uD807\uDD7D"},{"id":"K_D","text":"\uD807\uDD82"},{"id":"K_Q","text":"\uD807\uDD73"},{"id":"K_LBRKT","text":"\uD807\uDD78"},{"id":"K_N","text":"\uD807\uDD7A"},{"width":"65","id":"U_200C","text":"\u21CE"}]},{"id":"3","key":[{"nextlayer":"numeric","width":"110","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"id":"K_P","text":"\uD807\uDD85"},{"id":"K_B","text":"\uD807\uDD6E"},{"id":"K_M","text":"\uD807\uDD70"},{"id":"K_Y","text":"\uD807\uDD6C"},{"id":"K_R","text":"\uD807\uDD88"},{"id":"K_L","text":"\uD807\uDD75"},{"id":"K_V","text":"\uD807\uDD6D"},{"id":"K_S","text":"\uD807\uDD89"},{"id":"K_H","text":"\uD807\uDD87"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"shift","width":"140","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"525","id":"K_SPACE"},{"id":"K_PERIOD","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_003B","text":";"},{"id":"U_005C","text":"\\"}]},{"layer":"shift","id":"K_SLASH","text":"?","sk":[{"id":"U_201C","text":"\u201C"},{"id":"U_2018","text":"\u2018"},{"id":"U_2019","text":"\u2019"},{"id":"U_201D","text":"\u201D"},{"layer":"shift","id":"K_1","text":"!"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""}]},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"layer":"default","id":"K_A","text":"\uD807\uDD60"},{"id":"K_A","text":"\uD807\uDD61"},{"layer":"default","id":"K_I","text":"\uD807\uDD62"},{"id":"K_I","text":"\uD807\uDD63"},{"layer":"default","id":"K_U","text":"\uD807\uDD64"},{"id":"K_U","text":"\uD807\uDD65"},{"layer":"default","id":"K_E","text":"\uD807\uDD67"},{"width":"90","id":"K_Y","text":"\uD807\uDD68"},{"layer":"default","id":"K_O","text":"\uD807\uDD6A"},{"width":"90","id":"K_V","text":"\uD807\uDD6B"},{"width":"60","id":"K_M","text":"\uD807\uDD95"},{"layer":"default","width":"60","id":"K_X","text":"\uD807\uDD97"}]},{"id":"2","key":[{"id":"K_K","pad":"40","text":"\uD807\uDD72"},{"id":"K_G","text":"\uD807\uDD77"},{"id":"K_N","text":"\uD807\uDD84"},{"id":"K_C","text":"\uD807\uDD7C"},{"id":"K_J","text":"\uD807\uDD81"},{"id":"K_T","text":"\uD807\uDD7E"},{"id":"K_D","text":"\uD807\uDD83"},{"id":"K_Q","text":"\uD807\uDD74"},{"id":"K_LBRKT","text":"\uD807\uDD79"},{"layer":"default","id":"K_N","text":"\uD807\uDD7A"},{"width":"65","id":"U_200D","text":"\u21D4"}]},{"id":"3","key":[{"nextlayer":"numeric","width":"110","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"id":"K_P","text":"\uD807\uDD86"},{"id":"K_B","text":"\uD807\uDD6F"},{"id":"K_M","text":"\uD807\uDD95"},{"layer":"default","id":"K_Y","text":"\uD807\uDD6C"},{"layer":"default","id":"K_R","text":"\uD807\uDD88"},{"id":"K_L","text":"\uD807\uDD7F"},{"layer":"default","id":"K_V","text":"\uD807\uDD6D"},{"layer":"default","id":"K_S","text":"\uD807\uDD89"},{"id":"K_H","text":"\uD807\uDD96"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"140","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"525","id":"K_SPACE"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_003B","text":";"},{"id":"U_005C","text":"\\"}]},{"layer":"shift","id":"K_SLASH","text":"?","sk":[{"id":"U_201C","text":"\u201C"},{"id":"U_2018","text":"\u2018"},{"id":"U_2019","text":"\u2019"},{"id":"U_201D","text":"\u201D"},{"layer":"shift","id":"K_1","text":"!"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""}]},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","text":"\uD807\uDDA1","sk":[{"id":"T_1","text":"1"}]},{"id":"K_2","text":"\uD807\uDDA2","sk":[{"id":"T_2","text":"2"}]},{"id":"K_3","text":"\uD807\uDDA3","sk":[{"id":"T_3","text":"3"}]},{"id":"K_4","text":"\uD807\uDDA4","sk":[{"id":"T_4","text":"4"}]},{"id":"K_5","text":"\uD807\uDDA5","sk":[{"id":"T_5","text":"5"}]},{"id":"K_6","text":"\uD807\uDDA6","sk":[{"id":"T_6","text":"6"}]},{"id":"K_7","text":"\uD807\uDDA7","sk":[{"id":"T_7","text":"7"}]},{"id":"K_8","text":"\uD807\uDDA8","sk":[{"id":"T_8","text":"8"}]},{"id":"K_9","text":"\uD807\uDDA9","sk":[{"id":"T_9","text":"9"}]},{"id":"K_0","text":"\uD807\uDDA0","sk":[{"id":"T_0","text":"0"}]},{"id":"U_11D98","text":"\uD807\uDD98"}]},{"id":"2","key":[{"layer":"shift","id":"K_1","pad":"40","text":"!"},{"layer":"shift","id":"K_2","text":"@","sk":[{"id":"T_GMAIL","text":"@gmail"},{"id":"T_YAHOO","text":"@yahoo"}]},{"layer":"shift","id":"K_3","text":"#"},{"id":"U_20B9","text":"\u20B9","sk":[{"id":"U_0024","text":"$"},{"id":"U_00A3","text":"\u00A3"},{"id":"U_20BF","text":"\u20BF"},{"id":"U_20A8","text":"\u20A8"}]},{"layer":"shift","id":"K_5","text":"%"},{"layer":"default","id":"U_005E","text":"^"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"default","id":"U_005F","text":"_"},{"layer":"default","id":"K_EQUAL","text":"="},{"layer":"default","id":"U_007C","text":"|"},{"layer":"default","width":"65","id":"K_BKSLASH","text":"\\"}]},{"id":"3","key":[{"nextlayer":"default","width":"110","id":"K_NUMLOCK","sp":"2","text":"*123*"},{"layer":"default","id":"K_RBRKT","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"id":"U_003C","text":"<"},{"id":"U_007B","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"layer":"shift","id":"K_RBRKT","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"id":"U_003E","text":">"},{"id":"U_007D","text":"}"}]},{"layer":"shift","id":"K_EQUAL","text":"+"},{"layer":"default","id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_8","text":"*"},{"layer":"default","id":"K_SLASH","text":"\/"},{"id":"U_00BD","text":"\u00BD","sk":[{"id":"U_00BC","text":"\u00BC"},{"id":"U_00BE","text":"\u00BE"}]},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"shift","width":"140","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"525","id":"K_SPACE"},{"id":"K_PERIOD","text":".","sk":[{"id":"U_002C","text":","},{"id":"U_003A","text":":"},{"id":"U_003B","text":";"},{"id":"U_005C","text":"\\"}]},{"layer":"shift","id":"K_SLASH","text":"?","sk":[{"id":"U_201C","text":"\u201C"},{"id":"U_2018","text":"\u2018"},{"id":"U_2019","text":"\u2019"},{"id":"U_201D","text":"\u201D"},{"layer":"shift","id":"K_1","text":"!"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""}]},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.s14="aiueoAIUEYOV";this.s15="𑵠𑵢𑵤𑵧𑵪𑵡𑵣𑵥𑵧𑵨𑵪𑵫";this.s16="kgWcrjtdNq[npbmylvsKGCJTDQ{PBhL";this.s17="𑵱𑵶𑶄𑵻𑶈𑶀𑵽𑶂𑶄𑵳𑵸𑵺𑶅𑵮𑵰𑵬𑵵𑵭𑶉𑵲𑵷𑵼𑶁𑵾𑶃𑵴𑵹𑶆𑵯𑶇𑵿";this.s18="MH";this.s19="𑶕𑶖";this.s20="0123456789";this.s21="𑶠𑶡𑶢𑶣𑶤𑶥𑶦𑶧𑶨𑶩";this.s22="RSFZXwfz";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,256)) {if(1){r=m=1;k.KO(0,t,"0");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KO(0,t,"1");}}else if(k.KKM(e,16384,258)) {if(1){r=m=1;k.KO(0,t,"2");}}else if(k.KKM(e,16384,259)) {if(1){r=m=1;k.KO(0,t,"3");}}else if(k.KKM(e,16384,260)) {if(1){r=m=1;k.KO(0,t,"4");}}else if(k.KKM(e,16384,261)) {if(1){r=m=1;k.KO(0,t,"5");}}else if(k.KKM(e,16384,262)) {if(1){r=m=1;k.KO(0,t,"6");}}else if(k.KKM(e,16384,263)) {if(1){r=m=1;k.KO(0,t,"7");}}else if(k.KKM(e,16384,264)) {if(1){r=m=1;k.KO(0,t,"8");}}else if(k.KKM(e,16384,265)) {if(1){r=m=1;k.KO(0,t,"9");}}else if(k.KKM(e,16384,266)) {if(1){r=m=1;k.KO(0,t,"@gmail.com");}}else if(k.KKM(e,16384,267)) {if(1){r=m=1;k.KO(0,t,"@yahoo.com");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KO(0,t,"𑶠");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KO(0,t,"𑶡");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KO(0,t,"𑶢");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KO(0,t,"𑶣");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KO(0,t,"𑶤");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KO(0,t,"𑶥");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KO(0,t,"𑶦");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KO(0,t,"𑶧");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KO(0,t,"𑶨");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KO(0,t,"𑶩");}}else if(k.KKM(e,16400,188)) {if(k.KCM(1,t,"‘",1)){r=m=1;k.KO(1,t,"“");}else if(1){r=m=1;k.KO(0,t,"‘");}}else if(k.KKM(e,16400,190)) {if(k.KCM(1,t,"’",1)){r=m=1;k.KO(1,t,"”");}else if(1){r=m=1;k.KO(0,t,"’");}}else if(k.KKM(e,16400,65)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶊");}else if(1){r=m=1;k.KO(0,t,"𑵡");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KO(0,t,"𑵯");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KO(0,t,"𑵼");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KO(0,t,"𑶃");}}else if(k.KKM(e,16400,69)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶐");}else if(1){r=m=1;k.KO(0,t,"𑵧");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KO(0,t,"𑵷");}}else if(k.KKM(e,16400,72)) {if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"A",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"i",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"I",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"u",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"U",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"e",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"E",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"Y",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"o",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"O",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"V",1)){r=m=1;k.KO(-1,t,"𑶖");}else if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶖");}else if(1){r=m=1;k.KO(0,t,"𑶖");}}else if(k.KKM(e,16400,73)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶌");}else if(1){r=m=1;k.KO(0,t,"𑵣");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KO(0,t,"𑶁");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KO(0,t,"𑵲");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KO(0,t,"𑵿");}}else if(k.KKM(e,16400,77)) {if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"A",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"i",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"I",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"u",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"U",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"e",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"E",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"Y",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"o",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"O",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(2,1,t),this.s17)&&k.KCM(1,t,"V",1)){r=m=1;k.KO(-1,t,"𑶕");}else if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶕");}else if(1){r=m=1;k.KO(0,t,"𑶕");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KO(0,t,"𑶄");}}else if(k.KKM(e,16400,79)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶓");}else if(1){r=m=1;k.KO(0,t,"𑵪");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KO(0,t,"𑶆");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KO(0,t,"𑵴");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KO(0,t,"𑵾");}}else if(k.KKM(e,16400,85)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶎");}else if(1){r=m=1;k.KO(0,t,"𑵥");}}else if(k.KKM(e,16400,86)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶔");}else if(1){r=m=1;k.KO(0,t,"𑵫");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KO(0,t,"𑶄");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16400,89)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶑");}else if(1){r=m=1;k.KO(0,t,"𑵨");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KO(0,t,"𑵸");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KO(0,t,"[");}}else if(k.KKM(e,16384,65)) {if(1){r=m=1;k.KO(0,t,"𑵠");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KO(0,t,"𑵮");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KO(0,t,"𑵻");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KO(0,t,"𑶂");}}else if(k.KKM(e,16384,69)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶐");}else if(1){r=m=1;k.KO(0,t,"𑵧");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KO(0,t,"𑵶");}}else if(k.KKM(e,16384,72)) {if(1){r=m=1;k.KO(0,t,"𑶇");}}else if(k.KKM(e,16384,73)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶋");}else if(1){r=m=1;k.KO(0,t,"𑵢");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KO(0,t,"𑶀");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KO(0,t,"𑵱");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KO(0,t,"𑵵");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KO(0,t,"𑵰");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KO(0,t,"𑵺");}}else if(k.KKM(e,16384,79)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶓");}else if(1){r=m=1;k.KO(0,t,"𑵪");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KO(0,t,"𑶅");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KO(0,t,"𑵳");}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KO(0,t,"𑶈");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KO(0,t,"𑶉");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KO(0,t,"𑵽");}}else if(k.KKM(e,16384,85)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶍");}else if(1){r=m=1;k.KO(0,t,"𑵤");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KO(0,t,"𑵭");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16384,88)) {if(k.KA(0,k.KC(1,1,t),this.s17)){r=m=1;k.KO(-1,t,"𑶗");}else if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KO(0,t,"𑵬");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KB(t);}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KO(0,t,"𑵹");}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KO(0,t,"]");}}return r;};} \ No newline at end of file diff --git a/keyboard/gondi_gunjala_inscript/1.1.1/gondi_gunjala_inscript-1.1.1.js b/keyboard/gondi_gunjala_inscript/1.1.1/gondi_gunjala_inscript-1.1.1.js new file mode 100644 index 000000000..d7549f542 --- /dev/null +++ b/keyboard/gondi_gunjala_inscript/1.1.1/gondi_gunjala_inscript-1.1.1.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_gondi_gunjala_inscript());}function Keyboard_gondi_gunjala_inscript(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_gondi_gunjala_inscript";this.KN="Gondi INSCRIPT (Gunjala)";this.KMINVER="10.0";this.KV={F:' 1em "Narnoor"',K102:0};this.KV.KLS={"shift": ["","","","#","","","𑵳𑶗𑶈","","","","","𑶖","","","","","𑵫","𑵨","𑵡","𑵣","𑵥","𑵯","𑶄","𑵷","𑵹","𑶁","𑶃","","","","","","𑵪","𑵧","𑵠","𑵢","𑵤","𑶆","","𑵲","𑵴","𑵼","𑵾","","","","","","","","𑶗","𑶄","","","𑵿","","","","","","","","","",""],"default": ["`","𑶡","𑶢","𑶣","𑶤","𑶥","𑶦","𑶧","𑶨","𑶩","𑶠","-","=","","","","𑶔","𑶑","𑶊","𑶌","𑶎","𑵮","𑶇","𑵶","𑵸","𑶀","𑶂","","\\","","","","𑶓","𑶐","𑶗","𑶋","𑶍","𑶅","𑶈","𑵱","𑵳","𑵻","𑵽","","","","","","","","𑶕","𑵰","𑵺","𑵭","𑵵","𑶉",",",".","𑵬","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=1;this.KH='';this.KM=0;this.KBVER="1.1.1";this.KMBM=0x0010;this.KS=1;this.s11="JZzVBM>?]}|()*+&%$@!~";this.s12="DFGERTSWAQ";this.s13="𑵠𑵢𑵤𑵡𑵣𑵥𑵧𑵨𑵪𑵫";this.s14="kiU;jp'[Clovhyc/nbmKI:P\"{LOHYNu";this.s15="𑵱𑵶𑶄𑵻𑶈𑶀𑵽𑶂𑶄𑵳𑵸𑵺𑶅𑵮𑵰𑵬𑵵𑵭𑶉𑵲𑵷𑵼𑶁𑵾𑶃𑵴𑵹𑶆𑵯𑵿𑶇";this.s16="Xx_";this.s17="𑶗𑶕𑶖";this.s18="0123456789";this.s19="𑶠𑶡𑶢𑶣𑶤𑶥𑶦𑶧𑶨𑶩";this.s21="qwerasdfg";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16400,49)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,222)) {if(k.KFCM(1,t,['\"'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"“");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵾");}}else if(k.KKM(e,16400,51)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶗𑶈");}}else if(k.KKM(e,16400,52)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,53)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,55)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,222)) {if(k.KFCM(1,t,['\''])){r=m=1;k.KDC(1,t);k.KO(-1,t,"”");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵽");}}else if(k.KKM(e,16400,57)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,48)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,56)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,187)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,189)) {if(k.KFCM(2,t,['_','_'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"___");}else if(k.KFCM(1,t,['-'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"__");}}else if(k.KKM(e,16384,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵬");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶠");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶡");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶢");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶣");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶤");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶥");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶦");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶧");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶨");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶩");}}else if(k.KKM(e,16400,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵼");}}else if(k.KKM(e,16384,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵻");}}else if(k.KKM(e,16400,190)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,50)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵪");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶄");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵠");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵡");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵢");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵤");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶆");}}else if(k.KKM(e,16400,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵷");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵲");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵴");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵿");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵹");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶁");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵫");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵣");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵧");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵥");}}else if(k.KKM(e,16400,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶄");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵨");}}else if(k.KKM(e,16400,88)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'e'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"e𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'f'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"f𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'r'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"r𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'g'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"g𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'t'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"t𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'z'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"z𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'s'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"s𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'w'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"w𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'`'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"`𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'a'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"a𑶗");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'q'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"q𑶗");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶗");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶗");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵯");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶂");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵳𑶗𑶈");}}else if(k.KKM(e,16400,189)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'e'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"e𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'f'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"f𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'r'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"r𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'g'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"g𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'t'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"t𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'z'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"z𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'s'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"s𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'w'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"w𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'`'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"`𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'a'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"a𑶖");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'q'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"q𑶖");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶖");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶖");}}else if(k.KKM(e,16384,65)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶓");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵭");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵰");}}else if(k.KKM(e,16384,68)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶗");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,69)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶊");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,70)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶋");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,71)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶍");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶅");}}else if(k.KKM(e,16384,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵶");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶈");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵱");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵳");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶉");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵵");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵸");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶀");}}else if(k.KKM(e,16384,81)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶔");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,82)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶌");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,83)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶐");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,84)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶎");}}else if(k.KKM(e,16384,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶇");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵺");}}else if(k.KKM(e,16384,87)) {if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶑");}else if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,88)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'e'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"e𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'f'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"f𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'r'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"r𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'g'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"g𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'t'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"t𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'z'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"z𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'s'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"s𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'w'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"w𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'`'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"`𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'a'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"a𑶕");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'q'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"q𑶕");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"𑶕");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶕");}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑵮");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑶃");}}else if(k.KKM(e,16400,220)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,192)) {if(1){r=m=1;k.KDC(0,t);}}return r;};} \ No newline at end of file diff --git a/keyboard/malar_malayalam/1.7/malar_malayalam-1.7.js b/keyboard/malar_malayalam/1.7/malar_malayalam-1.7.js new file mode 100644 index 000000000..3ada7a821 --- /dev/null +++ b/keyboard/malar_malayalam/1.7/malar_malayalam-1.7.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_malar_malayalam());}function Keyboard_malar_malayalam(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_malar_malayalam";this.KN="Malar Malayalam";this.KMINVER="10.0";this.KV={F:' 1em "sans-serif"',K102:0};this.KV.KLS={"default": ["`","1","2","3","4","5","6","7","8","9","0","-","=","","","","q","w","e","r","t","y","u","i","o","p","[","]","\\","","","","a","s","d","f","g","h","j","k","l",";","'","","","","","","\\","z","x","c","v","b","n","m",",",".","/","","","","","",""],"shift": ["~","!","@","#","₹","%","^","&","*","(",")","_","+","","","","Q","W","E","R","T","Y","U","I","O","P","{","}","|","","","","A","S","D","F","G","H","J","K","L",":","\"","","","","","","|","Z","X","C","V","B","N","M","<",">","?","","","","","",""],"ctrl": ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"shift-alt": ["~","!","@","#","$","%","^","&","*","(",")","_","+","","","","","","","","","","","","","","{","}","|","","","","","","","","","","","","",":","\"","","","","","","","","","","","","","","<",">","?","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH='';this.KM=0;this.KBVER="1.7";this.KMBM=0x0010;this.KVKL={"phone":{"font":"sans-serif","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_Q","text":"q"},{"id":"K_W","text":"w"},{"id":"K_E","text":"e"},{"id":"K_R","text":"r"},{"id":"K_T","text":"t"},{"id":"K_Y","text":"y"},{"id":"K_U","text":"u"},{"id":"K_I","text":"i"},{"id":"K_O","text":"o"},{"id":"K_P","text":"p"}]},{"id":"2","key":[{"id":"K_A","pad":"70","text":"a"},{"id":"K_S","text":"s"},{"id":"K_D","text":"d"},{"id":"K_F","text":"f"},{"id":"K_G","text":"g"},{"id":"K_H","text":"h"},{"id":"K_J","text":"j"},{"id":"K_K","text":"k"},{"id":"K_L","text":"l"},{"width":"10","id":"T_new_111","sp":"10"}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"z"},{"id":"K_X","text":"x"},{"id":"K_C","text":"c"},{"id":"K_V","text":"v"},{"id":"K_B","text":"b"},{"id":"K_N","text":"n"},{"id":"K_M","text":"m"},{"id":"K_BKSLASH","text":"\\"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"100","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"id":"K_ROPT","sp":"1","text":"*Hide*"},{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"330","id":"K_SPACE"},{"id":"K_PERIOD","text":".","sk":[{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"}]},{"id":"K_COMMA","text":","},{"layer":"shift","id":"K_BKQUOTE","text":"~"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"nextlayer":"default","id":"K_Q","text":"Q"},{"nextlayer":"default","id":"K_W","text":"W"},{"nextlayer":"default","id":"K_E","text":"E"},{"nextlayer":"default","id":"K_R","text":"R"},{"nextlayer":"default","id":"K_T","text":"T"},{"nextlayer":"default","id":"K_Y","text":"Y"},{"nextlayer":"default","id":"K_U","text":"U"},{"nextlayer":"default","id":"K_I","text":"I"},{"nextlayer":"default","id":"K_O","text":"O"},{"nextlayer":"default","id":"K_P","text":"P"}]},{"id":"2","key":[{"nextlayer":"default","id":"K_A","pad":"70","text":"A"},{"nextlayer":"default","id":"K_S","text":"S"},{"nextlayer":"default","id":"K_D","text":"D"},{"nextlayer":"default","id":"K_F","text":"F"},{"nextlayer":"default","id":"K_G","text":"G"},{"nextlayer":"default","id":"K_H","text":"H"},{"nextlayer":"default","id":"K_J","text":"J"},{"nextlayer":"default","id":"K_K","text":"K"},{"nextlayer":"default","id":"K_L","text":"L"},{"width":"10","id":"T_new_236","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"nextlayer":"default","id":"K_Z","text":"Z"},{"nextlayer":"default","id":"K_X","text":"X"},{"nextlayer":"default","id":"K_C","text":"C"},{"nextlayer":"default","id":"K_V","text":"V"},{"nextlayer":"default","id":"K_B","text":"B"},{"nextlayer":"default","id":"K_N","text":"N"},{"nextlayer":"default","id":"K_M","text":"M"},{"nextlayer":"default","layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"id":"K_ROPT","sp":"1","text":"*Hide*"},{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"330","id":"K_SPACE"},{"nextlayer":"default","layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"shift","id":"K_1","text":"!"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"nextlayer":"default","id":"K_COMMA","text":","},{"nextlayer":"default","layer":"shift","id":"K_BKQUOTE","text":"~"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"}]},{"id":"2","key":[{"layer":"shift","id":"K_2","pad":"70","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"shift","id":"K_7","text":"&"},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"K_SLASH","text":"\/"},{"width":"10","id":"T_new_270","sp":"10"}]},{"id":"3","key":[{"nextlayer":"extra","id":"K_SHIFT","sp":"1","text":"=\\<"},{"id":"U_20B9","text":"\u20B9"},{"layer":"shift","id":"K_8","text":"*"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_COLON","text":":"},{"id":"K_COLON","text":";"},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_SLASH","text":"?"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","id":"K_LOWER","sp":"1","text":"*abc*"},{"id":"K_ROPT","sp":"1","text":"*Hide*"},{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"330","id":"K_SPACE"},{"id":"K_PERIOD","text":"."},{"id":"K_COMMA","text":","},{"id":"K_BKSLASH","text":"\\"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"extra","row":[{"id":"1","key":[{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"}]},{"id":"2","key":[{"id":"U_007E","pad":"70","text":"~"},{"id":"K_BKQUOTE","text":"`"},{"id":"U_007C","text":"|"},{"id":"K_EQUAL","text":"="},{"id":"K_HYPHEN","text":"-"},{"layer":"shift","id":"K_EQUAL","text":"+"},{"id":"U_00F7","text":"\u00F7"},{"id":"U_00D7","text":"\u00D7"},{"id":"K_SLASH","text":"\/"},{"width":"10","id":"T_new_270","sp":"10"}]},{"id":"3","key":[{"nextlayer":"numeric","id":"K_SHIFT","sp":"1","text":"*123*"},{"id":"U_0024","text":"$"},{"layer":"shift","id":"K_6","text":"^"},{"layer":"shift","id":"K_LBRKT","text":"{"},{"id":"K_LBRKT","text":"["},{"id":"K_RBRKT","text":"]"},{"layer":"shift","id":"K_RBRKT","text":"}"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_PERIOD","text":">"},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","id":"K_LOWER","sp":"1","text":"*abc*"},{"id":"K_ROPT","sp":"1","text":"*Hide*"},{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"330","id":"K_SPACE"},{"id":"K_PERIOD","text":"."},{"id":"K_COMMA","text":","},{"id":"K_BKSLASH","text":"\\"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"caps","row":[{"id":"1","key":[{"layer":"shift","id":"K_Q","text":"Q"},{"layer":"shift","id":"K_W","text":"W"},{"layer":"shift","id":"K_E","text":"E"},{"layer":"shift","id":"K_R","text":"R"},{"layer":"shift","id":"K_T","text":"T"},{"layer":"shift","id":"K_Y","text":"Y"},{"layer":"shift","id":"K_U","text":"U"},{"layer":"shift","id":"K_I","text":"I"},{"layer":"shift","id":"K_O","text":"O"},{"layer":"shift","id":"K_P","text":"P"}]},{"id":"2","key":[{"layer":"shift","id":"K_A","pad":"70","text":"A"},{"layer":"shift","id":"K_S","text":"S"},{"layer":"shift","id":"K_D","text":"D"},{"layer":"shift","id":"K_F","text":"F"},{"layer":"shift","id":"K_G","text":"G"},{"layer":"shift","id":"K_H","text":"H"},{"layer":"shift","id":"K_J","text":"J"},{"layer":"shift","id":"K_K","text":"K"},{"layer":"shift","id":"K_L","text":"L"},{"width":"10","id":"T_new_236","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"layer":"shift","id":"K_Z","text":"Z"},{"layer":"shift","id":"K_X","text":"X"},{"layer":"shift","id":"K_C","text":"C"},{"layer":"shift","id":"K_V","text":"V"},{"layer":"shift","id":"K_B","text":"B"},{"layer":"shift","id":"K_N","text":"N"},{"layer":"shift","id":"K_M","text":"M"},{"layer":"shift","id":"K_SLASH","text":"?"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"id":"K_ROPT","sp":"1","text":"*Hide*"},{"id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"330","id":"K_SPACE"},{"layer":"default","id":"K_PERIOD","text":".","sk":[{"layer":"shift","id":"K_1","text":"!"},{"layer":"default","id":"K_QUOTE","text":"'"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"default","id":"K_COLON","text":";"}]},{"layer":"default","id":"K_COMMA","text":","},{"layer":"shift","id":"K_BKQUOTE","text":"~"},{"id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]},"tablet":{"font":"sans-serif","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_BKQUOTE","text":"`"},{"id":"K_1","text":"1"},{"id":"K_2","text":"2"},{"id":"K_3","text":"3"},{"id":"K_4","text":"4"},{"id":"K_5","text":"5"},{"id":"K_6","text":"6"},{"id":"K_7","text":"7"},{"id":"K_8","text":"8"},{"id":"K_9","text":"9"},{"id":"K_0","text":"0"},{"id":"K_HYPHEN","text":"-"},{"id":"K_EQUAL","text":"="}]},{"id":"2","key":[{"id":"K_Q","text":"q"},{"id":"K_W","text":"w"},{"id":"K_E","text":"e"},{"id":"K_R","text":"r"},{"id":"K_T","text":"t"},{"id":"K_Y","text":"y"},{"id":"K_U","text":"u"},{"id":"K_I","text":"i"},{"id":"K_O","text":"o"},{"id":"K_P","text":"p"},{"id":"K_LBRKT","text":"["},{"id":"K_RBRKT","text":"]"},{"id":"K_BKSLASH","text":"\\"}]},{"id":"3","key":[{"id":"K_A","text":"a"},{"id":"K_S","text":"s"},{"id":"K_D","text":"d"},{"id":"K_F","text":"f"},{"id":"K_G","text":"g"},{"id":"K_H","text":"h"},{"id":"K_J","text":"j"},{"id":"K_K","text":"k"},{"id":"K_L","text":"l"},{"id":"K_COLON","text":";"},{"id":"K_QUOTE","text":"'"},{"width":"215","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"shift","width":"155","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"z"},{"id":"K_X","text":"x"},{"id":"K_C","text":"c"},{"id":"K_V","text":"v"},{"id":"K_B","text":"b"},{"id":"K_N","text":"n"},{"id":"K_M","text":"m"},{"id":"K_COMMA","text":","},{"id":"K_PERIOD","text":"."},{"id":"K_SLASH","text":"\/"},{"nextlayer":"shift","width":"160","id":"K_SHIFT","sp":"1","text":"*Shift*"}]},{"id":"5","key":[{"width":"155","id":"K_ROPT","sp":"1","text":"*Hide*"},{"width":"150","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"800","id":"K_SPACE"},{"width":"330","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"nextlayer":"default","id":"K_BKQUOTE","text":"~"},{"nextlayer":"default","id":"K_1","text":"!"},{"nextlayer":"default","id":"K_2","text":"@"},{"nextlayer":"default","id":"K_3","text":"#"},{"nextlayer":"default","id":"U_20B9","text":"\u20B9","sk":[{"nextlayer":"default","id":"U_0024","text":"$"}]},{"nextlayer":"default","id":"K_5","text":"%"},{"nextlayer":"default","id":"K_6","text":"^"},{"nextlayer":"default","id":"K_7","text":"&"},{"nextlayer":"default","id":"K_8","text":"*"},{"nextlayer":"default","id":"K_9","text":"("},{"nextlayer":"default","id":"K_0","text":")"},{"nextlayer":"default","id":"K_HYPHEN","text":"_"},{"nextlayer":"default","id":"K_EQUAL","text":"+"}]},{"id":"2","key":[{"nextlayer":"default","id":"K_Q","text":"Q"},{"nextlayer":"default","id":"K_W","text":"W"},{"nextlayer":"default","id":"K_E","text":"E"},{"nextlayer":"default","id":"K_R","text":"R"},{"nextlayer":"default","id":"K_T","text":"T"},{"nextlayer":"default","id":"K_Y","text":"Y"},{"nextlayer":"default","id":"K_U","text":"U"},{"nextlayer":"default","id":"K_I","text":"I"},{"nextlayer":"default","id":"K_O","text":"O"},{"nextlayer":"default","id":"K_P","text":"P"},{"nextlayer":"default","id":"K_LBRKT","text":"{"},{"nextlayer":"default","id":"K_RBRKT","text":"}"},{"nextlayer":"default","id":"K_BKSLASH","text":"|"}]},{"id":"3","key":[{"nextlayer":"default","id":"K_A","text":"A"},{"nextlayer":"default","id":"K_S","text":"S"},{"nextlayer":"default","id":"K_D","text":"D"},{"nextlayer":"default","id":"K_F","text":"F"},{"nextlayer":"default","id":"K_G","text":"G"},{"nextlayer":"default","id":"K_H","text":"H"},{"nextlayer":"default","id":"K_J","text":"J"},{"nextlayer":"default","id":"K_K","text":"K"},{"nextlayer":"default","id":"K_L","text":"L"},{"nextlayer":"default","id":"K_COLON","text":":"},{"nextlayer":"default","id":"K_QUOTE","text":"\""},{"width":"215","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"155","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"nextlayer":"default","id":"K_Z","text":"Z"},{"nextlayer":"default","id":"K_X","text":"X"},{"nextlayer":"default","id":"K_C","text":"C"},{"nextlayer":"default","id":"K_V","text":"V"},{"nextlayer":"default","id":"K_B","text":"B"},{"nextlayer":"default","id":"K_N","text":"N"},{"nextlayer":"default","id":"K_M","text":"M"},{"nextlayer":"default","id":"K_COMMA","text":"<"},{"nextlayer":"default","id":"K_PERIOD","text":">"},{"nextlayer":"default","id":"K_SLASH","text":"?"},{"nextlayer":"default","width":"160","id":"K_SHIFT","sp":"2","text":"*Shift*"}]},{"id":"5","key":[{"width":"155","id":"K_ROPT","sp":"1","text":"*Hide*"},{"width":"150","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"800","id":"K_SPACE"},{"width":"330","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"caps","row":[{"id":"1","key":[{"layer":"shift","id":"K_BKQUOTE","text":"~"},{"layer":"shift","id":"K_1","text":"!"},{"layer":"shift","id":"K_2","text":"@"},{"layer":"shift","id":"K_3","text":"#"},{"id":"U_20B9","text":"\u20B9"},{"layer":"shift","id":"K_5","text":"%"},{"layer":"shift","id":"K_6","text":"^"},{"layer":"shift","id":"K_7","text":"&"},{"layer":"shift","id":"K_8","text":"*"},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"layer":"shift","id":"K_HYPHEN","text":"_"},{"layer":"shift","id":"K_EQUAL","text":"+"}]},{"id":"2","key":[{"layer":"shift","id":"K_Q","text":"Q"},{"layer":"shift","id":"K_W","text":"W"},{"layer":"shift","id":"K_E","text":"E"},{"layer":"shift","id":"K_R","text":"R"},{"layer":"shift","id":"K_T","text":"T"},{"layer":"shift","id":"K_Y","text":"Y"},{"layer":"shift","id":"K_U","text":"U"},{"layer":"shift","id":"K_I","text":"I"},{"layer":"shift","id":"K_O","text":"O"},{"layer":"shift","id":"K_P","text":"P"},{"layer":"shift","id":"K_LBRKT","text":"{"},{"layer":"shift","id":"K_RBRKT","text":"}"},{"layer":"shift","id":"K_BKSLASH","text":"|"}]},{"id":"3","key":[{"layer":"shift","id":"K_A","text":"A"},{"layer":"shift","id":"K_S","text":"S"},{"layer":"shift","id":"K_D","text":"D"},{"layer":"shift","id":"K_F","text":"F"},{"layer":"shift","id":"K_G","text":"G"},{"layer":"shift","id":"K_H","text":"H"},{"layer":"shift","id":"K_J","text":"J"},{"layer":"shift","id":"K_K","text":"K"},{"layer":"shift","id":"K_L","text":"L"},{"layer":"shift","id":"K_COLON","text":":"},{"layer":"shift","id":"K_QUOTE","text":"\""},{"width":"215","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"155","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"layer":"shift","id":"K_Z","text":"Z"},{"layer":"shift","id":"K_X","text":"X"},{"layer":"shift","id":"K_C","text":"C"},{"layer":"shift","id":"K_V","text":"V"},{"layer":"shift","id":"K_B","text":"B"},{"layer":"shift","id":"K_N","text":"N"},{"layer":"shift","id":"K_M","text":"M"},{"layer":"shift","id":"K_COMMA","text":"<"},{"layer":"shift","id":"K_PERIOD","text":">"},{"layer":"shift","id":"K_SLASH","text":"?"},{"nextlayer":"default","width":"160","id":"K_SHIFT","sp":"2","text":"*Shift*"}]},{"id":"5","key":[{"width":"155","id":"K_ROPT","sp":"1","text":"*Hide*"},{"width":"150","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"800","id":"K_SPACE"},{"width":"330","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.s12="0123456789";this.s13="൦൧൨൩൪൫൬൭൮൯";this.s14=['','','','','','','','','',''];this.s15="കഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരലവശഷസഹളഴറഺഩ";this.s16="ാിീുൂൃൄെേൈൊോൌൗംഃഀഁൢൣ഻഼";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,8)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},{t:'a',a:this.s16}])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"്");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"്");}}else if(k.KKM(e,16384,97)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൧");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൧");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"1");}}else if(k.KKM(e,16384,96)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൦");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൦");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"0");}}else if(k.KKM(e,16384,98)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൨");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൨");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"2");}}else if(k.KKM(e,16384,99)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൩");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൩");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"3");}}else if(k.KKM(e,16384,101)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൫");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൫");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"5");}}else if(k.KKM(e,16384,102)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൬");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൬");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"6");}}else if(k.KKM(e,16384,103)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൭");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൭");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"7");}}else if(k.KKM(e,16384,104)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൮");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൮");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"8");}}else if(k.KKM(e,16384,105)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൯");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൯");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"9");}}else if(k.KKM(e,16384,100)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൪");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൪");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"4");}}else if(k.KKM(e,16384,109)) {if(k.KFCM(1,t,['–'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"––");}else if(k.KFCM(1,t,['—'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"——");}else if(k.KFCM(1,t,['-'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"--");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"-");}}else if(k.KKM(e,16384,106)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"*");}}else if(k.KKM(e,16384,107)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"+");}}else if(k.KKM(e,16384,110)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,".");}}else if(k.KKM(e,16384,111)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"/");}}else if(k.KKM(e,16384,32)) {if(k.KFCM(1,t,['‌'])){r=m=1;k.KDC(1,t);k.KO(-1,t," ");}}else if(k.KKM(e,16400,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!");}}else if(k.KKM(e,16400,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\"");}}else if(k.KKM(e,16400,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"#");}}else if(k.KKM(e,16400,52)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"$");}else if(k.KFCM(1,t,[{t:'d',d:4}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"$");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"₹");}}else if(k.KKM(e,16400,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"%");}}else if(k.KKM(e,16400,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"&");}}else if(k.KKM(e,16384,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"'");}}else if(k.KKM(e,16400,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"(");}}else if(k.KKM(e,16400,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,")");}}else if(k.KKM(e,16400,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"*");}}else if(k.KKM(e,16400,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"+");}}else if(k.KKM(e,16384,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,",");}}else if(k.KKM(e,16384,189)) {if(k.KFCM(1,t,['–'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"––");}else if(k.KFCM(1,t,['—'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"——");}else if(k.KFCM(1,t,['-'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"--");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"-");}}else if(k.KKM(e,16384,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,".");}}else if(k.KKM(e,16384,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"/");}}else if(k.KKM(e,16384,48)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൦");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൦");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"0");}}else if(k.KKM(e,16384,49)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൧");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൧");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"1");}}else if(k.KKM(e,16384,50)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൨");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൨");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"2");}}else if(k.KKM(e,16384,51)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൩");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൩");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"3");}}else if(k.KKM(e,16384,52)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൪");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൪");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"4");}}else if(k.KKM(e,16384,53)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൫");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൫");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"5");}}else if(k.KKM(e,16384,54)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൬");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൬");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"6");}}else if(k.KKM(e,16384,55)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൭");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൭");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"7");}}else if(k.KKM(e,16384,56)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൮");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൮");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"8");}}else if(k.KKM(e,16384,57)) {if(k.KFCM(1,t,[{t:'a',a:this.s13}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);k.KO(-1,t,"൯");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"൯");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"9");}}else if(k.KKM(e,16400,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,":");}}else if(k.KKM(e,16384,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,";");}}else if(k.KKM(e,16400,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"<");}}else if(k.KKM(e,16384,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"=");}}else if(k.KKM(e,16400,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,">");}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"?");}}else if(k.KKM(e,16400,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"@");}}else if(k.KKM(e,16400,65)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ാ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ആ");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"_");k.KDO(-1,t,3);}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഡ്");}}else if(k.KKM(e,16400,69)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"േ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഏ");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഘ്");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഃ");}}else if(k.KKM(e,16400,73)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ീ");}else if(k.KFCM(1,t,['ഈ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൟ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഈ");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഝ്");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഖ്");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ള്");}}else if(k.KKM(e,16400,77)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'ം'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ഀ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ഀ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ഁ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ഁ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ം");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഄ");}else if(k.KFCM(1,t,['ം'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഀ");}else if(k.KFCM(1,t,['ഀ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഁ");}else if(k.KFCM(1,t,['ഁ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ം");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ം");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ണ്");}}else if(k.KKM(e,16400,79)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ോ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഓ");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,4);}}else if(k.KKM(e,16400,82)) {if(k.KFCM(2,t,['റ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഋ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൃ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ൃ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൄ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ൄ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൃ");}else if(k.KFCM(1,t,['ഋ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൠ");}else if(k.KFCM(1,t,['ൃ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൄ");}else if(k.KFCM(1,t,['ൄ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൃ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"റ്");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ശ്");}}else if(k.KKM(e,16400,84)) {if(k.KFCM(2,t,['ഠ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"റ്റ്");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഠ്");}}else if(k.KKM(e,16400,85)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൂ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഊ");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,87)) {if(k.KFCM(2,t,['_',{t:'d',d:5}])){r=m=1;k.KDC(2,t);k.KO(-1,t,"‍");}else if(k.KFCM(1,t,['‍'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"_");k.KDO(-1,t,5);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"_");k.KDO(-1,t,5);}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,0);}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16400,90)) {if(k.KFCM(2,t,['_',{t:'d',d:6}])){r=m=1;k.KDC(2,t);k.KO(-1,t,"‌");}else if(k.KFCM(1,t,['‌'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"_");k.KDO(-1,t,6);}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"_");k.KDO(-1,t,6);}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"[");}}else if(k.KKM(e,16384,220)) {if(k.KFCM(5,t,['1','/','1','6','0'])){r=m=1;k.KDC(5,t);k.KO(-1,t,"൘");}else if(k.KFCM(4,t,['റ','്','റ','്'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"ഺ്");}else if(k.KFCM(4,t,['1','/','4','0'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൙");}else if(k.KFCM(4,t,['1','/','2','0'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൛");}else if(k.KFCM(4,t,['1','/','1','0'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൜");}else if(k.KFCM(4,t,['3','/','2','0'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൝");}else if(k.KFCM(4,t,['3','/','1','6'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൸");}else if(k.KFCM(4,t,['3','/','8','0'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൚");}else if(k.KFCM(4,t,['1','/','1','6'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൶");}else if(k.KFCM(4,t,['1','0','0','0'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"൲");}else if(k.KFCM(3,t,['റ','്','റ'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"ഺ");}else if(k.KFCM(3,t,[{t:'a',a:this.s15},'്','ഌ'])){r=m=1;k.KDC(3,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൢ");}else if(k.KFCM(3,t,[{t:'a',a:this.s15},'്','ൡ'])){r=m=1;k.KDC(3,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൣ");}else if(k.KFCM(3,t,['1','/','8'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"൷");}else if(k.KFCM(3,t,['1','/','5'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"൞");}else if(k.KFCM(3,t,['1','/','4'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"൳");}else if(k.KFCM(3,t,['1','/','2'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"൴");}else if(k.KFCM(3,t,['3','/','4'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"൵");}else if(k.KFCM(3,t,['1','0','0'])){r=m=1;k.KDC(3,t);k.KO(-1,t,"൱");}else if(k.KFCM(2,t,['ഔ',{t:'d',d:1}])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൌ");}else if(k.KFCM(2,t,['ന','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൻ");}else if(k.KFCM(2,t,['ണ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൺ");}else if(k.KFCM(2,t,['ല','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൽ");}else if(k.KFCM(2,t,['ള','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൾ");}else if(k.KFCM(2,t,['ര','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ർ");}else if(k.KFCM(2,t,['ക','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൿ");}else if(k.KFCM(2,t,['മ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൔ");}else if(k.KFCM(2,t,['യ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൕ");}else if(k.KFCM(2,t,['ഴ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൖ");}else if(k.KFCM(2,t,['ല','ു'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഌ");}else if(k.KFCM(2,t,['ല','ൂ'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൡ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ൃ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൄ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ൄ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൃ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ം'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ഀ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ഀ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ഁ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ഁ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ം");}else if(k.KFCM(2,t,['1','0'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"൰");}else if(k.KFCM(2,t,['പ','റ'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"൏");}else if(k.KFCM(2,t,['ന','ു'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"൹");}else if(k.KFCM(1,t,[{t:'a',a:this.s12}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s13,1,t);}else if(k.KFCM(1,t,['ആ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ാ");}else if(k.KFCM(1,t,['ഇ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ി");}else if(k.KFCM(1,t,['ഈ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ീ");}else if(k.KFCM(1,t,['ഉ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ു");}else if(k.KFCM(1,t,['ഊ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൂ");}else if(k.KFCM(1,t,['ഋ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൃ");}else if(k.KFCM(1,t,['എ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"െ");}else if(k.KFCM(1,t,['ഏ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"േ");}else if(k.KFCM(1,t,['ഐ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൈ");}else if(k.KFCM(1,t,['ഒ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൊ");}else if(k.KFCM(1,t,['ഓ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ോ");}else if(k.KFCM(1,t,['ഔ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൗ");}else if(k.KFCM(1,t,['₹'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"$");}else if(k.KFCM(1,t,['$'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"₹");}else if(k.KFCM(1,t,['ൻ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഩ്");}else if(k.KFCM(1,t,['ന'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഩ");}else if(k.KFCM(1,t,['ൠ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൄ");}else if(k.KFCM(1,t,['അ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഽ");}else if(k.KFCM(1,t,['ൃ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൄ");}else if(k.KFCM(1,t,['ൄ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൃ");}else if(k.KFCM(1,t,['ം'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഀ");}else if(k.KFCM(1,t,['ഀ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഁ");}else if(k.KFCM(1,t,['ഁ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ം");}else if(k.KFCM(1,t,['ഌ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൢ");}else if(k.KFCM(1,t,['ൡ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൣ");}else if(k.KFCM(1,t,['ർ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ൎ");}else if(k.KFCM(1,t,['ൎ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ർ");}else if(k.KFCM(1,t,['\''])){r=m=1;k.KDC(1,t);k.KO(-1,t,"‘");}else if(k.KFCM(1,t,['‘'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"’");}else if(k.KFCM(1,t,['’'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"`");}else if(k.KFCM(1,t,['`'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"´");}else if(k.KFCM(1,t,['´'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"'");}else if(k.KFCM(1,t,['\"'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"“");}else if(k.KFCM(1,t,['“'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"”");}else if(k.KFCM(1,t,['”'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"\"");}else if(k.KFCM(1,t,['-'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"–");}else if(k.KFCM(1,t,['–'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"—");}else if(k.KFCM(1,t,['—'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"-");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"\\");}else if(k.KFCM(1,t,[{t:'d',d:4}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"\\");}else if(k.KFCM(1,t,['/'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"÷");}else if(k.KFCM(1,t,['*'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"×");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\\");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"]");}}else if(k.KKM(e,16400,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"^");}}else if(k.KKM(e,16400,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"_");}}else if(k.KKM(e,16384,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"`");}}else if(k.KKM(e,16384,65)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);}else if(k.KFCM(1,t,['അ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ആ");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ാ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"അ");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ബ്");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"_");k.KDO(-1,t,2);}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ദ്");}}else if(k.KKM(e,16384,69)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'െ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ീ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"െ");}else if(k.KFCM(1,t,['എ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഈ");}else if(k.KFCM(1,t,['അ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഏ");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"േ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"എ");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഫ്");}}else if(k.KKM(e,16384,71)) {if(k.KFCM(2,t,['ണ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ങ്");}else if(k.KFCM(2,t,['ന','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ങ്ങ്");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഗ്");}}else if(k.KKM(e,16384,72)) {if(k.KFCM(4,t,['ൻ','്','റ','്'])){r=m=1;k.KDC(4,t);k.KO(-1,t,"ന്ത്");}else if(k.KFCM(4,t,['ന','്','_',{t:'d',d:2}])){r=m=1;k.KDC(4,t);k.KO(-1,t,"ഞ്ച്");}else if(k.KFCM(2,t,['ക','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഖ്");}else if(k.KFCM(2,t,['ഗ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഘ്");}else if(k.KFCM(2,t,['_',{t:'d',d:2}])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ച്");}else if(k.KFCM(2,t,['ച','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഛ്");}else if(k.KFCM(2,t,['_',{t:'d',d:3}])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഛ്");}else if(k.KFCM(2,t,['ജ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഝ്");}else if(k.KFCM(2,t,['ഡ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഢ്");}else if(k.KFCM(2,t,['ട','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ത്");}else if(k.KFCM(2,t,['ഠ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഥ്");}else if(k.KFCM(2,t,['ദ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ധ്");}else if(k.KFCM(2,t,['ബ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഭ്");}else if(k.KFCM(2,t,['സ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഷ്");}else if(k.KFCM(2,t,['ശ','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഴ്");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഹ്");}}else if(k.KKM(e,16384,73)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ി");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ി'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ീ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'െ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൈ");}else if(k.KFCM(1,t,['ഇ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഈ");}else if(k.KFCM(1,t,['അ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഐ");}else if(k.KFCM(1,t,['എ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഐ");}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൈ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഇ");}}else if(k.KKM(e,16384,74)) {if(k.KFCM(2,t,['ന','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ഞ്");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ജ്");}}else if(k.KKM(e,16384,75)) {if(k.KFCM(2,t,['ന','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ങ്ക്");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ക്");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ല്");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"മ്");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ന്");}}else if(k.KKM(e,16384,79)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'ൊ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൂ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൊ");}else if(k.KFCM(1,t,['ഒ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഊ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഒ");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"പ്");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,4);}}else if(k.KKM(e,16384,82)) {if(k.KFCM(2,t,['ര','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"റ്");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ര്");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"സ്");}}if(m) {}else if(k.KKM(e,16384,84)) {if(k.KFCM(2,t,['ന','്'])){r=m=1;k.KDC(2,t);k.KO(-1,t,"ൻ്റ്");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ട്");}}else if(k.KKM(e,16384,85)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ു");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ു'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൂ");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'ൊ'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൌ");}else if(k.KFCM(1,t,['ഉ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഊ");}else if(k.KFCM(1,t,['അ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഔ");}else if(k.KFCM(1,t,['ഒ'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"ഔ");k.KDO(-1,t,1);}else if(k.KFCM(1,t,[{t:'a',a:this.s15}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"ൗ");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ഉ");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"വ്");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"വ്");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,0);}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"യ്");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ശ്");}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"{");}}else if(k.KKM(e,16400,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"|");}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"}");}}else if(k.KKM(e,16400,192)) {if(k.KFCM(2,t,[{t:'a',a:this.s15},'്'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"഻");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'഻'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"഼");}else if(k.KFCM(2,t,[{t:'a',a:this.s15},'഼'])){r=m=1;k.KDC(2,t);k.KIO(-1,this.s15,1,t);k.KO(-1,t,"്");}else if(k.KFCM(1,t,['്'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"഻");}else if(k.KFCM(1,t,['഻'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"഼");}else if(k.KFCM(1,t,['഼'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"്");}else if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"~");}else if(k.KFCM(1,t,[{t:'d',d:4}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"~");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"്");}}return r;};} \ No newline at end of file diff --git a/keyboard/newa_romanized/1.0.1/newa_romanized-1.0.1.js b/keyboard/newa_romanized/1.0.1/newa_romanized-1.0.1.js new file mode 100644 index 000000000..135003295 --- /dev/null +++ b/keyboard/newa_romanized/1.0.1/newa_romanized-1.0.1.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_newa_romanized());}function Keyboard_newa_romanized(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_newa_romanized";this.KN="Newa Romanized";this.KMINVER="10.0";this.KV={F:' 1em "Noto Sans Newa"',K102:0};this.KV.KLS={"shift": ["𑑇","","","","𑐬𑑂‍","","","","","","","_","‌ zwnj ","","","","𑐛","𑐍","𑐿","𑐺","𑐠","𑐘","𑐹","𑐷","𑐌","𑐦","𑐃","𑐋","𑑉","","","","𑐁","𑐱","𑐢","𑐅","𑐑","𑐀","𑐗","𑐏","𑐯",":","\"","","","","","","","𑐆","𑐝","𑐕","𑑃","𑐨","𑐞","𑑄","𑐒",".","?","","","","","","‍"],"default": ["𑑌","𑑑","𑑒","𑑓","𑑔","𑑕","𑑖","𑑗","𑑘","𑑙","𑑐","-"," zwj ","","","","𑐚","𑑁","𑐾","𑐬","𑐟","𑐫","𑐸","𑐶","𑑀","𑐥","𑐂","𑐊","𑑅","","","","𑐵","𑐳","𑐡","𑐄","𑐐","𑐴","𑐖","𑐎","𑐮",";","'","","","","","","","𑐲","𑐜","𑐔","𑐰","𑐧","𑐣","𑐩","𑑍","𑑋","𑑂","","","","","",""],"alt": ["","","","","","𑐻","𑐼","𑐽","𑐾","𑐿","","","","","","","𑐭","","","𑐇","","𑐙","𑐄","","","","","","","","","","","","","𑑆","","","","","𑐈","𑐉","","","","","","","","","","","","","𑐤","𑐪","𑐓","𑑛","𑑝","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=1;this.KH='';this.KM=0;this.KBVER="1.0.1";this.KMBM=0x0050;this.KS=1;this.KVKD="T_half_ya_zwnj T_half_r_zwj";this.KVKL={"phone":{"font":"Noto Sans Newa","displayUnderlying":true,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_W","text":"\uD805\uDC41"},{"id":"K_E","text":"\uD805\uDC3E","sk":[{"id":"U_1140A","text":"\uD805\uDC0A"}]},{"id":"K_R","text":"\uD805\uDC2C","sk":[{"id":"U_1142D","text":"\uD805\uDC2D"},{"id":"T_half_r_zwj","text":"\uD805\uDC2C\uD805\uDC42\u200D"}]},{"id":"K_T","text":"\uD805\uDC1F","sk":[{"id":"U_1141A","text":"\uD805\uDC1A"}]},{"id":"K_Y","text":"\uD805\uDC2B","sk":[{"id":"T_half_ya_zwnj","text":"\uD805\uDC2B\uD805\uDC42\u200C"}]},{"id":"K_U","text":"\uD805\uDC38","sk":[{"id":"U_11404","text":"\uD805\uDC04"}]},{"id":"K_I","text":"\uD805\uDC36","sk":[{"id":"U_11402","text":"\uD805\uDC02"}]},{"id":"K_O","text":"\uD805\uDC40","sk":[{"id":"U_1140C","text":"\uD805\uDC0C"}]},{"id":"K_P","text":"\uD805\uDC25"},{"id":"U_0200D","text":"zwj","sk":[{"id":"U_0200C","text":"zwnj"}]}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"\uD805\uDC35","sk":[{"id":"U_11400","text":"\uD805\uDC00"}]},{"id":"K_S","text":"\uD805\uDC33","sk":[{"id":"U_11432","text":"\uD805\uDC32"}]},{"id":"K_D","text":"\uD805\uDC21","sk":[{"id":"U_1141C","text":"\uD805\uDC1C"}]},{"id":"U_11426","text":"\uD805\uDC26"},{"id":"K_G","text":"\uD805\uDC10"},{"id":"K_H","text":"\uD805\uDC34"},{"id":"K_J","text":"\uD805\uDC16"},{"id":"K_K","text":"\uD805\uDC0E"},{"id":"K_L","text":"\uD805\uDC2E"},{"width":"10","id":"T_new_134","sp":"10"}]},{"id":"3","key":[{"nextlayer":"shift","width":"110","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"U_11415","text":"\uD805\uDC15"},{"id":"K_C","text":"\uD805\uDC14"},{"id":"K_V","text":"\uD805\uDC30"},{"id":"K_B","text":"\uD805\uDC27"},{"id":"K_N","text":"\uD805\uDC23","sk":[{"id":"U_11424","text":"\uD805\uDC24"},{"id":"U_11412","text":"\uD805\uDC12"},{"id":"U_11413","text":"\uD805\uDC13"}]},{"id":"K_M","text":"\uD805\uDC29","sk":[{"id":"U_1142A","text":"\uD805\uDC2A"}]},{"id":"K_PERIOD","text":"\uD805\uDC4B","sk":[{"id":"U_1144D","text":"\uD805\uDC4D"},{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_005C","text":"\\"},{"id":"U_003A","text":":"},{"id":"U_003B","text":";"}]},{"id":"U_11442","text":"\uD805\uDC42"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"id":"K_W","text":"\uD805\uDC0D"},{"id":"K_E","text":"\uD805\uDC3F","sk":[{"id":"U_1140B","text":"\uD805\uDC0B"}]},{"id":"K_R","text":"\uD805\uDC3A","sk":[{"id":"U_1143B","text":"\uD805\uDC3B"},{"id":"U_11406","text":"\uD805\uDC06"},{"id":"U_11407","text":"\uD805\uDC07"}]},{"id":"K_T","text":"\uD805\uDC20","sk":[{"id":"U_1141B","text":"\uD805\uDC1B"}]},{"id":"K_Y","text":"\uD805\uDC18","sk":[{"id":"U_11419","text":"\uD805\uDC19"}]},{"id":"K_U","text":"\uD805\uDC39","sk":[{"id":"U_11405","text":"\uD805\uDC05"}]},{"id":"K_I","text":"\uD805\uDC37","sk":[{"id":"U_11403","text":"\uD805\uDC03"}]},{"id":"K_O","text":"\uD805\uDC0C"},{"id":"K_P","text":"\uD805\uDC26"},{"id":"U_0200C","text":"zwnj"}]},{"id":"2","key":[{"id":"K_A","pad":"50","text":"\uD805\uDC01"},{"id":"K_S","text":"\uD805\uDC31"},{"id":"K_D","text":"\uD805\uDC22","sk":[{"id":"U_1141D","text":"\uD805\uDC1D"}]},{"id":"U_11449","text":"\u200C\uD805\uDC49"},{"id":"K_G","text":"\uD805\uDC11"},{"id":"K_H","text":"\uD805\uDC00"},{"id":"K_J","text":"\uD805\uDC17"},{"id":"K_K","text":"\uD805\uDC0F"},{"id":"K_L","text":"\uD805\uDC2F","sk":[{"id":"U_1143C","text":"\uD805\uDC3C"},{"id":"U_11408","text":"\uD805\uDC08"},{"id":"U_1143D","text":"\uD805\uDC3D"},{"id":"U_11409","text":"\uD805\uDC09"}]},{"width":"10","id":"T_new_168","sp":"10"}]},{"id":"3","key":[{"nextlayer":"default","width":"110","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"U_11445","text":"\uD805\uDC45"},{"id":"K_C","text":"\uD805\uDC15"},{"id":"K_V","text":"\uD805\uDC43"},{"id":"K_B","text":"\uD805\uDC28"},{"id":"K_N","text":"\uD805\uDC1E"},{"id":"K_M","text":"\uD805\uDC44","sk":[{"id":"U_11448","text":"\uD805\uDC48"},{"id":"U_11446","text":"\uD805\uDC46"}]},{"id":"U_1144C","text":"\uD805\uDC4C","sk":[{"id":"U_002C","text":","},{"id":"U_0021","text":"!"},{"id":"U_003F","text":"?"},{"id":"U_0027","text":"'"},{"id":"U_0022","text":"\""},{"id":"U_005C","text":"\\"},{"id":"U_003A","text":":"},{"id":"U_003B","text":";"}]},{"id":"U_11442","text":"\uD805\uDC42"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"140","id":"K_NUMLOCK","sp":"1","text":"*123*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE","text":"\u200D"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","text":"\uD805\uDC51"},{"id":"K_2","text":"\uD805\uDC52"},{"id":"K_3","text":"\uD805\uDC53"},{"id":"K_4","text":"\uD805\uDC54"},{"id":"K_5","text":"\uD805\uDC55"},{"id":"K_6","text":"\uD805\uDC56"},{"id":"K_7","text":"\uD805\uDC57"},{"id":"K_8","text":"\uD805\uDC58"},{"id":"K_9","text":"\uD805\uDC59"},{"id":"K_0","text":"\uD805\uDC50"}]},{"id":"2","key":[{"id":"U_0024","pad":"50","text":"$"},{"id":"U_0040","text":"@"},{"id":"U_0023","text":"#"},{"id":"U_0025","text":"%"},{"id":"U_0026","text":"&"},{"id":"U_002D","text":"-"},{"layer":"default","id":"U_003D","text":"="},{"id":"U_007C","text":"|"},{"layer":"default","id":"U_005C","text":"\\"},{"width":"10","id":"T_new_202","sp":"10"}]},{"id":"3","key":[{"width":"110","id":"U_1144F","text":"\uD805\uDC4F","sk":[{"id":"U_11447","text":"\uD805\uDC47"},{"id":"U_1144A","text":"\uD805\uDC4A"},{"id":"U_1144E","text":"\uD805\uDC4E"},{"id":"U_1145B","text":"\uD805\uDC5B"},{"id":"U_1145D","text":"\uD805\uDC5D"},{"id":"U_1145E","text":"\uD805\uDC5E"},{"id":"U_1145F","text":"\uD805\uDC5F"}]},{"id":"U_005B","text":"[","sk":[{"id":"U_00AB","text":"\u00AB"},{"id":"U_003C","text":"<"},{"id":"U_007B","text":"{"}]},{"layer":"shift","id":"K_9","text":"("},{"layer":"shift","id":"K_0","text":")"},{"id":"U_005D","text":"]","sk":[{"id":"U_00BB","text":"\u00BB"},{"id":"U_003E","text":">"},{"id":"U_007D","text":"}"}]},{"id":"U_002B","text":"+"},{"id":"U_005F","text":"_"},{"id":"U_002A","text":"*"},{"id":"U_002F","text":"\/"},{"width":"90","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"140","id":"K_LOWER","sp":"1","text":"*abc*"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"630","id":"K_SPACE"},{"width":"140","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫𑑂‌");}}else if(k.KKM(e,16384,257)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐬𑑂‍");}}else if(k.KKM(e,16400,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\"");}}else if(k.KKM(e,16400,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐬𑑂‍");}}else if(k.KKM(e,16384,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"'");}}else if(k.KKM(e,16400,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16448,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐓");}}else if(k.KKM(e,16384,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑍");}}else if(k.KKM(e,16384,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"-");}}else if(k.KKM(e,16448,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑛");}}else if(k.KKM(e,16384,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑋");}}else if(k.KKM(e,16384,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑂");}}else if(k.KKM(e,16448,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑝");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑐");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑑");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑒");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑓");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑔");}}else if(k.KKM(e,16448,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐻");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑕");}}else if(k.KKM(e,16448,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐼");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑖");}}else if(k.KKM(e,16448,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐽");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑗");}}else if(k.KKM(e,16448,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐾");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑘");}}else if(k.KKM(e,16448,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐿");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑙");}}else if(k.KKM(e,16400,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,":");}}else if(k.KKM(e,16448,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐉");}}else if(k.KKM(e,16384,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,";");}}else if(k.KKM(e,16400,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐒");}}else if(k.KKM(e,16384,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‍");}}else if(k.KKM(e,16400,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,".");}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"?");}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐁");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐨");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐕");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐢");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐿");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐅");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐑");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐀");}}else if(k.KKM(e,16400,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐷");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐗");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐏");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐯");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑄");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐞");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐌");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐦");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐛");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐺");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐱");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐠");}}else if(k.KKM(e,16400,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐹");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑃");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐍");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐝");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐘");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐆");}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐂");}}else if(k.KKM(e,16384,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑅");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐊");}}else if(k.KKM(e,16400,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"_");}}else if(k.KKM(e,16384,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑌");}}else if(k.KKM(e,16384,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐵");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐧");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐔");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐡");}}else if(k.KKM(e,16384,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐾");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐄");}}else if(k.KKM(e,16448,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑆");}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐐");}}else if(k.KKM(e,16384,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐴");}}else if(k.KKM(e,16384,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐶");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐖");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐎");}}else if(k.KKM(e,16448,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐈");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐮");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐩");}}else if(k.KKM(e,16448,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐪");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐣");}}else if(k.KKM(e,16448,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐤");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑀");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐥");}}else if(k.KKM(e,16448,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐭");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐚");}}else if(k.KKM(e,16448,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐇");}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐬");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐳");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐟");}}else if(k.KKM(e,16448,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐄");}}else if(k.KKM(e,16384,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐸");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐰");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑁");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐜");}}else if(k.KKM(e,16448,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐙");}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐲");}}if(m) {}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐃");}}else if(k.KKM(e,16400,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑉");}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐋");}}else if(k.KKM(e,16400,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑇");}}return r;};} \ No newline at end of file diff --git a/keyboard/newa_traditional_extended/1.0.1/newa_traditional_extended-1.0.1.js b/keyboard/newa_traditional_extended/1.0.1/newa_traditional_extended-1.0.1.js new file mode 100644 index 000000000..ac9c19dde --- /dev/null +++ b/keyboard/newa_traditional_extended/1.0.1/newa_traditional_extended-1.0.1.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_newa_traditional_extended());}function Keyboard_newa_traditional_extended(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_newa_traditional_extended";this.KN="Newa Traditional Extended";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={"shift": ["𑑇","𑐖𑑂𑐘","𑐃","𑐑","𑐒","𑐕","𑐚","𑐛","𑐜","𑐝","𑐞","𑐍","𑑄","","","","𑑊","𑑏","𑐋","𑐴𑑂𑐬","𑐟𑑂𑐬","❈","𑐅","𑐎𑑂𑐲","𑐂","𑐊","dead","𑐿","zwj","","","","𑐁","𑐫𑑂‌","𑐩𑑂𑐴","𑑃","𑐣𑑂𑐴","𑐗","𑑀","𑐦","𑐷","𑑎","𑐹","","","","","","","𑐱𑑂𑐬","𑑝","𑐆","𑑈","𑑁","𑐮𑑂𑐴","𑑅","𑑚","𑑌","?","","","","","",""],"default": ["𑐘","𑑑","𑑒","𑑓","𑑔","𑑕","𑑖","𑑗","𑑘","𑑙","𑑐","𑐌",".","","","","𑑉","𑐢","𑐨","𑐔","𑐟","𑐠","𑐐","𑐲","𑐫","𑐄","𑐺","𑐾","𑑂","","","","𑐧","𑐎","𑐩","𑐵","𑐣","𑐖","𑐰","𑐥","𑐶","𑐳","𑐸","","","","","","","𑐱","𑐴","𑐀","𑐏","𑐡","𑐮","zwnj","𑑍","𑑋","𑐬","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH='';this.KM=0;this.KBVER="1.0.1";this.KMBM=0x0010;this.KS=1;this.KVKD="T_half_ya_zwnj";this.KVKL={"phone":{"font":"Noto Sans Newa","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_W","text":"\uD805\uDC22"},{"id":"K_E","text":"\uD805\uDC28"},{"id":"K_R","text":"\uD805\uDC14"},{"id":"K_T","text":"\uD805\uDC1F","sk":[{"layer":"shift","id":"K_T","text":"\uD805\uDC1F\uD805\uDC42\uD805\uDC2C"}]},{"id":"K_Y","text":"\uD805\uDC20"},{"id":"K_U","text":"\uD805\uDC10"},{"id":"K_O","text":"\uD805\uDC2B","sk":[{"id":"T_half_ya_zwnj","text":"\uD805\uDC2B\uD805\uDC42\u200C"}]},{"id":"K_P","text":"\uD805\uDC04","sk":[{"layer":"shift","id":"K_U","text":"\uD805\uDC05"}]},{"layer":"shift","id":"K_P","text":"\uD805\uDC0A","sk":[{"layer":"shift","id":"K_E","text":"\uD805\uDC0B"}]},{"id":"K_BKSLASH","text":"\uD805\uDC42","sk":[{"id":"K_LBRKT","text":"\uD805\uDC3A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC27"},{"id":"K_S","text":"\uD805\uDC0E"},{"id":"K_D","text":"\uD805\uDC29"},{"id":"K_F","text":"\uD805\uDC35","sk":[{"layer":"shift","id":"K_M","text":"\uD805\uDC45"}]},{"id":"K_G","text":"\uD805\uDC23","sk":[{"layer":"shift","id":"K_G","text":"\uD805\uDC24"}]},{"id":"K_H","text":"\uD805\uDC16","sk":[{"layer":"shift","id":"K_1","text":"\uD805\uDC16\uD805\uDC42\uD805\uDC18"}]},{"id":"K_J","text":"\uD805\uDC30"},{"id":"K_K","text":"\uD805\uDC25"},{"id":"K_COLON","text":"\uD805\uDC33"},{"id":"K_L","text":"\uD805\uDC36","sk":[{"layer":"shift","id":"K_L","text":"\uD805\uDC37"},{"id":"K_QUOTE","text":"\uD805\uDC38"},{"layer":"shift","id":"K_QUOTE","text":"\uD805\uDC39"}]}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31"},{"id":"K_X","text":"\uD805\uDC34"},{"id":"K_C","text":"\uD805\uDC00"},{"id":"K_V","text":"\uD805\uDC0F"},{"id":"K_B","text":"\uD805\uDC21"},{"id":"K_N","text":"\uD805\uDC2E"},{"id":"K_SLASH","text":"\uD805\uDC2C","sk":[{"layer":"shift","id":"K_R","text":"\uD805\uDC2D"}]},{"id":"K_PERIOD","text":"\uD805\uDC4B","sk":[{"id":"U_1144C","text":"\uD805\uDC4C"},{"layer":"shift","id":"K_SLASH","text":"?"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"layer":"default","id":"K_BKQUOTE","text":"\uD805\uDC18","sk":[{"id":"U_11419","text":"\uD805\uDC19"}]},{"id":"K_3","text":"\uD805\uDC11"},{"id":"K_4","text":"\uD805\uDC12","sk":[{"id":"U_11413","text":"\uD805\uDC13"}]},{"id":"K_5","text":"\uD805\uDC15"},{"id":"K_6","text":"\uD805\uDC1A"},{"id":"K_7","text":"\uD805\uDC1B"},{"id":"K_8","text":"\uD805\uDC1C"},{"id":"K_9","text":"\uD805\uDC1D"},{"layer":"default","id":"K_HYPHEN","text":"\uD805\uDC0C","sk":[{"layer":"shift","id":"K_HYPHEN","text":"\uD805\uDC0D"}]},{"layer":"default","id":"K_Q","text":"\uD805\uDC49","sk":[{"layer":"shift","id":"K_Q","text":"\uD805\uDC4A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC01"},{"id":"K_I","text":"\uD805\uDC0E\uD805\uDC42\uD805\uDC32"},{"id":"K_D","text":"\uD805\uDC2A"},{"id":"K_F","text":"\uD805\uDC43","sk":[{"layer":"shift","id":"K_EQUAL","text":"\uD805\uDC44"}]},{"id":"K_0","text":"\uD805\uDC1E"},{"id":"K_H","text":"\uD805\uDC17"},{"id":"K_J","text":"\uD805\uDC40","sk":[{"layer":"shift","id":"K_B","text":"\uD805\uDC41"}]},{"id":"K_K","text":"\uD805\uDC26"},{"layer":"default","id":"K_I","text":"\uD805\uDC32"},{"layer":"default","id":"K_M","text":"zwnj","sk":[{"layer":"shift","id":"K_BKSLASH","text":"zwj"}]}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31\uD805\uDC42\uD805\uDC2C"},{"id":"K_BKQUOTE","text":"\uD805\uDC47"},{"id":"K_C","text":"\uD805\uDC06","sk":[{"id":"U_11407","text":"\uD805\uDC07"}]},{"layer":"shift","id":"K_O","text":"\uD805\uDC02"},{"layer":"shift","id":"K_2","text":"\uD805\uDC03"},{"id":"K_N","text":"\uD805\uDC2F","sk":[{"id":"U_11408","text":"\uD805\uDC08"},{"id":"U_1143C","text":"\uD805\uDC3C"},{"id":"U_11409","text":"\uD805\uDC09"},{"id":"U_1143D","text":"\uD805\uDC3D"}]},{"layer":"default","id":"K_COMMA","text":"\uD805\uDC4D","sk":[{"id":"U_1145A","text":"\uD805\uDC5A"},{"id":"U_002C","text":","}]},{"id":"K_V","text":"\uD805\uDC48"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","text":"\uD805\uDC51","sk":[{"id":"U_0031","text":"1"}]},{"id":"K_2","text":"\uD805\uDC52","sk":[{"id":"U_0032","text":"2"}]},{"id":"K_3","text":"\uD805\uDC53","sk":[{"id":"U_0033","text":"3"}]},{"id":"K_4","text":"\uD805\uDC54","sk":[{"id":"U_0034","text":"4"}]},{"id":"K_5","text":"\uD805\uDC55","sk":[{"id":"U_0035","text":"5"}]},{"id":"K_6","text":"\uD805\uDC56","sk":[{"id":"U_0036","text":"6"}]},{"id":"K_7","text":"\uD805\uDC57","sk":[{"id":"U_0037","text":"7"}]},{"id":"K_8","text":"\uD805\uDC58","sk":[{"id":"U_0038","text":"8"}]},{"id":"K_9","text":"\uD805\uDC59","sk":[{"id":"U_0039","text":"9"}]},{"id":"K_0","text":"\uD805\uDC50","sk":[{"id":"U_0030","text":"0"}]}]},{"id":"2","key":[{"id":"U_0021","text":"!"},{"id":"U_0040","text":"@"},{"id":"U_0023","text":"#"},{"id":"U_0024","text":"$"},{"id":"U_0025","text":"%"},{"id":"U_005E","text":"^"},{"id":"U_0026","text":"&"},{"id":"U_002A","text":"*"},{"id":"U_0028","text":"(","sk":[{"id":"U_007B","text":"{"},{"id":"U_005B","text":"["}]},{"id":"U_0029","text":")","sk":[{"id":"U_007D","text":"}"},{"id":"U_005D","text":"]"}]}]},{"id":"3","key":[{"layer":"shift","id":"K_Y","text":"\u2748","sk":[{"id":"U_1145B","text":"\uD805\uDC5B"},{"id":"U_1145E","text":"\uD805\uDC5E"},{"id":"U_1145F","text":"\uD805\uDC5F"}]},{"id":"U_003C","text":"<","sk":[{"id":"U_00AB","text":"\u00AB"}]},{"id":"U_002D","text":"-","sk":[{"id":"U_005F","text":"_"}]},{"id":"U_003D","text":"=","sk":[{"id":"U_002B","text":"+"}]},{"id":"U_003E","text":">","sk":[{"id":"U_00BB","text":"\u00BB"}]},{"layer":"shift","id":"K_X","text":"\uD805\uDC5D"},{"layer":"shift","id":"K_COLON","text":"\uD805\uDC4E"},{"layer":"shift","id":"K_W","text":"\uD805\uDC4F"},{"id":"K_EQUAL","text":"."},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"\uD805\uDC0E\uD805\uDC0F\uD805\uDC10"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]},"tablet":{"font":"Noto Sans Newa","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_W","text":"\uD805\uDC22"},{"id":"K_E","text":"\uD805\uDC28"},{"id":"K_R","text":"\uD805\uDC14"},{"id":"K_T","text":"\uD805\uDC1F","sk":[{"layer":"shift","id":"K_T","text":"\uD805\uDC1F\uD805\uDC42\uD805\uDC2C"}]},{"id":"K_Y","text":"\uD805\uDC20"},{"id":"K_U","text":"\uD805\uDC10"},{"id":"K_O","text":"\uD805\uDC2B","sk":[{"id":"T_half_ya_zwnj","text":"\uD805\uDC2B\uD805\uDC42\u200C"}]},{"id":"K_P","text":"\uD805\uDC04","sk":[{"layer":"shift","id":"K_U","text":"\uD805\uDC05"}]},{"layer":"shift","id":"K_P","text":"\uD805\uDC0A","sk":[{"layer":"shift","id":"K_E","text":"\uD805\uDC0B"}]},{"id":"K_BKSLASH","text":"\uD805\uDC42","sk":[{"id":"K_LBRKT","text":"\uD805\uDC3A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC27"},{"id":"K_S","text":"\uD805\uDC0E"},{"id":"K_D","text":"\uD805\uDC29"},{"id":"K_F","text":"\uD805\uDC35","sk":[{"layer":"shift","id":"K_M","text":"\uD805\uDC45"}]},{"id":"K_G","text":"\uD805\uDC23","sk":[{"layer":"shift","id":"K_G","text":"\uD805\uDC24"}]},{"id":"K_H","text":"\uD805\uDC16","sk":[{"layer":"shift","id":"K_1","text":"\uD805\uDC16\uD805\uDC42\uD805\uDC18"}]},{"id":"K_J","text":"\uD805\uDC30"},{"id":"K_K","text":"\uD805\uDC25"},{"id":"K_COLON","text":"\uD805\uDC33"},{"id":"K_L","text":"\uD805\uDC36","sk":[{"layer":"shift","id":"K_L","text":"\uD805\uDC37"},{"id":"K_QUOTE","text":"\uD805\uDC38"},{"layer":"shift","id":"K_QUOTE","text":"\uD805\uDC39"}]}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31"},{"id":"K_X","text":"\uD805\uDC34"},{"id":"K_C","text":"\uD805\uDC00"},{"id":"K_V","text":"\uD805\uDC0F"},{"id":"K_B","text":"\uD805\uDC21"},{"id":"K_N","text":"\uD805\uDC2E"},{"id":"K_SLASH","text":"\uD805\uDC2C","sk":[{"layer":"shift","id":"K_R","text":"\uD805\uDC2D"}]},{"id":"K_PERIOD","text":"\uD805\uDC4B","sk":[{"id":"U_1144C","text":"\uD805\uDC4C"},{"layer":"shift","id":"K_SLASH","text":"?"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"layer":"default","id":"K_BKQUOTE","text":"\uD805\uDC18","sk":[{"id":"U_11419","text":"\uD805\uDC19"}]},{"id":"K_3","text":"\uD805\uDC11"},{"id":"K_4","text":"\uD805\uDC12","sk":[{"id":"U_11413","text":"\uD805\uDC13"}]},{"id":"K_5","text":"\uD805\uDC15"},{"id":"K_6","text":"\uD805\uDC1A"},{"id":"K_7","text":"\uD805\uDC1B"},{"id":"K_8","text":"\uD805\uDC1C"},{"id":"K_9","text":"\uD805\uDC1D"},{"layer":"default","id":"K_HYPHEN","text":"\uD805\uDC0C","sk":[{"layer":"shift","id":"K_HYPHEN","text":"\uD805\uDC0D"}]},{"layer":"default","id":"K_Q","text":"\uD805\uDC49","sk":[{"layer":"shift","id":"K_Q","text":"\uD805\uDC4A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC01"},{"id":"K_I","text":"\uD805\uDC0E\uD805\uDC42\uD805\uDC32"},{"id":"K_D","text":"\uD805\uDC2A"},{"id":"K_F","text":"\uD805\uDC43","sk":[{"layer":"shift","id":"K_EQUAL","text":"\uD805\uDC44"}]},{"id":"K_0","text":"\uD805\uDC1E"},{"id":"K_H","text":"\uD805\uDC17"},{"id":"K_J","text":"\uD805\uDC40","sk":[{"layer":"shift","id":"K_B","text":"\uD805\uDC41"}]},{"id":"K_K","text":"\uD805\uDC26"},{"layer":"default","id":"K_I","text":"\uD805\uDC32"},{"layer":"default","id":"K_M","text":"zwnj","sk":[{"layer":"shift","id":"K_BKSLASH","text":"zwj"}]}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31\uD805\uDC42\uD805\uDC2C"},{"id":"K_BKQUOTE","text":"\uD805\uDC47"},{"id":"K_C","text":"\uD805\uDC06","sk":[{"id":"U_11407","text":"\uD805\uDC07"}]},{"layer":"shift","id":"K_O","text":"\uD805\uDC02"},{"layer":"shift","id":"K_2","text":"\uD805\uDC03"},{"id":"K_N","text":"\uD805\uDC2F","sk":[{"id":"U_11408","text":"\uD805\uDC08"},{"id":"U_1143C","text":"\uD805\uDC3C"},{"id":"U_11409","text":"\uD805\uDC09"},{"id":"U_1143D","text":"\uD805\uDC3D"}]},{"layer":"default","id":"K_COMMA","text":"\uD805\uDC4D","sk":[{"id":"U_1145A","text":"\uD805\uDC5A"},{"id":"U_002C","text":","}]},{"id":"K_V","text":"\uD805\uDC48"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","text":"\uD805\uDC51","sk":[{"id":"U_0031","text":"1"}]},{"id":"K_2","text":"\uD805\uDC52","sk":[{"id":"U_0032","text":"2"}]},{"id":"K_3","text":"\uD805\uDC53","sk":[{"id":"U_0033","text":"3"}]},{"id":"K_4","text":"\uD805\uDC54","sk":[{"id":"U_0034","text":"4"}]},{"id":"K_5","text":"\uD805\uDC55","sk":[{"id":"U_0035","text":"5"}]},{"id":"K_6","text":"\uD805\uDC56","sk":[{"id":"U_0036","text":"6"}]},{"id":"K_7","text":"\uD805\uDC57","sk":[{"id":"U_0037","text":"7"}]},{"id":"K_8","text":"\uD805\uDC58","sk":[{"id":"U_0038","text":"8"}]},{"id":"K_9","text":"\uD805\uDC59","sk":[{"id":"U_0039","text":"9"}]},{"id":"K_0","text":"\uD805\uDC50","sk":[{"id":"U_0030","text":"0"}]}]},{"id":"2","key":[{"id":"U_0021","text":"!"},{"id":"U_0040","text":"@"},{"id":"U_0023","text":"#"},{"id":"U_0024","text":"$"},{"id":"U_0025","text":"%"},{"id":"U_005E","text":"^"},{"id":"U_0026","text":"&"},{"id":"U_002A","text":"*"},{"id":"U_0028","text":"(","sk":[{"id":"U_007B","text":"{"},{"id":"U_005B","text":"["}]},{"id":"U_0029","text":")","sk":[{"id":"U_007D","text":"}"},{"id":"U_005D","text":"]"}]}]},{"id":"3","key":[{"layer":"shift","id":"K_Y","text":"\u2748","sk":[{"id":"U_1145B","text":"\uD805\uDC5B"},{"id":"U_1145E","text":"\uD805\uDC5E"},{"id":"U_1145F","text":"\uD805\uDC5F"}]},{"id":"U_003C","text":"<","sk":[{"id":"U_00AB","text":"\u00AB"}]},{"id":"U_002D","text":"-","sk":[{"id":"U_005F","text":"_"}]},{"id":"U_003D","text":"=","sk":[{"id":"U_002B","text":"+"}]},{"id":"U_003E","text":">","sk":[{"id":"U_00BB","text":"\u00BB"}]},{"layer":"shift","id":"K_X","text":"\uD805\uDC5D"},{"layer":"shift","id":"K_COLON","text":"\uD805\uDC4E"},{"layer":"shift","id":"K_W","text":"\uD805\uDC4F"},{"id":"K_EQUAL","text":"."},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"\uD805\uDC0E\uD805\uDC0F\uD805\uDC10"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫𑑂‌");}}else if(k.KKM(e,16400,49)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"!");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐖𑑂𑐘");}}else if(k.KKM(e,16400,222)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"\"");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐹");}}else if(k.KKM(e,16400,51)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"#");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐑");}}else if(k.KKM(e,16400,52)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"$");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐒");}}else if(k.KKM(e,16400,53)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"%");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐕");}}else if(k.KKM(e,16400,55)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"&");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐛");}}else if(k.KKM(e,16384,222)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"'");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐸");}}else if(k.KKM(e,16400,57)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"(");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐝");}}else if(k.KKM(e,16400,48)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,")");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐞");}}else if(k.KKM(e,16400,56)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"*");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐜");}}else if(k.KKM(e,16400,187)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"+");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑄");}}else if(k.KKM(e,16384,188)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,",");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑍");}}else if(k.KKM(e,16384,189)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"-");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐌");}}else if(k.KKM(e,16384,190)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,".");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑋");}}else if(k.KKM(e,16384,191)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"/");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐬");}}else if(k.KKM(e,16384,48)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,")");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑐");}}else if(k.KKM(e,16384,49)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"!");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑑");}}else if(k.KKM(e,16384,50)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"@");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑒");}}else if(k.KKM(e,16384,51)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"#");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑓");}}else if(k.KKM(e,16384,52)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"$");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑔");}}else if(k.KKM(e,16384,53)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"%");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑕");}}else if(k.KKM(e,16384,54)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"^");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑖");}}else if(k.KKM(e,16384,55)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"&");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑗");}}else if(k.KKM(e,16384,56)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"*");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑘");}}else if(k.KKM(e,16384,57)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"(");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑙");}}else if(k.KKM(e,16400,186)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,":");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑎");}}else if(k.KKM(e,16384,186)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,";");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐳");}}else if(k.KKM(e,16400,188)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"<");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑚");}}else if(k.KKM(e,16384,187)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"=");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,".");}}else if(k.KKM(e,16400,190)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,">");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑌");}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"?");}}else if(k.KKM(e,16400,50)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"@");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐃");}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐁");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑁");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐆");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐩𑑂𑐴");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐋");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑃");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐣𑑂𑐴");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐗");}}else if(k.KKM(e,16400,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐎𑑂𑐲");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑀");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐦");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐷");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑅");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐮𑑂𑐴");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐂");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐊");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑊");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐴𑑂𑐬");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫𑑂‌");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐟𑑂𑐬");}}else if(k.KKM(e,16400,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐅");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑈");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑏");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑝");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"❈");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐱𑑂𑐬");}}else if(k.KKM(e,16384,219)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"[");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐺");}}else if(k.KKM(e,16384,220)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"\\");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑂");}}else if(k.KKM(e,16384,221)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"]");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐾");}}else if(k.KKM(e,16400,54)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"^");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐚");}}else if(k.KKM(e,16400,189)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"_");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐍");}}else if(k.KKM(e,16384,192)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"`");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐘");}}else if(k.KKM(e,16384,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐧");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐡");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐀");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐩");}}else if(k.KKM(e,16384,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐨");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐵");}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐣");}}else if(k.KKM(e,16384,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐖");}}else if(k.KKM(e,16384,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐲");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐰");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐥");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐶");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐮");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐄");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑉");}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐔");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐎");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐟");}}else if(k.KKM(e,16384,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐐");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐏");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐢");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐴");}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐠");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐱");}}else if(k.KKM(e,16400,219)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"{");}else if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,0);}}else if(k.KKM(e,16400,220)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"|");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‍");}}else if(k.KKM(e,16400,221)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"}");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐿");}}else if(k.KKM(e,16400,192)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"~");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑇");}}return r;};} \ No newline at end of file diff --git a/keyboard/newa_traditional_extended/1.0/newa_traditional_extended-1.0.js b/keyboard/newa_traditional_extended/1.0/newa_traditional_extended-1.0.js new file mode 100644 index 000000000..ab5207563 --- /dev/null +++ b/keyboard/newa_traditional_extended/1.0/newa_traditional_extended-1.0.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_newa_traditional_extended());}function Keyboard_newa_traditional_extended(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_newa_traditional_extended";this.KN="Newa Traditional Extended";this.KMINVER="10.0";this.KV={F:' 1em "Arial"',K102:0};this.KV.KLS={"shift": ["𑑇","𑐖𑑂𑐘","𑐃","𑐑","𑐒","𑐕","𑐚","𑐛","𑐜","𑐝","𑐞","𑐍","𑑄","","","","𑑊","𑑏","𑐋","𑐴𑑂𑐬","𑐟𑑂𑐬","❈","𑐅","𑐎𑑂𑐲","𑐂","𑐊","","𑐿","‍","","","","𑐁","𑐫𑑂‌","𑐩𑑂𑐴","𑑃","𑐣𑑂𑐴","𑐗","𑑀","𑐦","𑐷","𑑎","𑐹","","","","","","","𑐱𑑂𑐬","𑑝","𑐆","𑑈","𑑁","𑐮𑑂𑐴","𑑅","𑑚","𑑌","?","","","","","",""],"default": ["𑐘","𑑑","𑑒","𑑓","𑑔","𑑕","𑑖","𑑗","𑑘","𑑙","𑑐","𑐌",".","","","","𑑉","𑐢","𑐨","𑐔","𑐟","𑐠","𑐐","𑐲","𑐫","𑐄","𑐺","𑐾","𑑂","","","","𑐧","𑐎","𑐩","𑐵","𑐣","𑐖","𑐰","𑐥","𑐶","𑐳","𑐸","","","","","","","𑐱","𑐴","𑐀","𑐏","𑐡","𑐮","‌","𑑍","𑑋","𑐬","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH='';this.KM=0;this.KBVER="1.0";this.KMBM=0x0010;this.KS=1;this.KVKD="T_half_ya_zwnj";this.KVKL={"phone":{"font":"Noto Sans Newa","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_W","text":"\uD805\uDC22"},{"id":"K_E","text":"\uD805\uDC28"},{"id":"K_R","text":"\uD805\uDC14"},{"id":"K_T","text":"\uD805\uDC1F","sk":[{"layer":"shift","id":"K_T","text":"\uD805\uDC1F\uD805\uDC42\uD805\uDC2C"}]},{"id":"K_Y","text":"\uD805\uDC20"},{"id":"K_U","text":"\uD805\uDC10"},{"id":"K_O","text":"\uD805\uDC2B","sk":[{"id":"T_half_ya_zwnj","text":"\uD805\uDC2B\uD805\uDC42\u200C"}]},{"id":"K_P","text":"\uD805\uDC04","sk":[{"layer":"shift","id":"K_U","text":"\uD805\uDC05"}]},{"layer":"shift","id":"K_P","text":"\uD805\uDC0A","sk":[{"layer":"shift","id":"K_E","text":"\uD805\uDC0B"}]},{"id":"K_BKSLASH","text":"\uD805\uDC42","sk":[{"id":"K_LBRKT","text":"\uD805\uDC3A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC27"},{"id":"K_S","text":"\uD805\uDC0E"},{"id":"K_D","text":"\uD805\uDC29"},{"id":"K_F","text":"\uD805\uDC35","sk":[{"layer":"shift","id":"K_M","text":"\uD805\uDC45"}]},{"id":"K_G","text":"\uD805\uDC23","sk":[{"layer":"shift","id":"K_G","text":"\uD805\uDC24"}]},{"id":"K_H","text":"\uD805\uDC16","sk":[{"layer":"shift","id":"K_1","text":"\uD805\uDC16\uD805\uDC42\uD805\uDC18"}]},{"id":"K_J","text":"\uD805\uDC30"},{"id":"K_K","text":"\uD805\uDC25"},{"id":"K_COLON","text":"\uD805\uDC33"},{"id":"K_L","text":"\uD805\uDC36","sk":[{"layer":"shift","id":"K_L","text":"\uD805\uDC37"},{"id":"K_QUOTE","text":"\uD805\uDC38"},{"layer":"shift","id":"K_QUOTE","text":"\uD805\uDC39"}]}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31"},{"id":"K_X","text":"\uD805\uDC34"},{"id":"K_C","text":"\uD805\uDC00"},{"id":"K_V","text":"\uD805\uDC0F"},{"id":"K_B","text":"\uD805\uDC21"},{"id":"K_N","text":"\uD805\uDC2E"},{"id":"K_SLASH","text":"\uD805\uDC2C","sk":[{"layer":"shift","id":"K_R","text":"\uD805\uDC2D"}]},{"id":"K_PERIOD","text":"\uD805\uDC4B","sk":[{"id":"U_1144C","text":"\uD805\uDC4C"},{"layer":"shift","id":"K_SLASH","text":"?"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"layer":"default","id":"K_BKQUOTE","text":"\uD805\uDC18","sk":[{"id":"U_11419","text":"\uD805\uDC19"}]},{"id":"K_3","text":"\uD805\uDC11"},{"id":"K_4","text":"\uD805\uDC12","sk":[{"id":"U_11413","text":"\uD805\uDC13"}]},{"id":"K_5","text":"\uD805\uDC15"},{"id":"K_6","text":"\uD805\uDC1A"},{"id":"K_7","text":"\uD805\uDC1B"},{"id":"K_8","text":"\uD805\uDC1C"},{"id":"K_9","text":"\uD805\uDC1D"},{"layer":"default","id":"K_HYPHEN","text":"\uD805\uDC0C","sk":[{"layer":"shift","id":"K_HYPHEN","text":"\uD805\uDC0D"}]},{"layer":"default","id":"K_Q","text":"\uD805\uDC49","sk":[{"layer":"shift","id":"K_Q","text":"\uD805\uDC4A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC01"},{"id":"K_I","text":"\uD805\uDC0E\uD805\uDC42\uD805\uDC32"},{"id":"K_D","text":"\uD805\uDC2A"},{"id":"K_F","text":"\uD805\uDC43","sk":[{"layer":"shift","id":"K_EQUAL","text":"\uD805\uDC44"}]},{"id":"K_0","text":"\uD805\uDC1E"},{"id":"K_H","text":"\uD805\uDC17"},{"id":"K_J","text":"\uD805\uDC40","sk":[{"layer":"shift","id":"K_B","text":"\uD805\uDC41"}]},{"id":"K_K","text":"\uD805\uDC26"},{"layer":"default","id":"K_I","text":"\uD805\uDC32"},{"layer":"default","id":"K_M","text":"zwnj","sk":[{"layer":"shift","id":"K_BKSLASH","text":"zwj"}]}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31\uD805\uDC42\uD805\uDC2C"},{"id":"K_BKQUOTE","text":"\uD805\uDC47"},{"id":"K_C","text":"\uD805\uDC06","sk":[{"id":"U_11407","text":"\uD805\uDC07"}]},{"layer":"shift","id":"K_O","text":"\uD805\uDC02"},{"layer":"shift","id":"K_2","text":"\uD805\uDC03"},{"id":"K_N","text":"\uD805\uDC2F","sk":[{"id":"U_11408","text":"\uD805\uDC08"},{"id":"U_1143C","text":"\uD805\uDC3C"},{"id":"U_11409","text":"\uD805\uDC09"},{"id":"U_1143D","text":"\uD805\uDC3D"}]},{"layer":"default","id":"K_COMMA","text":"\uD805\uDC4D","sk":[{"id":"U_1145A","text":"\uD805\uDC5A"},{"id":"U_002C","text":","}]},{"id":"K_V","text":"\uD805\uDC48"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","text":"\uD805\uDC51","sk":[{"id":"U_0031","text":"1"}]},{"id":"K_2","text":"\uD805\uDC52","sk":[{"id":"U_0032","text":"2"}]},{"id":"K_3","text":"\uD805\uDC53","sk":[{"id":"U_0033","text":"3"}]},{"id":"K_4","text":"\uD805\uDC54","sk":[{"id":"U_0034","text":"4"}]},{"id":"K_5","text":"\uD805\uDC55","sk":[{"id":"U_0035","text":"5"}]},{"id":"K_6","text":"\uD805\uDC56","sk":[{"id":"U_0036","text":"6"}]},{"id":"K_7","text":"\uD805\uDC57","sk":[{"id":"U_0037","text":"7"}]},{"id":"K_8","text":"\uD805\uDC58","sk":[{"id":"U_0038","text":"8"}]},{"id":"K_9","text":"\uD805\uDC59","sk":[{"id":"U_0039","text":"9"}]},{"id":"K_0","text":"\uD805\uDC50","sk":[{"id":"U_0030","text":"0"}]}]},{"id":"2","key":[{"id":"U_0021","text":"!"},{"id":"U_0040","text":"@"},{"id":"U_0023","text":"#"},{"id":"U_0024","text":"$"},{"id":"U_0025","text":"%"},{"id":"U_005E","text":"^"},{"id":"U_0026","text":"&"},{"id":"U_002A","text":"*"},{"id":"U_0028","text":"(","sk":[{"id":"U_007B","text":"{"},{"id":"U_005B","text":"["}]},{"id":"U_0029","text":")","sk":[{"id":"U_007D","text":"}"},{"id":"U_005D","text":"]"}]}]},{"id":"3","key":[{"layer":"shift","id":"K_Y","text":"\u2748","sk":[{"id":"U_1145B","text":"\uD805\uDC5B"},{"id":"U_1145E","text":"\uD805\uDC5E"},{"id":"U_1145F","text":"\uD805\uDC5F"}]},{"id":"U_003C","text":"<","sk":[{"id":"U_00AB","text":"\u00AB"}]},{"id":"U_002D","text":"-","sk":[{"id":"U_005F","text":"_"}]},{"id":"U_003D","text":"=","sk":[{"id":"U_002B","text":"+"}]},{"id":"U_003E","text":">","sk":[{"id":"U_00BB","text":"\u00BB"}]},{"layer":"shift","id":"K_X","text":"\uD805\uDC5D"},{"layer":"shift","id":"K_COLON","text":"\uD805\uDC4E"},{"layer":"shift","id":"K_W","text":"\uD805\uDC4F"},{"id":"K_EQUAL","text":"."},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"\uD805\uDC0E\uD805\uDC0F\uD805\uDC10"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]},"tablet":{"font":"Noto Sans Newa","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_W","text":"\uD805\uDC22"},{"id":"K_E","text":"\uD805\uDC28"},{"id":"K_R","text":"\uD805\uDC14"},{"id":"K_T","text":"\uD805\uDC1F","sk":[{"layer":"shift","id":"K_T","text":"\uD805\uDC1F\uD805\uDC42\uD805\uDC2C"}]},{"id":"K_Y","text":"\uD805\uDC20"},{"id":"K_U","text":"\uD805\uDC10"},{"id":"K_O","text":"\uD805\uDC2B","sk":[{"id":"T_half_ya_zwnj","text":"\uD805\uDC2B\uD805\uDC42\u200C"}]},{"id":"K_P","text":"\uD805\uDC04","sk":[{"layer":"shift","id":"K_U","text":"\uD805\uDC05"}]},{"layer":"shift","id":"K_P","text":"\uD805\uDC0A","sk":[{"layer":"shift","id":"K_E","text":"\uD805\uDC0B"}]},{"id":"K_BKSLASH","text":"\uD805\uDC42","sk":[{"id":"K_LBRKT","text":"\uD805\uDC3A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC27"},{"id":"K_S","text":"\uD805\uDC0E"},{"id":"K_D","text":"\uD805\uDC29"},{"id":"K_F","text":"\uD805\uDC35","sk":[{"layer":"shift","id":"K_M","text":"\uD805\uDC45"}]},{"id":"K_G","text":"\uD805\uDC23","sk":[{"layer":"shift","id":"K_G","text":"\uD805\uDC24"}]},{"id":"K_H","text":"\uD805\uDC16","sk":[{"layer":"shift","id":"K_1","text":"\uD805\uDC16\uD805\uDC42\uD805\uDC18"}]},{"id":"K_J","text":"\uD805\uDC30"},{"id":"K_K","text":"\uD805\uDC25"},{"id":"K_COLON","text":"\uD805\uDC33"},{"id":"K_L","text":"\uD805\uDC36","sk":[{"layer":"shift","id":"K_L","text":"\uD805\uDC37"},{"id":"K_QUOTE","text":"\uD805\uDC38"},{"layer":"shift","id":"K_QUOTE","text":"\uD805\uDC39"}]}]},{"id":"3","key":[{"nextlayer":"shift","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31"},{"id":"K_X","text":"\uD805\uDC34"},{"id":"K_C","text":"\uD805\uDC00"},{"id":"K_V","text":"\uD805\uDC0F"},{"id":"K_B","text":"\uD805\uDC21"},{"id":"K_N","text":"\uD805\uDC2E"},{"id":"K_SLASH","text":"\uD805\uDC2C","sk":[{"layer":"shift","id":"K_R","text":"\uD805\uDC2D"}]},{"id":"K_PERIOD","text":"\uD805\uDC4B","sk":[{"id":"U_1144C","text":"\uD805\uDC4C"},{"layer":"shift","id":"K_SLASH","text":"?"}]},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"layer":"default","id":"K_BKQUOTE","text":"\uD805\uDC18","sk":[{"id":"U_11419","text":"\uD805\uDC19"}]},{"id":"K_3","text":"\uD805\uDC11"},{"id":"K_4","text":"\uD805\uDC12","sk":[{"id":"U_11413","text":"\uD805\uDC13"}]},{"id":"K_5","text":"\uD805\uDC15"},{"id":"K_6","text":"\uD805\uDC1A"},{"id":"K_7","text":"\uD805\uDC1B"},{"id":"K_8","text":"\uD805\uDC1C"},{"id":"K_9","text":"\uD805\uDC1D"},{"layer":"default","id":"K_HYPHEN","text":"\uD805\uDC0C","sk":[{"layer":"shift","id":"K_HYPHEN","text":"\uD805\uDC0D"}]},{"layer":"default","id":"K_Q","text":"\uD805\uDC49","sk":[{"layer":"shift","id":"K_Q","text":"\uD805\uDC4A"}]}]},{"id":"2","key":[{"id":"K_A","text":"\uD805\uDC01"},{"id":"K_I","text":"\uD805\uDC0E\uD805\uDC42\uD805\uDC32"},{"id":"K_D","text":"\uD805\uDC2A"},{"id":"K_F","text":"\uD805\uDC43","sk":[{"layer":"shift","id":"K_EQUAL","text":"\uD805\uDC44"}]},{"id":"K_0","text":"\uD805\uDC1E"},{"id":"K_H","text":"\uD805\uDC17"},{"id":"K_J","text":"\uD805\uDC40","sk":[{"layer":"shift","id":"K_B","text":"\uD805\uDC41"}]},{"id":"K_K","text":"\uD805\uDC26"},{"layer":"default","id":"K_I","text":"\uD805\uDC32"},{"layer":"default","id":"K_M","text":"zwnj","sk":[{"layer":"shift","id":"K_BKSLASH","text":"zwj"}]}]},{"id":"3","key":[{"nextlayer":"default","id":"K_SHIFT","sp":"2","text":"*Shift*"},{"id":"K_Z","text":"\uD805\uDC31\uD805\uDC42\uD805\uDC2C"},{"id":"K_BKQUOTE","text":"\uD805\uDC47"},{"id":"K_C","text":"\uD805\uDC06","sk":[{"id":"U_11407","text":"\uD805\uDC07"}]},{"layer":"shift","id":"K_O","text":"\uD805\uDC02"},{"layer":"shift","id":"K_2","text":"\uD805\uDC03"},{"id":"K_N","text":"\uD805\uDC2F","sk":[{"id":"U_11408","text":"\uD805\uDC08"},{"id":"U_1143C","text":"\uD805\uDC3C"},{"id":"U_11409","text":"\uD805\uDC09"},{"id":"U_1143D","text":"\uD805\uDC3D"}]},{"layer":"default","id":"K_COMMA","text":"\uD805\uDC4D","sk":[{"id":"U_1145A","text":"\uD805\uDC5A"},{"id":"U_002C","text":","}]},{"id":"K_V","text":"\uD805\uDC48"},{"id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"\uD805\uDC51\uD805\uDC47!"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"numeric","row":[{"id":"1","key":[{"id":"K_1","text":"\uD805\uDC51","sk":[{"id":"U_0031","text":"1"}]},{"id":"K_2","text":"\uD805\uDC52","sk":[{"id":"U_0032","text":"2"}]},{"id":"K_3","text":"\uD805\uDC53","sk":[{"id":"U_0033","text":"3"}]},{"id":"K_4","text":"\uD805\uDC54","sk":[{"id":"U_0034","text":"4"}]},{"id":"K_5","text":"\uD805\uDC55","sk":[{"id":"U_0035","text":"5"}]},{"id":"K_6","text":"\uD805\uDC56","sk":[{"id":"U_0036","text":"6"}]},{"id":"K_7","text":"\uD805\uDC57","sk":[{"id":"U_0037","text":"7"}]},{"id":"K_8","text":"\uD805\uDC58","sk":[{"id":"U_0038","text":"8"}]},{"id":"K_9","text":"\uD805\uDC59","sk":[{"id":"U_0039","text":"9"}]},{"id":"K_0","text":"\uD805\uDC50","sk":[{"id":"U_0030","text":"0"}]}]},{"id":"2","key":[{"id":"U_0021","text":"!"},{"id":"U_0040","text":"@"},{"id":"U_0023","text":"#"},{"id":"U_0024","text":"$"},{"id":"U_0025","text":"%"},{"id":"U_005E","text":"^"},{"id":"U_0026","text":"&"},{"id":"U_002A","text":"*"},{"id":"U_0028","text":"(","sk":[{"id":"U_007B","text":"{"},{"id":"U_005B","text":"["}]},{"id":"U_0029","text":")","sk":[{"id":"U_007D","text":"}"},{"id":"U_005D","text":"]"}]}]},{"id":"3","key":[{"layer":"shift","id":"K_Y","text":"\u2748","sk":[{"id":"U_1145B","text":"\uD805\uDC5B"},{"id":"U_1145E","text":"\uD805\uDC5E"},{"id":"U_1145F","text":"\uD805\uDC5F"}]},{"id":"U_003C","text":"<","sk":[{"id":"U_00AB","text":"\u00AB"}]},{"id":"U_002D","text":"-","sk":[{"id":"U_005F","text":"_"}]},{"id":"U_003D","text":"=","sk":[{"id":"U_002B","text":"+"}]},{"id":"U_003E","text":">","sk":[{"id":"U_00BB","text":"\u00BB"}]},{"layer":"shift","id":"K_X","text":"\uD805\uDC5D"},{"layer":"shift","id":"K_COLON","text":"\uD805\uDC4E"},{"layer":"shift","id":"K_W","text":"\uD805\uDC4F"},{"id":"K_EQUAL","text":"."},{"width":"100","id":"K_BKSP","sp":"1","text":"*BkSp*"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"\uD805\uDC0E\uD805\uDC0F\uD805\uDC10"},{"width":"120","id":"K_LOPT","sp":"1","text":"*Menu*"},{"width":"610","id":"K_SPACE"},{"width":"210","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,256)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫𑑂‌");}}else if(k.KKM(e,16400,49)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"!");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐖𑑂𑐘");}}else if(k.KKM(e,16400,222)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"\"");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐹");}}else if(k.KKM(e,16400,51)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"#");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐑");}}else if(k.KKM(e,16400,52)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"$");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐒");}}else if(k.KKM(e,16400,53)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"%");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐕");}}else if(k.KKM(e,16400,55)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"&");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐛");}}else if(k.KKM(e,16384,222)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"'");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐸");}}else if(k.KKM(e,16400,57)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"(");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐝");}}else if(k.KKM(e,16400,48)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,")");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐞");}}else if(k.KKM(e,16400,56)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"*");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐜");}}else if(k.KKM(e,16400,187)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"+");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑄");}}else if(k.KKM(e,16384,188)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,",");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑍");}}else if(k.KKM(e,16384,189)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"-");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐌");}}else if(k.KKM(e,16384,190)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,".");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑋");}}else if(k.KKM(e,16384,191)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"/");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐬");}}else if(k.KKM(e,16384,48)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,")");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑐");}}else if(k.KKM(e,16384,49)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"!");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑑");}}else if(k.KKM(e,16384,50)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"@");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑒");}}else if(k.KKM(e,16384,51)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"#");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑓");}}else if(k.KKM(e,16384,52)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"$");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑔");}}else if(k.KKM(e,16384,53)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"%");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑕");}}else if(k.KKM(e,16384,54)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"^");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑖");}}else if(k.KKM(e,16384,55)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"&");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑗");}}else if(k.KKM(e,16384,56)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"*");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑘");}}else if(k.KKM(e,16384,57)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"(");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑙");}}else if(k.KKM(e,16400,186)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,":");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑎");}}else if(k.KKM(e,16384,186)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,";");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐳");}}else if(k.KKM(e,16400,188)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"<");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑚");}}else if(k.KKM(e,16384,187)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"=");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,".");}}else if(k.KKM(e,16400,190)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,">");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑌");}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"?");}}else if(k.KKM(e,16400,50)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"@");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐃");}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐁");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑁");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐆");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐩𑑂𑐴");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐋");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑃");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐣𑑂𑐴");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐗");}}else if(k.KKM(e,16400,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐎𑑂𑐲");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑀");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐦");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐷");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑅");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐮𑑂𑐴");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐂");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐊");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑊");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐴𑑂𑐬");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫𑑂‌");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐟𑑂𑐬");}}else if(k.KKM(e,16400,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐅");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑈");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑏");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑝");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"❈");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐱𑑂𑐬");}}else if(k.KKM(e,16384,219)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"[");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐺");}}else if(k.KKM(e,16384,220)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"\\");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑂");}}else if(k.KKM(e,16384,221)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"]");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐾");}}else if(k.KKM(e,16400,54)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"^");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐚");}}else if(k.KKM(e,16400,189)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"_");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐍");}}else if(k.KKM(e,16384,192)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"`");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐘");}}else if(k.KKM(e,16384,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐧");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐡");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐀");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐩");}}else if(k.KKM(e,16384,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐨");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐵");}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐣");}}else if(k.KKM(e,16384,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐖");}}else if(k.KKM(e,16384,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐲");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐰");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐥");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐶");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‌");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐮");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐫");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐄");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑉");}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐔");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐎");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐟");}}else if(k.KKM(e,16384,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐐");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐏");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐢");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐴");}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐠");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐱");}}else if(k.KKM(e,16400,219)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"{");}else if(1){r=m=1;k.KDC(0,t);k.KDO(-1,t,0);}}else if(k.KKM(e,16400,220)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"|");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‍");}}else if(k.KKM(e,16400,221)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"}");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑐿");}}else if(k.KKM(e,16400,192)) {if(k.KFCM(1,t,[{t:'d',d:0}])){r=m=1;k.KDC(1,t);k.KO(-1,t,"~");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑑇");}}return r;};} \ No newline at end of file diff --git a/keyboard/runeboard/2.2/runeboard-2.2.js b/keyboard/runeboard/2.2/runeboard-2.2.js new file mode 100644 index 000000000..164fa4170 --- /dev/null +++ b/keyboard/runeboard/2.2/runeboard-2.2.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_runeboard());}function Keyboard_runeboard(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_runeboard";this.KN="Runes";this.KMINVER="15.0";this.KV={F:' 1em "Catrinity"',K102:1};this.KV.KLS={"default": ["⁝","1","2","3","4","5","6","7","8","9","0","[","]","","","","ᚫ","ᚣ","ᛟ","ᛈ","ᛄ","ᚠ","ᚸ","ᚳ","ᚱ","ᛚ","ᛝ","ᛥ","ᛇ","","","","ᚪ","ᚩ","ᛖ","ᚢ","ᛁ","ᛞ","ᚻ","ᛏ","ᚾ","ᛋ","ᛡ","","","","","","ᛇ","ZWJ","ᛢ","ᚷ","ᛣ","ᛠ","ᛒ","ᛗ","ᚹ","ᚦ","ᛉ","","","","","","᛫"],"shift": ["⁞","᛭","@","£","$","%","₿","&","*","(",")","{","}","","","","⟨","⟩","᛬","ᛕ","ᛨ","ᚡ","ᚵ","ᚲ","ᛦ","ᛛ","ᛜ","ᚶ","|","","","","ᚨ","ᚮ","ᚰ","ᚤ","ᛂ","ᛑ","ᚺ","ᛐ","ᚿ","ᛌ","?","","","","","","|","ᛅ","ᚬ","ᛃ","ᛤ","ᛪ","ᛔ","ᛘ","ᚥ","ᚧ","ᛎ","","","","","",""],"ctrl-alt": ["°","!","†","#","¢","©","ᛮ","ᛯ","ᛰ","_","+","-","=","","","","⟪","⟫","Å","ᛷ","ᛸ","","","ᛍ","ᛧ","ᛲ","~","`","\\","","","","ᛅ","ᚯ","ᛶ","ᛳ","ᛵ","ᚼ","ᚽ","","ᛀ","ᛊ","/","","","","","","\\","ᛆ","ᚭ","ᛴ","ᚴ","ᛱ","ᛓ","ᛙ","ᛩ","<",">","","","","","",""],"shift-ctrl-alt": ["","Ⅰ","Ⅴ","Ⅹ","Ⅼ","Ⅽ","Ⅾ","Ⅿ","ↁ","ↂ","ↇ","ↈ","Ↄ","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH='';this.KM=0;this.KBVER="2.2";this.KMBM=0x0070;this.KVKL={"tablet":{"font":"Catrinity","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"id":"K_Q","text":"\u16AB"},{"id":"K_W","text":"\u16A3"},{"id":"K_E","text":"\u16DF"},{"id":"K_R","text":"\u16C8"},{"id":"K_T","text":"\u16C4"},{"id":"K_Y","text":"\u16A0","sk":[{"id":"U_16A0_200D_16A0","text":"\u16A0\u200D\u16A0"}]},{"id":"K_U","text":"\u16B8"},{"id":"K_I","text":"\u16B3"},{"id":"K_O","text":"\u16B1"},{"id":"K_P","text":"\u16DA"},{"id":"K_LBRKT","text":"\u16DD"}]},{"id":"2","key":[{"id":"K_A","pad":"75","text":"\u16AA"},{"id":"K_S","text":"\u16A9"},{"id":"K_D","text":"\u16D6"},{"id":"K_F","text":"\u16A2"},{"id":"K_G","text":"\u16C1"},{"id":"K_H","text":"\u16DE"},{"id":"K_J","text":"\u16BB"},{"id":"K_K","text":"\u16CF"},{"id":"K_L","text":"\u16BE"},{"id":"K_COLON","text":"\u16CB","sk":[{"id":"U_16CC","text":"\u16CC"}]},{"id":"K_QUOTE","text":"\u16E1"}]},{"id":"3","key":[{"nextlayer":"shift","width":"100","id":"K_SHIFT","sp":"1","text":"*Shift*"},{"id":"K_Z","text":"ZWJ"},{"id":"K_X","text":"\u16E2"},{"id":"K_C","text":"\u16B7"},{"id":"K_V","text":"\u16E3","sk":[{"id":"U_16E4","text":"\u16E4"}]},{"id":"K_B","text":"\u16E0"},{"id":"K_N","text":"\u16D2"},{"id":"K_M","text":"\u16D7"},{"id":"K_COMMA","text":"\u16B9"},{"id":"K_PERIOD","text":"\u16A6"},{"id":"K_SLASH","text":"\u16C9"}]},{"id":"4","key":[{"width":"130","id":"K_BKSP","sp":"1","text":"*BkSp*"},{"width":"130","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"K_oE2","text":"\u16C7"},{"id":"K_BKQUOTE","text":"\u205D\u200B","sk":[{"id":"U_16ED_200B","text":"\u16ED\u200B"},{"id":"U_0021_200B","text":"!\u200B"},{"id":"U_2020_200B","text":"\u2020\u200B"},{"id":"U_003F_200B","text":"?\u200B"}]},{"width":"300","id":"K_SPACE","text":"\u16EB\u200B","sk":[{"id":"U_16EC_200B","text":"\u16EC\u200B"}]},{"id":"K_HYPHEN","text":"\u200B[","sk":[{"id":"U_200B_0028","text":"\u200B("},{"id":"U_200B_007B","text":"\u200B{"},{"id":"U_200B_27E8","text":"\u200B\u27E8"},{"id":"U_200B_27EA","text":"\u200B\u27EA"}]},{"id":"K_EQUAL","text":"]\u200B","sk":[{"id":"U_0029_200B","text":")\u200B"},{"id":"U_007D_200B","text":"}\u200B"},{"id":"U_27E9_200B","text":"\u27E9\u200B"},{"id":"U_27EB_200B","text":"\u27EB\u200B"}]},{"id":"K_RBRKT","text":"\u16E5"},{"width":"130","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"shift","row":[{"id":"1","key":[{"nextlayer":"default","id":"K_Q","text":"\u200B\u27E8"},{"nextlayer":"default","id":"K_W","text":"\u27E9\u200B"},{"nextlayer":"default","id":"K_E","text":"\u16EC\u200B"},{"id":"K_R","text":"\u16D5"},{"id":"K_T","text":"\u16E8"},{"id":"K_Y","text":"\u16A1"},{"id":"K_U","text":"\u16B5"},{"id":"K_I","text":"\u16B2"},{"id":"K_O","text":"\u16E6"},{"id":"K_P","text":"\u16DB"},{"id":"K_LBRKT","text":"\u16DC"}]},{"id":"2","key":[{"id":"K_A","pad":"75","text":"\u16A8"},{"id":"K_S","text":"\u16AE"},{"id":"K_D","text":"\u16B0"},{"id":"K_F","text":"\u16A4"},{"id":"K_G","text":"\u16C2"},{"id":"K_H","text":"\u16D1"},{"id":"K_J","text":"\u16BA"},{"id":"K_K","text":"\u16D0"},{"id":"K_L","text":"\u16BF"},{"nextlayer":"default","id":"K_COLON","text":"\u16CC"},{"nextlayer":"default","id":"K_QUOTE","text":"?\u200B"}]},{"id":"3","key":[{"nextlayer":"AltGr","width":"100","id":"K_SHIFT","sp":"1","text":"*AltGr*"},{"id":"K_Z","text":"\u16C5"},{"id":"K_X","text":"\u16AC"},{"id":"K_C","text":"\u16C3"},{"nextlayer":"default","id":"K_V","text":"\u16E4"},{"id":"K_B","text":"\u16EA"},{"id":"K_N","text":"\u16D4"},{"id":"K_M","text":"\u16D8"},{"id":"K_COMMA","text":"\u16A5"},{"id":"K_PERIOD","text":"\u16A7"},{"id":"K_SLASH","text":"\u16CE"}]},{"id":"4","key":[{"width":"130","id":"K_BKSP","sp":"1","text":"*BkSp*"},{"width":"130","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"K_BKSLASH","text":"|"},{"id":"K_BKQUOTE","text":"\u205E\u200B"},{"width":"300","id":"K_SPACE"},{"nextlayer":"default","id":"K_HYPHEN","text":"\u200B("},{"nextlayer":"default","id":"K_EQUAL","text":")\u200B"},{"id":"K_RBRKT","text":"\u16B6"},{"width":"130","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"AltGr","row":[{"id":"1","key":[{"nextlayer":"default","id":"K_Q","text":"\u200B\u27EA"},{"nextlayer":"default","id":"K_W","text":"\u27EB\u200B"},{"id":"K_E","text":"\u212B"},{"id":"K_R","text":"\u16F7"},{"id":"K_T","text":"\u16F8"},{"nextlayer":"shift","id":"K_Y","sp":"9"},{"nextlayer":"shift","id":"K_U","sp":"9"},{"id":"K_I","text":"\u16CD"},{"id":"K_O","text":"\u16E7"},{"id":"K_P","text":"\u16F2"},{"id":"K_LBRKT","text":"~"}]},{"id":"2","key":[{"id":"K_A","pad":"75","text":"\u16C5"},{"id":"K_S","text":"\u16AF"},{"id":"K_D","text":"\u16F6"},{"id":"K_F","text":"\u16F3"},{"id":"K_G","text":"\u16F5"},{"id":"K_H","text":"\u16BC"},{"id":"K_J","text":"\u16BD"},{"nextlayer":"shift","id":"K_K","sp":"9"},{"id":"K_L","text":"\u16C0"},{"id":"K_COLON","text":"\u16CA"},{"id":"K_QUOTE","text":"\/"}]},{"id":"3","key":[{"nextlayer":"123","width":"100","id":"K_SHIFT","sp":"1","text":"*123*"},{"id":"K_Z","text":"\u16C6"},{"id":"K_X","text":"\u16AD"},{"id":"K_C","text":"\u16F4"},{"id":"K_V","text":"\u16B4"},{"id":"K_B","text":"\u16F1"},{"id":"K_N","text":"\u16D3"},{"id":"K_M","text":"\u16D9"},{"id":"K_COMMA","text":"\u16E9"},{"id":"K_PERIOD","text":"<"},{"id":"K_SLASH","text":">"}]},{"id":"4","key":[{"width":"130","id":"K_BKSP","sp":"1","text":"*BkSp*"},{"width":"130","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"K_oE2","text":"\\"},{"id":"K_BKQUOTE","text":"\u00B0"},{"nextlayer":"shift","width":"300","id":"K_SPACE","sp":"1","text":"*Shift*"},{"id":"K_HYPHEN","text":"-"},{"id":"K_EQUAL","text":"="},{"id":"K_RBRKT","text":"`"},{"width":"130","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]},{"id":"123","row":[{"id":"1","key":[{"id":"U_0031","text":"1"},{"id":"U_0032","text":"2"},{"id":"U_0033","text":"3"},{"id":"U_0034","text":"4"},{"id":"U_0035","text":"5"},{"id":"U_0036","text":"6"},{"id":"U_0037","text":"7"},{"id":"U_0038","text":"8"},{"id":"U_0039","text":"9"},{"id":"U_0021","text":"!"},{"id":"U_00B0","text":"\u00B0"}]},{"id":"2","key":[{"id":"U_2160","pad":"75","text":"\u2160"},{"id":"U_2164","text":"\u2164"},{"id":"U_2169","text":"\u2169"},{"id":"U_216C","text":"\u216C"},{"id":"U_216D","text":"\u216D","sk":[{"id":"U_2183","text":"\u2183"}]},{"id":"U_216E","text":"\u216E","sk":[{"id":"U_2181","text":"\u2181"},{"id":"U_2187","text":"\u2187"}]},{"id":"U_216F","text":"\u216F","sk":[{"id":"U_2182","text":"\u2182"},{"id":"U_2188","text":"\u2188"}]},{"id":"U_16EE","text":"\u16EE"},{"id":"U_16EF","text":"\u16EF"},{"id":"U_16F0","text":"\u16F0"},{"id":"U_0025","text":"%"}]},{"id":"3","key":[{"nextlayer":"default","width":"100","id":"K_SHIFT","sp":"1","text":"Main"},{"id":"U_007B","text":"{"},{"id":"U_20BF","text":"\u20BF"},{"id":"U_00A3","text":"\u00A3"},{"id":"U_0024","text":"$"},{"id":"U_00A2","text":"\u00A2"},{"id":"U_00A9","text":"\u00A9"},{"id":"U_00AE","text":"\u00AE"},{"id":"U_2122","text":"\u2122"},{"id":"U_0026","text":"&"},{"id":"U_007D","text":"}"}]},{"id":"4","key":[{"width":"130","id":"K_BKSP","sp":"1","text":"*BkSp*"},{"width":"130","id":"K_LOPT","sp":"1","text":"*Menu*"},{"id":"U_0040","text":"@"},{"id":"U_0023","text":"#"},{"nextlayer":"AltGr","width":"300","id":"K_SPACE","sp":"1","text":"*AltGr*"},{"id":"U_005F","text":"_"},{"id":"U_002B","text":"+"},{"id":"U_002A","text":"*"},{"width":"130","id":"K_ENTER","sp":"1","text":"*Enter*"}]}]}]}};this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,226)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛇ");}}else if(k.KKM(e,16400,226)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"|");}}else if(k.KKM(e,16480,226)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\\");}}else if(k.KKM(e,16384,32)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"᛫​");}}else if(k.KKM(e,16400,32)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t," ");}}else if(k.KKM(e,16400,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"᛭​");}}else if(k.KKM(e,16496,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ⅰ");}}else if(k.KKM(e,16400,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"?​");}}else if(k.KKM(e,16400,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"£");}}else if(k.KKM(e,16496,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ⅹ");}}else if(k.KKM(e,16400,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"$");}}else if(k.KKM(e,16496,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ⅼ");}}else if(k.KKM(e,16400,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"%");}}else if(k.KKM(e,16496,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ⅽ");}}else if(k.KKM(e,16400,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"&");}}else if(k.KKM(e,16496,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ⅿ");}}else if(k.KKM(e,16384,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛡ");}}else if(k.KKM(e,16480,222)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"/");}}else if(k.KKM(e,16400,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"(​");}}else if(k.KKM(e,16496,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ↂ");}}else if(k.KKM(e,16400,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,")​");}}else if(k.KKM(e,16496,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ↇ");}}else if(k.KKM(e,16400,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"*");}}else if(k.KKM(e,16496,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ↁ");}}else if(k.KKM(e,16400,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"}​");}}else if(k.KKM(e,16496,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ↄ");}}else if(k.KKM(e,16384,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚹ");}}else if(k.KKM(e,16480,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛩ");}}else if(k.KKM(e,16384,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"[​");}}else if(k.KKM(e,16480,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"-");}}else if(k.KKM(e,16384,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚦ");}}else if(k.KKM(e,16480,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"<");}}else if(k.KKM(e,16384,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛉ");}}else if(k.KKM(e,16480,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,">");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"0");}}else if(k.KKM(e,16480,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"+");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"1");}}else if(k.KKM(e,16480,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"!​");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"2");}}else if(k.KKM(e,16480,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"†​");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"3");}}else if(k.KKM(e,16480,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"#");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"4");}}else if(k.KKM(e,16480,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"¢");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"5");}}else if(k.KKM(e,16480,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"©");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"6");}}else if(k.KKM(e,16480,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛮ");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"7");}}else if(k.KKM(e,16480,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛯ");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"8");}}else if(k.KKM(e,16480,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛰ");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"9");}}else if(k.KKM(e,16480,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"_");}}else if(k.KKM(e,16400,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛌ");}}else if(k.KKM(e,16384,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛋ");}}else if(k.KKM(e,16480,186)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛊ");}}else if(k.KKM(e,16400,188)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚥ");}}else if(k.KKM(e,16384,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"]​");}}else if(k.KKM(e,16480,187)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"=");}}else if(k.KKM(e,16400,190)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚧ");}}else if(k.KKM(e,16400,191)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛎ");}}else if(k.KKM(e,16400,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"@");}}else if(k.KKM(e,16496,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ⅴ");}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚨ");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛪ");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛃ");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚰ");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"᛬​");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚤ");}}else if(k.KKM(e,16400,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛂ");}}else if(k.KKM(e,16400,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛑ");}}else if(k.KKM(e,16400,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚲ");}}else if(k.KKM(e,16400,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚺ");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛐ");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚿ");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛘ");}}else if(k.KKM(e,16400,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛔ");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛦ");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛛ");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"⟨​");}}else if(k.KKM(e,16400,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛕ");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚮ");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛨ");}}else if(k.KKM(e,16400,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚵ");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛤ");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"⟩​");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚬ");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚡ");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛅ");}}else if(k.KKM(e,16384,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛝ");}}else if(k.KKM(e,16480,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"~");}}else if(k.KKM(e,16384,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛇ");}}else if(k.KKM(e,16480,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"\\");}}else if(k.KKM(e,16384,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛥ");}}else if(k.KKM(e,16480,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"`");}}else if(k.KKM(e,16400,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"₿");}}else if(k.KKM(e,16496,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Ⅾ");}}else if(k.KKM(e,16400,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"{​");}}else if(k.KKM(e,16496,189)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ↈ");}}if(m) {}else if(k.KKM(e,16384,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"⁝​");}}else if(k.KKM(e,16480,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"°");}}else if(k.KKM(e,16384,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚪ");}}else if(k.KKM(e,16480,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛅ");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛠ");}}else if(k.KKM(e,16480,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛱ");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚷ");}}else if(k.KKM(e,16480,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛴ");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛖ");}}else if(k.KKM(e,16480,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛶ");}}else if(k.KKM(e,16384,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛟ");}}else if(k.KKM(e,16480,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Å");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚢ");}}else if(k.KKM(e,16480,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛳ");}}else if(k.KKM(e,16384,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛁ");}}else if(k.KKM(e,16480,71)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛵ");}}else if(k.KKM(e,16384,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛞ");}}else if(k.KKM(e,16480,72)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚼ");}}else if(k.KKM(e,16384,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚳ");}}else if(k.KKM(e,16480,73)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛍ");}}else if(k.KKM(e,16384,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚻ");}}else if(k.KKM(e,16480,74)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚽ");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛏ");}}else if(k.KKM(e,16480,75)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚾ");}}else if(k.KKM(e,16480,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛀ");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛗ");}}else if(k.KKM(e,16480,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛙ");}}else if(k.KKM(e,16384,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛒ");}}else if(k.KKM(e,16480,78)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛓ");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚱ");}}else if(k.KKM(e,16480,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛧ");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛚ");}}else if(k.KKM(e,16480,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛲ");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚫ");}}else if(k.KKM(e,16480,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"⟪​");}}else if(k.KKM(e,16384,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛈ");}}else if(k.KKM(e,16480,82)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛷ");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚩ");}}else if(k.KKM(e,16480,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚯ");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛄ");}}else if(k.KKM(e,16480,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛸ");}}else if(k.KKM(e,16384,85)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚸ");}}else if(k.KKM(e,16480,85)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛣ");}}else if(k.KKM(e,16480,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚴ");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚣ");}}else if(k.KKM(e,16480,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"⟫​");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛢ");}}else if(k.KKM(e,16480,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚭ");}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚠ");}}else if(k.KKM(e,16480,89)) {if(1){r=m=1;k.KDC(0,t);}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‍");}}else if(k.KKM(e,16480,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛆ");}}else if(k.KKM(e,16400,219)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᛜ");}}else if(k.KKM(e,16400,220)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"|");}}else if(k.KKM(e,16400,221)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"ᚶ");}}else if(k.KKM(e,16400,192)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"⁞​");}}return r;};} \ No newline at end of file diff --git a/keyboard/warang_citi/1.1.2/warang_citi-1.1.2.js b/keyboard/warang_citi/1.1.2/warang_citi-1.1.2.js new file mode 100644 index 000000000..d1c6728e1 --- /dev/null +++ b/keyboard/warang_citi/1.1.2/warang_citi-1.1.2.js @@ -0,0 +1 @@ +if(typeof keyman === 'undefined') {console.log('Keyboard requires KeymanWeb 10.0 or later');if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");} else {KeymanWeb.KR(new Keyboard_warang_citi());}function Keyboard_warang_citi(){this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;this.KI="Keyboard_warang_citi";this.KN="Warang Citi";this.KMINVER="10.0";this.KV={F:' 1em "BoyoGagrai"',K102:0};this.KV.KLS={"default": ["`","𑣡","𑣢","𑣣","𑣤","𑣥","𑣦","𑣧","𑣨","𑣩","𑣠","-","=","","","","𑣄","𑣟","𑣈","𑣜","𑣒","𑣅","𑣇","𑣆","𑣉","𑣘","[","]","\\","","","","𑣁","𑣞","𑣑","^","𑣋","𑣙","𑣎","𑣌","𑣚",";","'","","","","","","","z","𑣝","c","𑣀","𑣗","𑣓","𑣖",",",".",".","","","","","",""],"shift": ["~","!","𑣿","#","$","%","^","&","*","(",")","_","+","","","","𑢤","𑢿","𑢨","𑢼","𑢲","𑢥","𑢧","𑢦","𑢩","𑢸","{","}","|","","","","𑢡","𑢾","𑢱","^","𑢫","𑢹","𑢮","𑢬","𑢺",":","\"","","","","","","","Z","𑢽","C","𑢠","𑢷","𑢳","𑢶","<",">","?","","","","","",""]};this.KV.BK=(function(x){var e=Array.apply(null,Array(65)).map(String.prototype.valueOf,""),r=[],v,i,m=['default','shift','ctrl','shift-ctrl','alt','shift-alt','ctrl-alt','shift-ctrl-alt'];for(i=m.length-1;i>=0;i--)if((v=x[m[i]])||r.length)r=(v?v:e).slice().concat(r);return r})(this.KV.KLS);this.KDU=0;this.KH=' Start Using Warang Citi Keyboard

Start Using Warang Citi Keyboard

Start typing Warang Citi phonetically according to English alphabet.

Rules for Desktop

Type DH for Warang Citi letter DA:
Type TH for Warang Citi letter OT
Type NG for Warang Citi letter ONG
Type NJ for Warang Citi letter BINJ
Type NN for Warang Citi letter ENN
Type RR for Warang Citi letter HORR
Type V for Warang Citi letter ANG
Type X for Warang Citi letter SSU
Type @ for Warang Citi letter OWANG
Type CTRL+DIGITS for Arabic Num

Rules for Mobile Devices

Type D for Warang Citi letter DA:
Type Ḑ for Warang Citi letter ODD
Type T for Warang Citi letter OT
Type Ț for Warang Citi letter TTE
Type NG for Warang Citi letter ONG
Type NJ for Warang Citi letter BINJ
Type NN for Warang Citi letter ENN
Type RR for Warang Citi letter HORR
Type V for Warang Citi letter ANG
Type X for Warang Citi letter SSU

© 2019 Mangu Purty

Warang Citi Keyboard 1.0

Keyboard Layout

Desktop Layout

Default

Desktop Layout

Shifted

Desktop Layout

Touch Layout

Default Layer

The default layer is Latin keyboard:
Touch Layout, Default

Latin Shifted

Touch Layout, Shifted

Warang Citi Layer

Touch h-symbol to go to Warang Citi layer. Touch h-symbol to go back to Latin layer.

s Touch Layout, Default

Numeric Layer

Touch Layout, Numeric ';this.KM=0;this.KBVER="1.1.2";this.KMBM=0x0011;this.KS=1;this.KVKL={"phone":{"font":"BoyoGagrai","displayUnderlying":false,"layer":[{"id":"default","row":[{"id":"1","key":[{"width":"106","id":"U_0031","text":"1"},{"width":"106","id":"U_0032","text":"2"},{"width":"106","id":"U_0033","text":"3"},{"width":"106","id":"U_0034","text":"4"},{"width":"106","id":"U_0035","text":"5"},{"width":"106","id":"U_0036","text":"6"},{"width":"106","id":"U_0037","text":"7"},{"width":"106","id":"U_0038","text":"8"},{"width":"106","id":"U_0039","text":"9"},{"width":"106","id":"U_0030","text":"0"}]},{"id":"2","key":[{"width":"106","id":"K_Q","text":":"},{"width":"106","id":"K_W","text":"w"},{"width":"106","id":"K_E","text":"e"},{"width":"106","id":"K_R","text":"r"},{"width":"106","id":"K_T","text":"\u021B"},{"width":"106","id":"K_Y","text":"y"},{"width":"106","id":"K_U","text":"u"},{"width":"106","id":"K_I","text":"i"},{"width":"106","id":"K_O","text":"o"},{"width":"106","id":"K_P","text":"p"}]},{"id":"3","key":[{"width":"106","id":"K_A","pad":"75","text":"a"},{"width":"106","id":"K_S","text":"s"},{"width":"106","id":"K_D","text":"\u1E11"},{"width":"106","id":"U_118D4","text":"d"},{"width":"106","id":"K_G","text":"g"},{"width":"106","id":"K_H","text":"h"},{"width":"106","id":"K_J","text":"j"},{"width":"106","id":"K_K","text":"k"},{"width":"106","id":"K_L","text":"l"},{"width":"10","id":"T_new_120","sp":"10"}]},{"id":"4","key":[{"nextlayer":"wara-shift","width":"150","id":"K_SHIFT","text":"\u21E7"},{"layer":"wara-shift","width":"106","id":"U_118D5","text":"t"},{"width":"106","id":"K_X","text":"x"},{"width":"106","id":"U_118CF","text":"c"},{"width":"106","id":"K_V","text":"v"},{"width":"106","id":"K_B","text":"b"},{"width":"106","id":"K_N","text":"n"},{"width":"106","id":"K_M","text":"m"},{"width":"150","id":"K_BKSP","sp":"1","text":"\u232B"}]},{"id":"5","key":[{"nextlayer":"wara-numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"?123"},{"width":"106","id":"K_COMMA","text":","},{"width":"106","id":"K_LOPT","sp":"1","text":"\uD83C\uDF10"},{"width":"450","id":"K_SPACE","sp":"1","text":"Warang Citi"},{"width":"106","id":"K_PERIOD","text":"."},{"id":"K_ENTER","sp":"1","text":"\u23CE"}]}]},{"id":"wara-shift","row":[{"id":"1","key":[{"nextlayer":"default","width":"106","id":"U_0021","text":"!"},{"nextlayer":"default","width":"106","id":"U_0040","text":"@"},{"nextlayer":"default","width":"106","id":"U_0023","text":"#"},{"nextlayer":"default","width":"106","id":"U_0024","text":"$"},{"nextlayer":"default","width":"106","id":"U_0025","text":"%"},{"nextlayer":"default","width":"106","id":"U_005E","text":"^"},{"nextlayer":"default","width":"106","id":"U_0026","text":"&"},{"nextlayer":"default","width":"106","id":"U_002A","text":"*"},{"nextlayer":"default","width":"106","id":"U_0028","text":"("},{"nextlayer":"default","width":"106","id":"U_0029","text":")"}]},{"id":"2","key":[{"nextlayer":"default","width":"106","id":"K_Q","text":":"},{"nextlayer":"default","width":"106","id":"K_W","text":"W"},{"nextlayer":"default","width":"106","id":"K_E","text":"E"},{"nextlayer":"default","width":"106","id":"K_R","text":"R"},{"nextlayer":"default","width":"106","id":"K_T","text":"\u021A"},{"nextlayer":"default","width":"106","id":"K_Y","text":"Y"},{"nextlayer":"default","width":"106","id":"K_U","text":"U"},{"nextlayer":"default","width":"106","id":"K_I","text":"I"},{"nextlayer":"default","width":"106","id":"K_O","text":"O"},{"nextlayer":"default","width":"106","id":"K_P","text":"P"}]},{"id":"3","key":[{"nextlayer":"default","width":"106","id":"K_A","pad":"75","text":"A"},{"nextlayer":"default","width":"106","id":"K_S","text":"S"},{"nextlayer":"default","width":"106","id":"K_D","text":"\u1E10"},{"nextlayer":"default","width":"106","id":"U_118B4","text":"D"},{"nextlayer":"default","width":"106","id":"K_G","text":"G"},{"nextlayer":"default","width":"106","id":"K_H","text":"H"},{"nextlayer":"default","width":"106","id":"K_J","text":"J"},{"nextlayer":"default","width":"106","id":"K_K","text":"K"},{"nextlayer":"default","width":"106","id":"K_L","text":"L"},{"width":"10","id":"T_new_120","sp":"10"}]},{"id":"4","key":[{"nextlayer":"wara-lock","width":"150","id":"K_SHIFT","sp":"1","text":"\u2B06"},{"nextlayer":"default","layer":"wara-shift","width":"106","id":"U_118B5","text":"T"},{"nextlayer":"default","width":"106","id":"K_X","text":"X"},{"nextlayer":"default","width":"106","id":"U_118AF","text":"C"},{"nextlayer":"default","width":"106","id":"K_V","text":"V"},{"nextlayer":"default","width":"106","id":"K_B","text":"B"},{"nextlayer":"default","width":"106","id":"K_N","text":"N"},{"nextlayer":"default","width":"106","id":"K_M","text":"M"},{"id":"K_BKSP","sp":"1","text":"\u232B"}]},{"id":"5","key":[{"nextlayer":"wara-numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"?123"},{"width":"106","id":"K_COMMA","text":","},{"width":"106","id":"K_LOPT","sp":"1","text":"\uD83C\uDF10"},{"width":"450","id":"K_SPACE"},{"width":"106","id":"K_PERIOD","text":"."},{"id":"K_ENTER","sp":"1","text":"\u23CE"}]}]},{"id":"wara-numeric","row":[{"id":"1","key":[{"width":"106","id":"U_118E1","text":"\uD806\uDCE1"},{"width":"106","id":"U_118E2","text":"\uD806\uDCE2"},{"width":"106","id":"U_118E3","text":"\uD806\uDCE3"},{"width":"106","id":"U_118E4","text":"\uD806\uDCE4"},{"width":"106","id":"U_118E5","text":"\uD806\uDCE5"},{"width":"106","id":"U_118E6","text":"\uD806\uDCE6"},{"width":"106","id":"U_118E7","text":"\uD806\uDCE7"},{"width":"106","id":"U_118E8","text":"\uD806\uDCE8"},{"width":"106","id":"U_118E9","text":"\uD806\uDCE9"},{"width":"106","id":"U_118E0","text":"\uD806\uDCE0"}]},{"id":"2","key":[{"width":"106","id":"U_0025","text":"%"},{"width":"106","id":"U_00A9","text":"\u00A9"},{"width":"106","id":"U_00AE","text":"\u00AE"},{"width":"106","id":"U_002A","text":"*"},{"width":"106","id":"U_007E","text":"~"},{"width":"106","id":"U_0025","text":"%"},{"width":"106","id":"U_005C","text":"\\"},{"width":"106","id":"K_EQUAL","text":"="},{"width":"106","id":"U_003C","text":"<"},{"width":"106","id":"U_003E","text":">"}]},{"id":"3","key":[{"width":"106","id":"U_118FF","text":"\uD806\uDCFF"},{"width":"106","id":"U_20B9","text":"\u20B9"},{"width":"106","id":"U_0023","text":"#"},{"width":"106","id":"U_005F","text":"_"},{"width":"106","id":"U_0026","text":"&"},{"width":"106","id":"U_002D","text":"-"},{"width":"106","id":"U_002B","text":"+"},{"width":"106","id":"U_0028","text":"(","sk":[{"id":"U_007B","text":"{"},{"id":"U_005B","text":"["}]},{"width":"106","id":"U_0029","text":")","sk":[{"id":"U_005D","text":"]"},{"id":"U_007D","text":"}"}]},{"width":"106","id":"U_007C","text":"|"}]},{"id":"4","key":[{"id":"U_0040","pad":"140","text":"@"},{"id":"U_0022","text":"\""},{"id":"U_0027","text":"'"},{"id":"U_003A","text":":"},{"id":"U_003B","text":";"},{"id":"U_002C","text":","},{"id":"U_002E","text":"."},{"id":"U_002F","text":"\/"},{"width":"100","id":"K_BKSP","sp":"1","text":"\u232B"}]},{"id":"5","key":[{"nextlayer":"default","width":"150","id":"K_LOWER","sp":"1","text":"\uD806\uDCCA\uD806\uDCCB\uD806\uDCCC"},{"width":"106","id":"U_0021","text":"!"},{"width":"106","id":"K_LOPT","sp":"1","text":"\uD83C\uDF10"},{"width":"450","id":"K_SPACE"},{"width":"106","id":"U_003F","text":"?"},{"id":"K_ENTER","sp":"1","text":"\u23CE"}]}]},{"id":"wara-lock","row":[{"id":"1","key":[{"width":"106","id":"U_0031","text":"1"},{"width":"106","id":"U_0032","text":"2"},{"width":"106","id":"U_0033","text":"3"},{"width":"106","id":"U_0034","text":"4"},{"width":"106","id":"U_0035","text":"5"},{"width":"106","id":"U_0036","text":"6"},{"width":"106","id":"U_0037","text":"7"},{"width":"106","id":"U_0038","text":"8"},{"width":"106","id":"U_0039","text":"9"},{"width":"106","id":"U_0030","text":"0"}]},{"id":"2","key":[{"layer":"wara-shift","width":"106","id":"K_Q","text":":"},{"layer":"wara-shift","width":"106","id":"K_W","text":"W"},{"layer":"wara-shift","width":"106","id":"K_E","text":"E"},{"layer":"wara-shift","width":"106","id":"K_R","text":"R"},{"layer":"wara-shift","width":"106","id":"K_T","text":"\u021A"},{"layer":"wara-shift","width":"106","id":"K_Y","text":"Y"},{"layer":"wara-shift","width":"106","id":"K_U","text":"U"},{"layer":"wara-shift","width":"106","id":"K_I","text":"I"},{"layer":"wara-shift","width":"106","id":"K_O","text":"O"},{"layer":"wara-shift","width":"106","id":"K_P","text":"P"}]},{"id":"3","key":[{"layer":"wara-shift","width":"106","id":"K_A","pad":"75","text":"A"},{"layer":"wara-shift","width":"106","id":"K_S","text":"S"},{"layer":"wara-shift","width":"106","id":"K_D","text":"\u1E10"},{"layer":"wara-shift","width":"106","id":"U_118B4","text":"D"},{"layer":"wara-shift","width":"106","id":"K_G","text":"G"},{"layer":"wara-shift","width":"106","id":"K_H","text":"H"},{"layer":"wara-shift","width":"106","id":"K_J","text":"J"},{"layer":"wara-shift","width":"106","id":"K_K","text":"K"},{"layer":"wara-shift","width":"106","id":"K_L","text":"L"},{"width":"10","sp":"10"}]},{"id":"4","key":[{"nextlayer":"default","width":"150","id":"K_F2","sp":"2","text":"\u21EA"},{"layer":"wara-shift","width":"106","id":"U_118B5","text":"T"},{"layer":"wara-shift","width":"106","id":"K_X","text":"X"},{"layer":"wara-shift","width":"106","id":"U_118AF","text":"C"},{"layer":"wara-shift","width":"106","id":"K_V","text":"V"},{"layer":"wara-shift","width":"106","id":"K_B","text":"B"},{"layer":"wara-shift","width":"106","id":"K_N","text":"N"},{"layer":"wara-shift","width":"106","id":"K_M","text":"M"},{"id":"K_BKSP","sp":"1","text":"\u232B"}]},{"id":"5","key":[{"nextlayer":"wara-numeric","width":"150","id":"K_NUMLOCK","sp":"1","text":"?123"},{"width":"106","id":"K_COMMA","text":","},{"width":"106","id":"K_LOPT","sp":"1","text":"\uD83C\uDF10"},{"width":"450","id":"K_SPACE"},{"width":"106","id":"K_PERIOD","text":"."},{"id":"K_ENTER","sp":"1","text":"\u23CE"}]}]}]}};this.KCSS=".kmw-keyboard-warang_citi /*1234567890-ROW-NORMAL*/\n \n #default-U_0031, #default-U_0031, #default-U_0032, #default-U_0033, #default-U_0034, #default-U_0035, #default-U_0036, #default-U_0036, #default-U_0037, #default-U_0038, #default-U_0039, #default-U_0030,\n \n #default-U_0031, #default-U_0031, #default-U_0032, #default-U_0033, #default-U_0034, #default-U_0035, #default-U_0036, #default-U_0036, #default-U_0037, #default-U_0038, #default-U_0039, #default-U_0030,\n \n #shift-K_1, #shift-K_2, #shift-K_2, #shift-K_3, #shift-K_4, #shift-K_5, #shift-K_6, #shift-K_6, #shift-K_7, #shift-K_8, #shift-K_9,\n \n #wara-numeric-U_0031, #wara-numeric-U_0032, #wara-numeric-U_0033, #wara-numeric-U_0034, #wara-numeric-U_0035, #wara-numeric-U_0036, #wara-numeric-U_0036, #wara-numeric-U_0037, #wara-numeric-U_0038, #wara-numeric-U_0039, #wara-numeric-U_0030,\n \n #wara-lock-U_0031, #wara-lock-U_0032, #wara-lock-U_0033, #wara-lock-U_0034, #wara-lock-U_0035, #wara-lock-U_0036, #wara-lock-U_0036, #wara-lock-U_0037, #wara-lock-U_0038, #wara-lock-U_0039, #wara-lock-U_0030,\n \n #lock-U_0031, #lock-U_0032, #lock-U_0033, #lock-U_0034, #lock-U_0035, #lock-U_0036, #lock-U_0036, #lock-U_0037, #lock-U_0038, #lock-U_0039, #lock-U_0030,\n \n #wara-numeric-U_118E1, #wara-numeric-U_118E1, #wara-numeric-U_118E2, #wara-numeric-U_118E3, #wara-numeric-U_118E4, #wara-numeric-U_118E5, #wara-numeric-U_118E6, #wara-numeric-U_118E7, #wara-numeric-U_118E8, #wara-numeric-U_118E9, #wara-numeric-U_118E0,\n \n #numeric-U_0031, #numeric-U_0032, #numeric-U_0033, #numeric-U_0034, #numeric-U_0035, #numeric-U_0036, #numeric-U_0037, #numeric-U_0038, #numeric-U_0039, #numeric-U_0030 {\n background-color: rgb(51, 51, 51);\n color: white;\n border-color: rgb(51, 51, 51);\n padding-bottom: 42px;\n border-radius: 0px;\n }\n \n .kmw-keyboard-warang_citi /* QWERTYUIOP-ROW*/\n \n #default-K_Q, #default-K_Q, #default-K_W, #default-K_E, #default-K_R, #default-K_T, #default-K_Y, #default-K_U, #default-K_I, #default-K_O, #default-K_P,\n \n #wara-shift-K_Q, #wara-shift-K_W, #wara-shift-K_E, #wara-shift-K_R, #wara-shift-K_T, #wara-shift-K_Y, #wara-shift-K_U, #wara-shift-K_I, #wara-shift-K_O, #wara-shift-K_P,\n \n #wara-lock-K_Q, #wara-lock-K_Q, #wara-lock-K_W, #wara-lock-K_E, #wara-lock-K_R, #wara-lock-K_T, #wara-lock-K_Y, #wara-lock-K_U, #wara-lock-K_I, #wara-lock-K_O, #wara-lock-K_P,\n \n #default-U_0071, #default-U_0077, #default-U_0065, #default-U_0072, #default-U_0074, #default-U_0079, #default-U_0075, #default-U_0069, #default-U_006F, #default-U_0070,\n \n #shift-U_0051, #shift-U_0057, #shift-U_0045, #shift-U_0052, #shift-U_0054, #shift-U_0059, #shift-U_0055, #shift-U_0049, #shift-U_004F, #shift-U_0050,\n \n #lock-U_0051, #lock-U_0057, #lock-U_0045, #lock-U_0052, #lock-U_0054, #lock-U_0059, #lock-U_0055, #lock-U_0049, #lock-U_004F, #lock-U_0050,\n \n #wara-numeric-U_0025, #wara-numeric-U_00A9, #wara-numeric-U_00AE, #wara-numeric-U_002A, #wara-numeric-U_007E, #wara-numeric-U_0025, #wara-numeric-U_005C, #wara-numeric-K_EQUAL, #wara-numeric-U_003C, #wara-numeric-U_003E,\n \n #numeric-U_0025, #numeric-U_00A9, #numeric-U_00AE, #numeric-U_002A, #numeric-U_007E, #numeric-U_0025, #numeric-U_005C, #numeric-K_EQUAL, #numeric-U_003C, #numeric-U_003E {\n background-color: rgb(51, 51, 51);\n color: white;\n border-color: rgb(51, 51, 51);\n padding-bottom: 50px;\n border-radius: 0px;\n }\n \n .kmw-keyboard-warang_citi /*ASDFGHJKL-ROW*/\n \n #default-K_A, #default-K_A, #default-K_S, #default-K_D, #default-U_118D4, #default-K_G, #default-K_H, #default-K_J, #default-K_K, #default-K_L,\n \n #wara-shift-K_A, #wara-shift-K_S, #wara-shift-K_D, #wara-shift-U_118B4, #wara-shift-K_G, #wara-shift-K_H, #wara-shift-K_J, #wara-shift-K_K, #wara-shift-K_L,\n \n #wara-lock-K_A, #wara-lock-K_S, #wara-lock-K_D, #wara-lock-U_118B4, #wara-lock-K_G, #wara-lock-K_H, #wara-lock-K_J, #wara-lock-K_K, #wara-lock-K_L,\n \n #default-U_0061, #default-U_0073, #default-U_0064, #default-U_0066, #default-U_0067, #default-U_0068, #default-U_006A, #default-U_006B, #default-U_006C,\n \n #shift-U_0041, #shift-U_0053, #shift-U_0044, #shift-U_0046, #shift-U_0047, #shift-U_0048, #shift-U_004A, #shift-U_004B, #shift-U_004C,\n \n #lock-U_0041, #lock-U_0053, #lock-U_0044, #lock-U_0046, #lock-U_0047, #lock-U_0048, #lock-U_004A, #lock-U_004B, #lock-U_004C,\n \n #wara-numeric-U_118FF, #wara-numeric-U_20B9, #wara-numeric-U_0023, #wara-numeric-U_005F, #wara-numeric-U_0026, #wara-numeric-U_002D, #wara-numeric-U_002B, #wara-numeric-U_0028, #wara-numeric-U_0029, #wara-numeric-U_007C,\n \n #numeric-U_118FF, #numeric-U_20B9, #numeric-U_0023, #numeric-U_005F, #numeric-U_0026, #numeric-U_002D, #numeric-U_002B, #numeric-U_0028, #numeric-U_0029, #numeric-U_007C {\n background-color: rgb(51, 51, 51);\n color: white;\n border-color: rgb(51, 51, 51);\n padding-bottom: 46px;\n border-radius: 0px;\n }\n \n .kmw-keyboard-warang_citi /*ZXCVBNM-ROW*/\n \n #default-K_SHIFT, #default-K_SHIFT, #default-U_118D5, #default-K_X, #default-U_118CF, #default-K_V, #default-K_B, #default-K_N, #default-K_M, #default-K_BKSP,\n \n #wara-shift-K_SHIFT, #wara-shift-U_118B5, #wara-shift-K_X, #wara-shift-U_118AF, #wara-shift-K_V, #wara-shift-K_B, #wara-shift-K_N, #wara-shift-K_M, #wara-shift-K_BKSP,\n \n #wara-lock-K_F2, #wara-lock-U_118B5, #wara-lock-K_X, #wara-lock-U_118AF, #wara-lock-K_V, #wara-lock-K_B, #wara-lock-K_N, #wara-lock-K_M, #wara-lock-K_BKSP,\n \n #default-K_SHIFT, #default-U_007A, #default-U_0078, #default-U_0063, #default-U_0076, #default-U_0062, #default-U_006E, #default-U_006D, #default-K_BKSP,\n \n #shift-K_SHIFT, #shift-U_005A, #shift-U_0058, #shift-U_0043, #shift-U_0056, #shift-U_0042, #shift-U_004E, #shift-U_004D, #shift-K_BKSP,\n \n #lock-K_SHIFT, #lock-U_005A, #lock-U_0058, #lock-U_0043, #lock-U_0056, #lock-U_0042, #lock-U_004E, #lock-U_004D, #lock-K_BKSP,\n \n #wara-numeric-U_0040, #wara-numeric-U_0022, #wara-numeric-U_0027, #wara-numeric-U_003A, #wara-numeric-U_003B, #wara-numeric-U_002C, #wara-numeric-U_002E, #wara-numeric-U_002F, #wara-numeric-K_BKSP,\n \n #numeric-U_0040, #numeric-U_0022, #numeric-U_0027, #numeric-U_003A, #numeric-U_003B, #numeric-U_002C, #numeric-U_002E, #numeric-U_002F, #numeric-K_BKSP {\n background-color: rgb(51, 51, 51);\n color: white;\n border-color: rgb(51, 51, 51);\n padding-bottom: 42px;\n border-radius: 0px;\n }\n \n .kmw-keyboard-warang_citi /*BOTTOM-ROW*/ \n \n #default-K_NUMLOCK, #default-K_NUMLOCK, #default-K_COMMA, #default-K_F13, #default-K_SPACE, #default-K_LOPT, #default-K_PERIOD, #default-K_ENTER,\n \n #wara-shift-K_NUMLOCK, #wara-shift-K_COMMA, #wara-shift-K_F13, #wara-shift-K_SPACE, #wara-shift-K_LOPT, #wara-shift-K_PERIOD, #wara-shift-K_ENTER,\n \n #wara-lock-K_NUMLOCK, #wara-lock-K_COMMA, #wara-lock-K_F13, #wara-lock-K_SPACE, #wara-lock-K_LOPT, #wara-lock-K_PERIOD, #wara-lock-K_ENTER,\n \n #default-K_NUMLOCK, #default-K_COMMA, #default-K_F13, #default-K_SPACE, #default-K_LOPT, #default-K_PERIOD, #default-K_ENTER,\n \n #shift-K_NUMLOCK, #shift-U_002C, #shift-K_F13, #shift-K_SPACE, #shift-K_LOPT, #shift-U_002E, #shift-K_ENTER,\n \n #lock-K_NUMLOCK, #lock-K_COMMA, #lock-K_F13, #lock-K_SPACE, #lock-K_LOPT, #lock-K_PERIOD, #lock-K_ENTER,\n \n #numeric-K_LOWER, #numeric-U_0021, #numeric-K_F13, #numeric-K_SPACE, #numeric-K_LOPT, #numeric-U_003F, #numeric-K_ENTER,\n \n #wara-numeric-K_LOWER, #wara-numeric-U_0021, #wara-numeric-K_F13, #wara-numeric-K_SPACE, #wara-numeric-K_LOPT, #wara-numeric-U_003F, #wara-numeric-K_ENTER {\n background-color: rgb(51, 51, 51);\n color: white;\n border-color: rgb(51, 51, 51);\n padding-bottom: 25px;\n border-radius: 0px;\n }\n \n .kmw-keyboard-warang_citi /*SPACE-BAR-CSS*/\n \n #lock-K_SPACE, #numeric-K_SPACE, #shift-K_SPACE /* #wara-numeric-K_SPACE, #wara-lock-K_SPACE, default-K_SPACE, #wara-shift-K_SPACE*/ {\n border: rgb(51, 51, 51);\n border-radius: 15px;\n border-top: 0px;\n background: -webkit-linear-gradient(top, rgb(51, 51, 51) 20%, rgba(0, 0, 0, 0) 20%), -webkit-linear-gradient(top, #aaaaaa 80%, rgb(51, 51, 51) 80%);\n margin-bottom: 9px;\n padding-top: 5px;\n }\n \n .kmw-keyboard-warang_citi /*shift-SYMBOLS-TOP-ROW*/\n #wara-shift-U_0021, #wara-shift-U_0021, #wara-shift-U_0040, #wara-shift-U_0023, #wara-shift-U_0024, #wara-shift-U_0025, #wara-shift-U_005E, #wara-shift-U_0026, #wara-shift-U_002A, #wara-shift-U_0028, #wara-shift-U_0029,\n \n #shift-U_0021, #shift-U_0040, #shift-U_0023, #shift-U_0024, #shift-U_0025, #shift-U_005E, #shift-U_0026, #shift-U_002A, #shift-U_0028, #shift-U_0029 {\n background-color: rgb(51, 51, 51);\n color: white;\n border-color: rgb(51, 51, 51);\n padding-bottom: 42px;\n border-radius: 0px;\n }\n \n \n .kmw-keyboard-warang_citi /*NUMLOCK-CSS*/ \n \n #default-K_NUMLOCK, #default-K_NUMLOCK, #shift-K_NUMLOCK, #lock-K_NUMLOCK, #default-K_NUMLOCK, #wara-shift-K_NUMLOCK, #wara-lock-K_NUMLOCK {\n \n font-size: 16px;\n }\n \n \n ";this.s16="qwertyiuopasdghjklzxcvbnm@QWERTYUIOPASDGHJKLZXCVBNM";this.s17="𑣄𑣟𑣈𑣜𑣒𑣅𑣆𑣇𑣉𑣘𑣁𑣞𑣑𑣋𑣙𑣎𑣌𑣚z𑣝c𑣀𑣗𑣓𑣖𑣿𑢤𑢿𑢨𑢼𑢲𑢥𑢧𑢦𑢩𑢸𑢡𑢾𑢱𑢫𑢹𑢮𑢬𑢺Z𑢽C𑢠𑢷𑢳𑢶";this.s18="Hh";this.s19="Nn";this.s20="Jj";this.s21="Gg";this.s22="Aa";this.s23="Rr";this.s24="Ii";this.s25="Uu";this.s26="𑣀𑣂𑣃𑣅𑣆𑣇𑣈𑣉𑣊𑣋𑣌𑣍𑣎𑣏𑣐𑣑𑣒𑣓𑣔𑣕𑣖𑣗𑣘𑣙𑣚𑣛𑣜𑣝𑣞𑣟𑣿𑢵𑢴𑢤𑢿𑢨𑢼𑢲𑢥𑢣𑢢𑢩𑢸𑢾𑢱𑢴𑢫𑢹𑢮𑢬𑢺𑢽𑢯𑢠𑢷𑢰𑢪𑢭𑢳𑢶";this.s27="𑢵𑢴𑢤𑢿𑢨𑢼𑢲𑢥𑢣𑢢𑢩𑢸𑢾𑢱𑢴𑢫𑢹𑢮𑢬𑢺𑢽𑢯𑢠𑢷𑢰𑢪𑢭𑢳𑢶";this.s28="𑣀𑣂𑣃𑣅𑣆𑣇𑣈𑣉𑣊𑣋𑣌𑣍𑣎𑣏𑣐𑣑𑣒𑣓𑣔𑣕𑣖𑣗𑣘𑣙𑣚𑣛𑣜𑣝𑣞𑣟";this.s29="0123456789";this.s30="𑣠𑣡𑣢𑣣𑣤𑣥𑣦𑣧𑣨𑣩";this.KVER="16.0.138.0";this.KVS=[];this.gs=function(t,e) {return this.g0(t,e);};this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16384,8)) {if(k.KFCM(1,t,['𑣿'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"@");}}else if(k.KKM(e,16385,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"1");}}else if(k.KKM(e,16385,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"2");}}else if(k.KKM(e,16385,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"3");}}else if(k.KKM(e,16385,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"4");}}else if(k.KKM(e,16385,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"5");}}else if(k.KKM(e,16385,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"6");}}else if(k.KKM(e,16385,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"7");}}else if(k.KKM(e,16385,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"8");}}else if(k.KKM(e,16385,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"9");}}else if(k.KKM(e,16385,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"0");}}else if(k.KKM(e,16384,48)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣠");}}else if(k.KKM(e,16384,49)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣡");}}else if(k.KKM(e,16384,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣢");}}else if(k.KKM(e,16384,51)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣣");}}else if(k.KKM(e,16384,52)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣤");}}else if(k.KKM(e,16384,53)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣥");}}else if(k.KKM(e,16384,54)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣦");}}else if(k.KKM(e,16384,55)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣧");}}else if(k.KKM(e,16384,56)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣨");}}else if(k.KKM(e,16384,57)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣩");}}else if(k.KKM(e,16400,50)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣿");}}else if(k.KKM(e,16400,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢡");}}else if(k.KKM(e,16400,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢷");}}else if(k.KKM(e,16400,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"C");}}else if(k.KKM(e,16400,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢱");}}else if(k.KKM(e,16400,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢨");}}else if(k.KKM(e,16400,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‍");}}else if(k.KKM(e,16400,71)) {if(k.KFCM(1,t,['𑣓'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣊");}else if(k.KFCM(1,t,['𑢳'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢪");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢫");}}else if(k.KKM(e,16400,72)) {if(k.KFCM(1,t,['c'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣏");}else if(k.KFCM(1,t,['𑣒'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣕");}else if(k.KFCM(1,t,['𑣑'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣔");}else if(k.KFCM(1,t,['C'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢯");}else if(k.KFCM(1,t,['𑢲'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢵");}else if(k.KFCM(1,t,['𑢱'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢴");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢹");}}else if(k.KKM(e,16400,73)) {if(k.KFCM(2,t,[' ','𑢡'])){r=m=1;k.KDC(2,t);k.KO(-1,t," 𑢡𑢦");}else if(k.KFCM(1,t,[{t:'a',a:this.s26}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s26,1,t);k.KO(-1,t,"𑢢");}else if(k.KFCM(1,t,['𑢡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢦");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢦");}}else if(k.KKM(e,16400,74)) {if(k.KFCM(1,t,['𑣓'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣍");}else if(k.KFCM(1,t,['𑢳'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢭");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢮");}}else if(k.KKM(e,16400,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢬");}}else if(k.KKM(e,16400,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢺");}}else if(k.KKM(e,16400,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢶");}}else if(k.KKM(e,16400,78)) {if(k.KFCM(1,t,['𑣓'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣐");}else if(k.KFCM(1,t,['𑢳'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢰");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢳");}}else if(k.KKM(e,16400,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢩");}}else if(k.KKM(e,16400,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢸");}}else if(k.KKM(e,16400,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢤");}}else if(k.KKM(e,16400,82)) {if(k.KFCM(1,t,['𑣜'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣛");}else if(k.KFCM(1,t,['𑢼'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢻");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢼");}}else if(k.KKM(e,16400,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢾");}}else if(k.KKM(e,16400,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢲");}}else if(k.KKM(e,16400,85)) {if(k.KFCM(2,t,[' ','𑢡'])){r=m=1;k.KDC(2,t);k.KO(-1,t," 𑢡𑢧");}else if(k.KFCM(1,t,[{t:'a',a:this.s26}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s26,1,t);k.KO(-1,t,"𑢣");}else if(k.KFCM(1,t,['𑢡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢧");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢧");}}else if(k.KKM(e,16400,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢠");}}else if(k.KKM(e,16400,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢿");}}else if(k.KKM(e,16400,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢽");}}else if(k.KKM(e,16400,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑢥");}}else if(k.KKM(e,16400,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"Z");}}else if(k.KKM(e,16384,65)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣁");}}else if(k.KKM(e,16384,66)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣗");}}else if(k.KKM(e,16384,67)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"c");}}else if(k.KKM(e,16384,68)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣑");}}else if(k.KKM(e,16384,69)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣈");}}else if(k.KKM(e,16384,70)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"‍");}}else if(k.KKM(e,16384,71)) {if(k.KFCM(1,t,['𑣓'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣊");}else if(k.KFCM(1,t,['𑢳'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢪");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣋");}}else if(k.KKM(e,16384,72)) {if(k.KFCM(1,t,['c'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣏");}else if(k.KFCM(1,t,['𑣒'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣕");}else if(k.KFCM(1,t,['𑣑'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣔");}else if(k.KFCM(1,t,['C'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢯");}else if(k.KFCM(1,t,['𑢲'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢵");}else if(k.KFCM(1,t,['𑢱'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢴");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣙");}}else if(k.KKM(e,16384,73)) {if(k.KFCM(2,t,[' ','𑣁'])){r=m=1;k.KDC(2,t);k.KO(-1,t," 𑣁𑣆");}else if(k.KFCM(2,t,[' ','𑢡'])){r=m=1;k.KDC(2,t);k.KO(-1,t," 𑢡𑢦");}else if(k.KFCM(1,t,[{t:'a',a:this.s26}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s26,1,t);k.KO(-1,t,"𑣂");}else if(k.KFCM(1,t,['𑣁'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣆");}else if(k.KFCM(1,t,['𑢡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢦");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣆");}}else if(k.KKM(e,16384,74)) {if(k.KFCM(1,t,['𑣓'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣍");}else if(k.KFCM(1,t,['𑢳'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢭");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣎");}}else if(k.KKM(e,16384,75)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣌");}}else if(k.KKM(e,16384,76)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣚");}}else if(k.KKM(e,16384,77)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣖");}}else if(k.KKM(e,16384,78)) {if(k.KFCM(1,t,['𑣓'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣐");}else if(k.KFCM(1,t,['𑢳'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢰");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣓");}}else if(k.KKM(e,16384,79)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣉");}}else if(k.KKM(e,16384,80)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣘");}}else if(k.KKM(e,16384,81)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣄");}}else if(k.KKM(e,16384,82)) {if(k.KFCM(1,t,['𑣜'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣛");}else if(k.KFCM(1,t,['𑢼'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢻");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣜");}}else if(k.KKM(e,16384,83)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣞");}}else if(k.KKM(e,16384,84)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣒");}}else if(k.KKM(e,16384,85)) {if(k.KFCM(2,t,[' ','𑣁'])){r=m=1;k.KDC(2,t);k.KO(-1,t," 𑣁𑣇");}else if(k.KFCM(2,t,[' ','𑢡'])){r=m=1;k.KDC(2,t);k.KO(-1,t," 𑢡𑢧");}else if(k.KFCM(1,t,[{t:'a',a:this.s26}])){r=m=1;k.KDC(1,t);k.KIO(-1,this.s26,1,t);k.KO(-1,t,"𑣃");}else if(k.KFCM(1,t,['𑣁'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑣇");}else if(k.KFCM(1,t,['𑢡'])){r=m=1;k.KDC(1,t);k.KO(-1,t,"𑢧");}else if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣇");}}else if(k.KKM(e,16384,86)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣀");}}else if(k.KKM(e,16384,87)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣟");}}else if(k.KKM(e,16384,88)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣝");}}else if(k.KKM(e,16384,89)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"𑣅");}}else if(k.KKM(e,16384,90)) {if(1){r=m=1;k.KDC(0,t);k.KO(-1,t,"z");}}return r;};} \ No newline at end of file diff --git a/kmw/engine/17.0.203/keymanweb.js b/kmw/engine/17.0.203/keymanweb.js new file mode 100644 index 000000000..7aae19007 --- /dev/null +++ b/kmw/engine/17.0.203/keymanweb.js @@ -0,0 +1,2 @@ +(function(){var Qi=Object.create;var Rt=Object.defineProperty;var Ci=Object.getOwnPropertyDescriptor;var bi=Object.getOwnPropertyNames;var hi=Object.getPrototypeOf,Ui=Object.prototype.hasOwnProperty;var En=function(i,t){return function(){return t||i((t={exports:{}}).exports,t),t.exports}},kn=function(i,t){for(var e in t)Rt(i,e,{get:t[e],enumerable:!0})},vt=function(i,t,e,n){if(t&&typeof t=="object"||typeof t=="function")for(var c=bi(t),l=0,r=c.length,s;l=0;o--)(B=e[o])&&(s=(r<3?B(s):r>3?B(n,c,s):B(n,c))||s);return r>3&&s&&Object.defineProperty(n,c,s),s},Dn=function(e,n,c,l){function r(s){return s instanceof c?s:new c(function(B){B(s)})}return new(c||(c=Promise))(function(s,B){function o(F){try{a(l.next(F))}catch(y){B(y)}}function g(F){try{a(l.throw(F))}catch(y){B(y)}}function a(F){F.done?s(F.value):r(F.value).then(o,g)}a((l=l.apply(e,n||[])).next())})},Mn=function(e,n){var c={label:0,sent:function(){if(s[0]&1)throw s[1];return s[1]},trys:[],ops:[]},l,r,s,B;return B={next:o(0),throw:o(1),return:o(2)},typeof Symbol=="function"&&(B[Symbol.iterator]=function(){return this}),B;function o(a){return function(F){return g([a,F])}}function g(a){if(l)throw new TypeError("Generator is already executing.");for(;B&&(B=0,a[0]&&(c=0)),c;)try{if(l=1,r&&(s=a[0]&2?r.return:a[0]?r.throw||((s=r.return)&&s.call(r),0):r.next)&&!(s=s.call(r,a[1])).done)return s;switch(r=0,s&&(a=[a[0]&2,s.value]),a[0]){case 0:case 1:s=a;break;case 4:return c.label++,{value:a[1],done:!1};case 5:c.label++,r=a[1],a=[0];continue;case 7:a=c.ops.pop(),c.trys.pop();continue;default:if(s=c.trys,!(s=s.length>0&&s[s.length-1])&&(a[0]===6||a[0]===2)){c=0;continue}if(a[0]===3&&(!s||a[1]>s[0]&&a[1]?~",'{|}"']],isKnownOSKModifierKey:function(i){switch(i){case"K_SHIFT":case"K_LOPT":case"K_ROPT":case"K_NUMLOCK":case"K_CAPS":return!0;default:if(q.keyCodes[i]>=5e4)return!0;var t=q[i];if(t>5e4&&t<50011)return!0}return!1},getModifierState:function(i){var t=0;i.indexOf("shift")>=0&&(t|=q.modifierCodes.SHIFT);var e=!1;i.indexOf("leftctrl")>=0&&(t|=q.modifierCodes.LCTRL,e=!0),i.indexOf("rightctrl")>=0&&(t|=q.modifierCodes.RCTRL,e=!0),i.indexOf("ctrl")>=0&&!e&&(t|=q.modifierCodes.CTRL);var n=!1;return i.indexOf("leftalt")>=0&&(t|=q.modifierCodes.LALT,n=!0),i.indexOf("rightalt")>=0&&(t|=q.modifierCodes.RALT,n=!0),i.indexOf("alt")>=0&&!n&&(t|=q.modifierCodes.ALT),t},getStateFromLayer:function(i){var t=0;return i.indexOf("caps")>=0?t|=q.modifierCodes.CAPS:t|=q.modifierCodes.NO_CAPS,t}},I=q;var xe;(function(i){i.Enter="\n",i.Backspace="\b"})(xe||(xe={}));var Xi=function(){function i(){}return i.prototype.codeForEvent=function(t){return I.keyCodes[t.kName]||t.Lcode},i.prototype.forAny=function(t,e,n){var c="";if((c=this.forSpecialEmulation(t))!=null)return c;if(!e&&(c=this.forNumpadKeys(t))!=null)return c;if((c=this.forUnicodeKeynames(t,n))!=null)return c;if((c=this.forBaseKeys(t,n))!=null)return c;var l=this.codeForEvent(t);switch(l){default:return null}},i.prototype.isCommand=function(t){var e=this.codeForEvent(t);switch(e){default:return!1}},i.prototype.applyCommand=function(t,e){},i.prototype.forSpecialEmulation=function(t){var e=this.codeForEvent(t);switch(e){case I.keyCodes.K_BKSP:return xe.Backspace;case I.keyCodes.K_ENTER:return xe.Enter;default:return null}},i.prototype.forNumpadKeys=function(t){if(t.Lcode>=I.keyCodes.K_NP0&&t.Lcode<=I.keyCodes.K_NPSLASH){if(t.Lcode<106)var e=t.Lcode-48;else e=t.Lcode-64;var n=String._kmwFromCharCode(e);return n}else return null},i.prototype.forUnicodeKeynames=function(t,e){var n=t.kName;if(!n||n.substr(0,2)!="U_")return null;for(var c="",l=n.substr(2).split("_"),r=0,s=l;r=I.keyCodes.K_0&&n<=I.keyCodes.K_9)return I.codesUS[c][0][n-I.keyCodes.K_0];if(n>=I.keyCodes.K_A&&n<=I.keyCodes.K_Z)return String.fromCharCode(n+(c?0:32));if(n>=I.keyCodes.K_COLON&&n<=I.keyCodes.K_BKQUOTE)return I.codesUS[c][1][n-I.keyCodes.K_COLON];if(n>=I.keyCodes.K_LBRKT&&n<=I.keyCodes.K_QUOTE)return I.codesUS[c][2][n-I.keyCodes.K_LBRKT];if(n==I.keyCodes.K_oE2)return c?"|":"\\"}catch(l){e&&(e.errorLog="Error detected with default mapping for key: code = "+n+", shift state = "+(c==1?"shift":"default"))}return null},i}(),Ge=Xi;var pi=new Ge,mi=function(){function i(t){this.isSynthetic=!0;for(var e in t)t[e]!==void 0&&(this[e]=t[e])}return i.constructNullKeyEvent=function(t){var e=new i({Lcode:0,kName:"",device:t,Lstates:void 0,Lmodifiers:void 0,vkCode:void 0,LisVirtualKey:void 0});return e},Object.defineProperty(i.prototype,"isModifier",{get:function(){switch(this.Lcode){case 16:case 17:case 18:case 20:case 144:case 145:return!0;default:return!1}},enumerable:!1,configurable:!0}),i.prototype.setMnemonicCode=function(t,e){if(this.Lcode!=I.keyCodes.K_SPACE){var n=new i(this);for(var c in this)n[c]=this[c];n.kName="K_xxxx",n.Lmodifiers=t?16:0;var l=pi.forAny(n,!0);this.vkCode=this.Lcode,l?this.Lcode=l.charCodeAt(0):this.isModifier||delete this.Lcode}e&&(this.Lcode>=65&&this.Lcode<=90||this.Lcode>=97&&this.Lcode<=122)&&(this.Lmodifiers^=16,this.Lcode^=32)},i}(),$=mi;var Xe=function(){function i(){}return i}(),Zi=function(){function i(){this.FF=new Xe,this.Safari=new Xe,this.Opera=new Xe,this.FF.k61=187,this.FF.k59=186,this.FF.k173=189}return i}(),Li=function(){function i(){this.se=new Xe,this.se.k220=192,this.se.k187=189,this.se.k219=187,this.se.k221=219,this.se.k186=221,this.se.k191=220,this.se.k192=186,this.se.k189=191,this.uk=new Xe,this.uk.k223=192,this.uk.k192=222,this.uk.k222=226,this.uk.k220=220}return i}(),Ji=function(){function i(){}return i._usCodeInit=function(){var t=new Xe,e=new Xe;t.k192=96,t.k49=49,t.k50=50,t.k51=51,t.k52=52,t.k53=53,t.k54=54,t.k55=55,t.k56=56,t.k57=57,t.k48=48,t.k189=45,t.k187=61,t.k81=113,t.k87=119,t.k69=101,t.k82=114,t.k84=116,t.k89=121,t.k85=117,t.k73=105,t.k79=111,t.k80=112,t.k219=91,t.k221=93,t.k220=92,t.k65=97,t.k83=115,t.k68=100,t.k70=102,t.k71=103,t.k72=104,t.k74=106,t.k75=107,t.k76=108,t.k186=59,t.k222=39,t.k90=122,t.k88=120,t.k67=99,t.k86=118,t.k66=98,t.k78=110,t.k77=109,t.k188=44,t.k190=46,t.k191=47,e.k192=126,e.k49=33,e.k50=64,e.k51=35,e.k52=36,e.k53=37,e.k54=94,e.k55=38,e.k56=42,e.k57=40,e.k48=41,e.k189=95,e.k187=43,e.k81=81,e.k87=87,e.k69=69,e.k82=82,e.k84=84,e.k89=89,e.k85=85,e.k73=73,e.k79=79,e.k80=80,e.k219=123,e.k221=125,e.k220=124,e.k65=65,e.k83=83,e.k68=68,e.k70=70,e.k71=71,e.k72=72,e.k74=74,e.k75=75,e.k76=76,e.k186=58,e.k222=34,e.k90=90,e.k88=88,e.k67=67,e.k86=86,e.k66=66,e.k78=78,e.k77=77,e.k188=60,e.k190=62,e.k191=63,i._usCharCodes=[t,e]},i._USKeyCodeToCharCode=function(t){return i.usCharCodes[t.Lmodifiers&16?1:0]["k"+t.Lcode]},Object.defineProperty(i,"usCharCodes",{get:function(){return i._usCharCodes||i._usCodeInit(),i._usCharCodes},enumerable:!1,configurable:!0}),i.browserMap=new Zi,i.languageMap=new Li,i}(),de=Ji;function ke(i,t,e){e.enumerable=!0}var M=function(){function i(){this.isMnemonic=!1}return Object.defineProperty(i.prototype,"baseKeyID",{get:function(){if(typeof this.id!="undefined")return this.id},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"isPadding",{get:function(){return this.sp==10},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"coreID",{get:function(){if(typeof this.id!="undefined"){var t=this.id||"";return this.displayLayer!=this.layer&&(t=t+"+"+this.layer),t}},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"elementID",{get:function(){if(typeof this.id!="undefined")return this.displayLayer+"-"+this.coreID},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"baseKeyEvent",{get:function(){return new $(this._baseKeyEvent)},enumerable:!1,configurable:!0}),i.unicodeIDToText=function(t,e){if(!t||t.substring(0,2)!="U_")return null;for(var n="",c=t.substring(2).split("_"),l=0,r=c;l0){var u=s[s.length-1];if(s.length==1&&u.pad<0){var Q=u.width/l,C=1-(F+Q+y);a(u,C,Q,F)}else{var C=u.pad/l,Q=1-(F+C+y);a(u,C,Q,F)}}var h=new i;for(var o in h)t.hasOwnProperty(o)||(t[o]=h[o]);var b=t;b.proportionalY=r},i.prototype.populateKeyMap=function(t){this.key.forEach(function(e){e.coreID&&(t[e.coreID]=e)})},i.SPECIAL_LABEL=/\*\w+\*/,i}();var _n=function(){function i(){}return i.sanitize=function(t){for(var e=0,n=t.row;el&&(l=o)}n.formFactor=="desktop"?l+=5:l+=M.DEFAULT_RIGHT_MARGIN;for(var u=t.row.length,Q=0;Q.5*r.proportionalWidth?(o=s-.5*r.proportionalWidth,s=.5):(o=0,s/=r.proportionalWidth),B>.5*n.rowProportionalHeight?(g=B-.5*n.rowProportionalHeight,B=.5):(g=0,B/=n.rowProportionalHeight),o*=e,o+=s*n.rowProportionalHeight,g+=B*n.rowProportionalHeight;var a=o*o+g*g;c[r.coreID]=a})}),c},i.prototype.getKey=function(t){t.indexOf(this.id+"-")==0&&(t=t.replace(this.id+"-",""));var e=t.split("::");if(e.length>1){var n=this.keyMap[e[0]];return n.getSubkey(e[1])}else return this.keyMap[t]},i}();var st=function(){function i(){}return i.prototype.getLayer=function(t){return this.layerMap[t]},i.correctLayerEmptyRowBug=function(t){for(var e=0;e=0;l--)(!Array.isArray(c[l].key)||c[l].key.length==0)&&c.splice(l,1)}},i.sanitize=function(t){i.correctLayerEmptyRowBug(t.layer);for(var e=0,n=t.layer;e0)return e?-1:1;c++}while(c1114111||Math.floor(n)!==n)throw new RangeError("Invalid code point "+n);n<65536?t.push(n):(n-=65536,t.push((n>>10)+55296),t.push(n%1024+56320))}return String.fromCharCode.apply(void 0,t)},String.prototype.kmwCharCodeAt=function(i){var t=String(this),e=0;if(i<0||i>=t.length)return NaN;for(var n=0;n=55296&&c<=56319&&t.length>e+1){var l=t.charCodeAt(e+1);if(l>=56320&&l<=57343)return(c-55296<<10)+(l-56320)+65536}return c},String.prototype.kmwIndexOf=function(i,t){var e=String(this),n=e.indexOf(i,t);if(n<0)return n;for(var c=0,l=0;l!==null&&lt){var l=i;i=t,t=l}n=e.kmwCodePointToCodeUnit(i),c=e.kmwCodePointToCodeUnit(t)}return(isNaN(n)||n===null)&&(n=0),(isNaN(c)||c===null)&&(c=e.length),e.substring(n,c)},String.prototype.kmwNextChar=function(i){var t=String(this);if(i===null||i<0||i>=t.length-1)return null;var e=t.charCodeAt(i);if(e>=55296&&e<=56319&&t.length>i+1){var n=t.charCodeAt(i+1);if(n>=56320&&n<=57343)return i==t.length-2?null:i+2}return i+1},String.prototype.kmwPrevChar=function(i){var t=String(this);if(i==null||i<=0||i>t.length)return null;var e=t.charCodeAt(i-1);if(e>=56320&&e<=57343&&i>1){var n=t.charCodeAt(i-2);if(n>=55296&&n<=56319)return i-2}return i-1},String.prototype.kmwCodePointToCodeUnit=function(i){if(i===null)return null;var t=String(this),e=0;if(i<0){e=t.length;for(var n=0;n>i;n--)e=t.kmwPrevChar(e);return e}if(i==t.kmwLength())return t.length;for(var n=0;n=0?t.kmwSubstr(i,1):""},String.prototype.kmwBMPNextChar=function(i){var t=String(this);return i<0||i>=t.length-1?null:i+1},String.prototype.kmwBMPPrevChar=function(i){var t=String(this);return i<=0||i>t.length?null:i-1},String.prototype.kmwBMPCodePointToCodeUnit=function(i){return i},String.prototype.kmwBMPCodeUnitToCodePoint=function(i){return i},String.prototype.kmwBMPLength=function(){var i=String(this);return i.length},String.prototype.kmwBMPSubstr=function(i,t){var e=String(this);return i>-1?e.substr(i,t):e.substr(e.length+i,-i)},String.kmwEnableSupplementaryPlane=function(i){var t=String.prototype;String._kmwFromCharCode=i?String.kmwFromCharCode:String.fromCharCode,t._kmwCharAt=i?t.kmwCharAt:t.charAt,t._kmwCharCodeAt=i?t.kmwCharCodeAt:t.charCodeAt,t._kmwIndexOf=i?t.kmwIndexOf:t.indexOf,t._kmwLastIndexOf=i?t.kmwLastIndexOf:t.lastIndexOf,t._kmwSlice=i?t.kmwSlice:t.slice,t._kmwSubstring=i?t.kmwSubstring:t.substring,t._kmwSubstr=i?t.kmwSubstr:t.kmwBMPSubstr,t._kmwLength=i?t.kmwLength:t.kmwBMPLength,t._kmwNextChar=i?t.kmwNextChar:t.kmwBMPNextChar,t._kmwPrevChar=i?t.kmwPrevChar:t.kmwBMPPrevChar,t._kmwCodePointToCodeUnit=i?t.kmwCodePointToCodeUnit:t.kmwBMPCodePointToCodeUnit,t._kmwCodeUnitToCodePoint=i?t.kmwCodeUnitToCodePoint:t.kmwBMPCodeUnitToCodePoint},String._kmwFromCharCode||String.kmwEnableSupplementaryPlane(!1)}Oe();var Ri=function(){function i(t){var e=this;this._hasResolved=!1,this._hasRejected=!1,this._promise=new Promise(function(n,c){e.resolve=function(l){e._hasResolved=!0,n(l)},e.reject=function(l){e._hasRejected=!0,c(l)},t&&t(e.resolve,e.reject)})}return Object.defineProperty(i.prototype,"hasResolved",{get:function(){return this._hasResolved},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"hasRejected",{get:function(){return this._hasRejected},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"hasFinalized",{get:function(){return this.hasResolved||this.hasRejected},enumerable:!1,configurable:!0}),i.prototype.then=function(t,e){return this._promise.then(t,e)},i.prototype.catch=function(t){return this._promise.catch(t)},i.prototype.finally=function(t){return this._promise.finally(t)},Object.defineProperty(i.prototype,"corePromise",{get:function(){return this._promise},enumerable:!1,configurable:!0}),i}(),A=Ri;var ee=function(){function i(){}return i.buildDefaultLayout=function(t,e,n){var c=n;typeof i.dfltLayout[c]!="object"&&(c="desktop");var l=I.modifierBitmasks.NON_CHIRAL,r=z.CURRENT;e&&(l=e.modifierBitmask,r=e.compilerVersion),t||(t=this.DEFAULT_RAW_SPEC);var s=Re(i.dfltLayout[c]),B,o=s.layer,g=t.KLS,a=t.K102,F,y,u,Q,C,h,b,U,V=(l&I.modifierBitmasks.IS_CHIRAL)!=0;if(t.F){var X=/^(?:(?:italic|bold) )* *[0-9.eE-]+(?:[a-z]+) "(.+)"$/.exec(t.F);X&&(s.font=X[1])}var L=!(typeof g=="undefined"||!g);L||(g=t.KLS=i.processLegacyDefinitions(t.BK));var P=/\*\w+\*/,p=Object.getOwnPropertyNames(g),E=[];if(p.splice(p.indexOf("default"),1),p=["default"].concat(p),e&&e.emulatesAltGr&&(p.indexOf("leftctrl-leftalt")==-1&&p.indexOf("rightalt")!=-1&&(p.push("leftctrl-leftalt"),g["leftctrl-leftalt"]=g.rightalt),p.indexOf("leftctrl-leftalt-shift")==-1&&p.indexOf("rightalt-shift")!=-1&&(p.push("leftctrl-leftalt-shift"),g["leftctrl-leftalt-shift"]=g["rightalt-shift"])),s.displayUnderlying=e?!!e.scriptObject.KDU:!1,n=="desktop")for(E=i.generateLayerIds(V),B=0;B0&&(o[B]=Re(o[0])),o[B].id=oe[B],o[B].nextlayer=oe[B],i.formatDefaultLayer(o[B],V,n,!!a);for(B=0;B=0&&ge0&&S!=null&&(S.sp=i.buttonClasses["SHIFT-ON"],S.sk=null,S.text=i.modifierSpecials[o[B].id]?i.modifierSpecials[o[B].id]:"*Shift*")}return s},i.getLayerId=function(t){var e=I.modifierCodes,n="";return t==0?"default":(t&e.LCTRL&&(n=(n.length>0?n+"-":"")+"leftctrl"),t&e.RCTRL&&(n=(n.length>0?n+"-":"")+"rightctrl"),t&e.LALT&&(n=(n.length>0?n+"-":"")+"leftalt"),t&e.RALT&&(n=(n.length>0?n+"-":"")+"rightalt"),t&e.SHIFT&&(n=(n.length>0?n+"-":"")+"shift"),t&e.CTRL&&(n=(n.length>0?n+"-":"")+"ctrl"),t&e.ALT&&(n=(n.length>0?n+"-":"")+"alt"),n)},i.generateLayerIds=function(t){var e,n;t?(e=32,n=1):(e=8,n=16);for(var c=[],l=0;l?~~~~~ ",i.DEFAULT_RAW_SPEC={F:"Tahoma",BK:i.dfltText},i.buttonClasses={DEFAULT:0,SHIFT:1,"SHIFT-ON":2,SPECIAL:3,"SPECIAL-ON":4,DEADKEY:8,BLANK:9,HIDDEN:10},i.modifierSpecials={leftalt:"*LAlt*",rightalt:"*RAlt*",alt:"*Alt*",leftctrl:"*LCtrl*",rightctrl:"*RCtrl*",ctrl:"*Ctrl*","ctrl-alt":"*AltGr*","leftctrl-leftalt":"*LAltCtrl*","rightctrl-rightalt":"*RAltCtrl*","leftctrl-leftalt-shift":"*LAltCtrlShift*","rightctrl-rightalt-shift":"*RAltCtrlShift*",shift:"*Shift*","shift-alt":"*AltShift*","shift-ctrl":"*CtrlShift*","shift-ctrl-alt":"*AltCtrlShift*","leftalt-shift":"*LAltShift*","rightalt-shift":"*RAltShift*","leftctrl-shift":"*LCtrlShift*","rightctrl-shift":"*RCtrlShift*"},i.dfltLayout={desktop:{font:"Tahoma,Helvetica",layer:[{id:"default",row:[{id:"1",key:[{id:"K_BKQUOTE"},{id:"K_1"},{id:"K_2"},{id:"K_3"},{id:"K_4"},{id:"K_5"},{id:"K_6"},{id:"K_7"},{id:"K_8"},{id:"K_9"},{id:"K_0"},{id:"K_HYPHEN"},{id:"K_EQUAL"},{id:"K_BKSP",text:"*BkSp*",sp:"1",width:"130"}]},{id:"2",key:[{id:"K_TAB",text:"*Tab*",sp:"1",width:"130"},{id:"K_Q"},{id:"K_W"},{id:"K_E"},{id:"K_R"},{id:"K_T"},{id:"K_Y"},{id:"K_U"},{id:"K_I"},{id:"K_O"},{id:"K_P"},{id:"K_LBRKT"},{id:"K_RBRKT"},{id:"K_BKSLASH"}]},{id:"3",key:[{id:"K_CAPS",text:"*Caps*",sp:"1",width:"165"},{id:"K_A"},{id:"K_S"},{id:"K_D"},{id:"K_F"},{id:"K_G"},{id:"K_H"},{id:"K_J"},{id:"K_K"},{id:"K_L"},{id:"K_COLON"},{id:"K_QUOTE"},{id:"K_ENTER",text:"*Enter*",sp:"1",width:"165"}]},{id:"4",key:[{id:"K_SHIFT",text:"*Shift*",sp:"1",width:"130"},{id:"K_oE2"},{id:"K_Z"},{id:"K_X"},{id:"K_C"},{id:"K_V"},{id:"K_B"},{id:"K_N"},{id:"K_M"},{id:"K_COMMA"},{id:"K_PERIOD"},{id:"K_SLASH"},{id:"K_RSHIFT",text:"*Shift*",sp:"1",width:"130"}]},{id:"5",key:[{id:"K_LCONTROL",text:"*Ctrl*",sp:"1",width:"170"},{id:"K_LALT",text:"*Alt*",sp:"1",width:"160"},{id:"K_SPACE",text:"",width:"770"},{id:"K_RALT",text:"*Alt*",sp:"1",width:"160"},{id:"K_RCONTROL",text:"*Ctrl*",sp:"1",width:"170"}]}]}]},tablet:{font:"Tahoma,Helvetica",layer:[{id:"default",row:[{id:"0",key:[{id:"K_1"},{id:"K_2"},{id:"K_3"},{id:"K_4"},{id:"K_5"},{id:"K_6"},{id:"K_7"},{id:"K_8"},{id:"K_9"},{id:"K_0"},{id:"K_HYPHEN"},{id:"K_EQUAL"},{sp:"10",width:"1"}]},{id:"1",key:[{id:"K_Q",pad:"25"},{id:"K_W"},{id:"K_E"},{id:"K_R"},{id:"K_T"},{id:"K_Y"},{id:"K_U"},{id:"K_I"},{id:"K_O"},{id:"K_P"},{id:"K_LBRKT"},{id:"K_RBRKT"},{sp:"10",width:"1"}]},{id:"2",key:[{id:"K_A",pad:"50"},{id:"K_S"},{id:"K_D"},{id:"K_F"},{id:"K_G"},{id:"K_H"},{id:"K_J"},{id:"K_K"},{id:"K_L"},{id:"K_COLON"},{id:"K_QUOTE"},{id:"K_BKSLASH",width:"90"}]},{id:"3",key:[{id:"K_oE2",width:"90"},{id:"K_Z"},{id:"K_X"},{id:"K_C"},{id:"K_V"},{id:"K_B"},{id:"K_N"},{id:"K_M"},{id:"K_COMMA"},{id:"K_PERIOD"},{id:"K_SLASH"},{id:"K_BKQUOTE"},{sp:"10",width:"1"}]},{id:"4",key:[{id:"K_SHIFT",text:"*Shift*",sp:"1",width:"200",sk:[{id:"K_LCONTROL",text:"*Ctrl*",sp:"1",width:"50",nextlayer:"ctrl"},{id:"K_LCONTROL",text:"*LCtrl*",sp:"1",width:"50",nextlayer:"leftctrl"},{id:"K_RCONTROL",text:"*RCtrl*",sp:"1",width:"50",nextlayer:"rightctrl"},{id:"K_LALT",text:"*Alt*",sp:"1",width:"50",nextlayer:"alt"},{id:"K_LALT",text:"*LAlt*",sp:"1",width:"50",nextlayer:"leftalt"},{id:"K_RALT",text:"*RAlt*",sp:"1",width:"50",nextlayer:"rightalt"},{id:"K_ALTGR",text:"*AltGr*",sp:"1",width:"50",nextlayer:"ctrl-alt"}]},{id:"K_LOPT",text:"*Menu*",sp:"1",width:"150"},{id:"K_SPACE",text:"",width:"570"},{id:"K_BKSP",text:"*BkSp*",sp:"1",width:"150"},{id:"K_ENTER",text:"*Enter*",sp:"1",width:"200"}]}]}]},phone:{font:"Tahoma,Helvetica",layer:[{id:"default",row:[{id:"0",key:[{id:"K_1"},{id:"K_2"},{id:"K_3"},{id:"K_4"},{id:"K_5"},{id:"K_6"},{id:"K_7"},{id:"K_8"},{id:"K_9"},{id:"K_0"},{id:"K_HYPHEN"},{id:"K_EQUAL"},{sp:"10",width:"1"}]},{id:"1",key:[{id:"K_Q",pad:"25"},{id:"K_W"},{id:"K_E"},{id:"K_R"},{id:"K_T"},{id:"K_Y"},{id:"K_U"},{id:"K_I"},{id:"K_O"},{id:"K_P"},{id:"K_LBRKT"},{id:"K_RBRKT"},{sp:"10",width:"1"}]},{id:"2",key:[{id:"K_A",pad:"50"},{id:"K_S"},{id:"K_D"},{id:"K_F"},{id:"K_G"},{id:"K_H"},{id:"K_J"},{id:"K_K"},{id:"K_L"},{id:"K_COLON"},{id:"K_QUOTE"},{id:"K_BKSLASH",width:"90"}]},{id:"3",key:[{id:"K_oE2",width:"90"},{id:"K_Z"},{id:"K_X"},{id:"K_C"},{id:"K_V"},{id:"K_B"},{id:"K_N"},{id:"K_M"},{id:"K_COMMA"},{id:"K_PERIOD"},{id:"K_SLASH"},{id:"K_BKQUOTE"},{sp:"10",width:"1"}]},{id:"4",key:[{id:"K_SHIFT",text:"*Shift*",sp:"1",width:"200",sk:[{id:"K_LCONTROL",text:"*Ctrl*",sp:"1",width:"50",nextlayer:"ctrl"},{id:"K_LCONTROL",text:"*LCtrl*",sp:"1",width:"50",nextlayer:"leftctrl"},{id:"K_RCONTROL",text:"*RCtrl*",sp:"1",width:"50",nextlayer:"rightctrl"},{id:"K_LALT",text:"*Alt*",sp:"1",width:"50",nextlayer:"alt"},{id:"K_LALT",text:"*LAlt*",sp:"1",width:"50",nextlayer:"leftalt"},{id:"K_RALT",text:"*RAlt*",sp:"1",width:"50",nextlayer:"rightalt"},{id:"K_ALTGR",text:"*AltGr*",sp:"1",width:"50",nextlayer:"ctrl-alt"}]},{id:"K_LOPT",text:"*Menu*",width:"150",sp:"1"},{id:"K_SPACE",width:"570",text:""},{id:"K_BKSP",text:"*BkSp*",width:"150",sp:"1"},{id:"K_ENTER",text:"*Enter*",width:"200",sp:"1"}]}]}]}},i}();var Ai=function(){function i(){this.stores={}}return i}(),pe;(function(i){i[i.NOT_LOADED=void 0]="NOT_LOADED",i[i.POLYFILLED=1]="POLYFILLED",i[i.CALIBRATED=2]="CALIBRATED"})(pe||(pe={}));var fi=function(){function i(t){t?this.scriptObject=t:this.scriptObject=i.DEFAULT_SCRIPT_OBJECT,this.layoutStates={}}return i.prototype.process=function(t,e){return this.scriptObject.gs(t,e)},i.prototype.processNewContextEvent=function(t,e){return this.scriptObject.gn?this.scriptObject.gn(t,e):!1},i.prototype.processPostKeystroke=function(t,e){return this.scriptObject.gpk?this.scriptObject.gpk(t,e):!1},Object.defineProperty(i.prototype,"isHollow",{get:function(){return this.scriptObject==i.DEFAULT_SCRIPT_OBJECT},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"id",{get:function(){return this.scriptObject.KI},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"name",{get:function(){return this.scriptObject.KN},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"variableStores",{get:function(){var t=this.scriptObject.KVS,e={};if(Array.isArray(t))for(var n=0,c=t;n0){e=this._legacyLayoutSpec;break}}if(!e&&(this.helpText==""||t!=x.FormFactor.Desktop)&&(e={F:"Tahoma",BK:ee.dfltText}),this._layouts||(this._layouts={}),e){var l=this._layouts[t]=ee.buildDefaultLayout(e,this,t);return l.isDefault=!0,l}else return this._layouts[t]=null,null},i.prototype.layout=function(t){var e=this.findOrConstructLayout(t);return e?(this.layoutStates[t]==pe.NOT_LOADED&&(e=st.polyfill(e,this,t),this.layoutStates[t]=pe.POLYFILLED),e):null},i.prototype.refreshLayouts=function(){var t=[x.FormFactor.Desktop,x.FormFactor.Phone,x.FormFactor.Tablet],e=this;t.forEach(function(n){e.layoutStates[n]=pe.NOT_LOADED})},i.prototype.markLayoutCalibrated=function(t){this.layoutStates[t]!=pe.NOT_LOADED&&(this.layoutStates[t]=pe.CALIBRATED)},i.prototype.getLayoutState=function(t){return this.layoutStates[t]},i.prototype.constructNullKeyEvent=function(t,e){e=e||{K_CAPS:!1,K_NUMLOCK:!1,K_SCROLL:!1};var n=$.constructNullKeyEvent(t);return this.setSyntheticEventDefaults(n,e),n},i.prototype.constructKeyEvent=function(t,e,n){var c=t.baseKeyEvent;c.device=e,this.isMnemonic&&c.setMnemonicCode(t.layer.indexOf("shift")!=-1,n.K_CAPS),this.setSyntheticEventDefaults(c,n);var l={K_CAPS:I.stateBitmasks.CAPS,K_NUMLOCK:I.stateBitmasks.NUM_LOCK,K_SCROLL:I.stateBitmasks.SCROLL_LOCK},r=l[c.kName];return r&&(c.Lstates^=r,c.LmodifierChange=!0),c},i.prototype.setSyntheticEventDefaults=function(t,e){t.device.touchable||(t.Lstates=0,t.Lstates|=e.K_CAPS?I.modifierCodes.CAPS:I.modifierCodes.NO_CAPS,t.Lstates|=e.K_NUMLOCK?I.modifierCodes.NUM_LOCK:I.modifierCodes.NO_NUM_LOCK,t.Lstates|=e.K_SCROLL?I.modifierCodes.SCROLL_LOCK:I.modifierCodes.NO_SCROLL_LOCK),t.kName&&t.kName.substr(0,2)=="U_"&&(t.LisVirtualKey=!1),typeof t.Lcode=="undefined"&&(t.Lcode=this.getVKDictionaryCode(t.kName),t.Lcode||(t.Lcode=1)),(t.Lmodifiers&I.modifierBitmasks.ALT_GR_SIM)==I.modifierBitmasks.ALT_GR_SIM&&this.emulatesAltGr&&(t.Lmodifiers&=~I.modifierBitmasks.ALT_GR_SIM,t.Lmodifiers|=I.modifierCodes.RALT)},i.prototype.getVKDictionaryCode=function(t){if(!this.scriptObject.VKDictionary){var e=[];if(typeof this.scriptObject.KVKD=="string")for(var n=this.scriptObject.KVKD.split(" "),c=0;ct&&(l.p+=e)}},i.prototype.count=function(){return this.dks.length},i}();var jn=function(){function i(t){this.id=t}return i.prototype.set=function(t){throw new Error("System store with ID "+this.id+" may not be directly set.")},i}();var Bt=function(i){(0,d.__extends)(t,i);function t(e,n){var c=i.call(this,e)||this;return c.handler=null,c._value=n,c}return Object.defineProperty(t.prototype,"value",{get:function(){return this._value},enumerable:!1,configurable:!0}),t.prototype.matches=function(e){return this._value==e},t.prototype.set=function(e){this.handler&&this.handler(this,e)||(this._value=e)},t}(jn);var qn=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this,f.TSS_PLATFORM)||this;return n.kbdInterface=e,n}return t.prototype.matches=function(e){var n,c,l=e.split(" "),r=this.kbdInterface.activeDevice;for(n=0;n0&&o=55296&&y<=56319){var C=u>=56320&&u<=57343;C=C||Q>=56320&&Q<=57343,C&&(o=o-1)}}var h=n._kmwCodeUnitToCodePoint(o),b=c-h,U=l-h,V=e._kmwSubstr(h,U),X=e._kmwLength()-l,L=n._kmwLength()-c,P=L-X;return P<0&&(V=V+e._kmwSubstr(l,-P),P=0),new Ti(V,b,P)},i.prototype.buildTranscriptionFrom=function(t,e,n,c){var l=this.buildTransformFrom(t);return new Ei(e,l,H.from(t,n),c)},i.prototype.restoreTo=function(t){this.setTextBeforeCaret(t.getTextBeforeCaret()),this.setTextAfterCaret(t.getTextAfterCaret()),this._dks=t._dks.clone()},i.prototype.apply=function(t){t.deleteRight&&this.setTextAfterCaret(this.getTextAfterCaret()._kmwSubstr(t.deleteRight)),t.deleteLeft&&this.deleteCharsBeforeCaret(t.deleteLeft),t.insert&&this.insertTextBeforeCaret(t.insert),this._dks.clear()},i.prototype.setTextBeforeCaret=function(t){this.deleteCharsBeforeCaret(this.getTextBeforeCaret()._kmwLength()),this.insertTextBeforeCaret(t)},i.prototype.saveProperties=function(){},i.prototype.restoreProperties=function(){},i}(),wt=$n,H=function(i){(0,d.__extends)(t,i);function t(e,n,c){var l=i.call(this)||this;l.selForward=!0,l.text=e||"";var r=l.text._kmwLength();return l.selStart=typeof n=="number"?n:r,l.selEnd=typeof c=="number"?c:l.selStart,l.selForward=l.selEnd>=l.selStart,l}return t.from=function(e,n){var c;if(e instanceof t){var l=e;c=new t(l.text,l.selStart,l.selEnd)}else{var r=e.getText(),s=r._kmwLength(),B=s,o=0;if(e.hasSelection()){var g=e.getTextBeforeCaret(),a=e.getTextAfterCaret();B=g._kmwLength(),o=s-a._kmwLength()}c=new t(r,B,o)}return c.setDeadkeys(e.deadkeys()),c},t.prototype.clearSelection=function(){this.text=this.getTextBeforeCaret()+this.getTextAfterCaret(),this.selEnd=this.selStart,this.selForward=!0},t.prototype.invalidateSelection=function(){},t.prototype.isSelectionEmpty=function(){return this.selStart==this.selEnd},t.prototype.hasSelection=function(){return!0},t.prototype.getDeadkeyCaret=function(){return this.selStart},t.prototype.setSelection=function(e,n){if(this.selStart=e,this.selEnd=typeof n=="number"?n:e,this.selForward=n>=e,!this.selForward){var c=this.selStart;this.selStart=this.selEnd,this.selEnd=c}},t.prototype.getTextBeforeCaret=function(){return this.text.kmwSubstr(0,this.selStart)},t.prototype.getSelectedText=function(){return this.text.kmwSubstr(this.selStart,this.selEnd-this.selStart)},t.prototype.getTextAfterCaret=function(){return this.text.kmwSubstr(this.selEnd)},t.prototype.getText=function(){return this.text},t.prototype.deleteCharsBeforeCaret=function(e){e>=0&&(e>this.selStart&&(e=this.selStart),this.adjustDeadkeys(-e),this.text=this.text.kmwSubstr(0,this.selStart-e)+this.text.kmwSubstr(this.selStart),this.selStart-=e,this.selEnd-=e)},t.prototype.insertTextBeforeCaret=function(e){this.adjustDeadkeys(e._kmwLength()),this.text=this.getTextBeforeCaret()+e+this.text.kmwSubstr(this.selStart),this.selStart+=e.kmwLength(),this.selEnd+=e.kmwLength()},t.prototype.handleNewlineAtCaret=function(){this.insertTextBeforeCaret("\n")},t.prototype.setTextAfterCaret=function(e){this.text=this.getTextBeforeCaret()+e},t.prototype.doInputEvent=function(){},t}($n);var ki=function(){function i(){this.transcription=null,this.setStore={},this.saveStore={},this.variableStores={},this.triggersDefaultCommand=!1}return i.prototype.finalize=function(t,e,n){if(!this.transcription)throw"Cannot finalize a RuleBehavior with no transcription.";t.beepHandler&&this.beep&&t.beepHandler(e);for(var c in this.setStore){var l=t.keyboardInterface.systemStores[c];if(l)try{l.set(this.setStore[c])}catch(s){t.errorLogger&&t.errorLogger("Rule attempted to perform illegal operation - 'platform' may not be changed.")}else t.warningLogger&&t.warningLogger("Unknown store affected by keyboard rule: "+c)}if(t.keyboardInterface.applyVariableStores(this.variableStores),t.keyboardInterface.variableStoreSerializer)for(var c in this.saveStore)t.keyboardInterface.variableStoreSerializer.saveStore(t.activeKeyboard.id,c,this.saveStore[c]);if(this.triggersDefaultCommand){var r=this.transcription.keystroke;t.defaultRules.applyCommand(r,e)}t.warningLogger&&this.warningLog?t.warningLogger(this.warningLog):t.errorLogger&&this.errorLog&&t.errorLogger(this.errorLog)},i.prototype.mergeInDefaults=function(t){var e=this.transcription.keystroke,n=t.transcription.keystroke;if(e.Lcode!=n.Lcode||e.Lmodifiers!=n.Lmodifiers)throw"RuleBehavior default-merge not supported unless keystrokes are identical!";this.triggersDefaultCommand=this.triggersDefaultCommand||t.triggersDefaultCommand;var c=H.from(this.transcription.preInput,!1);c.apply(this.transcription.transform),c.apply(t.transcription.transform),this.transcription=c.buildTranscriptionFrom(this.transcription.preInput,e,!1,this.transcription.alternates)},i}(),le=ki;var Yi=function(){function i(){}return i}();var Xs=function(){function i(){}return i}(),ps=function(){function i(){}return i}(),ms=function(){function i(){}return i}(),Zs=function(){function i(){}return i}(),Ls=function(){function i(){}return i}(),Js=function(){function i(){}return i}(),wi=function(){function i(){}return i.prototype.reset=function(){this._cache=[]},i.prototype.get=function(t,e){return typeof this._cache[t]=="undefined"||typeof this._cache[t][e]=="undefined"?null:this._cache[t][e]},i.prototype.set=function(t,e,n){typeof this._cache[t]=="undefined"&&(this._cache[t]=[]),this._cache[t][e]=n},i}(),Oi=function(){function i(){}return i.prototype.reset=function(){this._cache=[]},i.prototype.get=function(t,e){return typeof this._cache[t]=="undefined"||typeof this._cache[t][e]=="undefined"?null:this._cache[t][e]},i.prototype.set=function(t,e,n){typeof this._cache[t]=="undefined"&&(this._cache[t]=[]),this._cache[t][e]=n},i.prototype.clone=function(){var t=new i;return t._cache=this._cache,t},i}(),f;(function(i){i[i.TSS_LAYER=33]="TSS_LAYER",i[i.TSS_PLATFORM=31]="TSS_PLATFORM",i[i.TSS_NEWLAYER=42]="TSS_NEWLAYER",i[i.TSS_OLDLAYER=43]="TSS_OLDLAYER"})(f||(f={}));var ec=function(i){(0,d.__extends)(t,i);function t(e,n,c){c===void 0&&(c=null);var l=i.call(this,e,n)||this;return l.cachedContext=new wi,l.cachedContextEx=new Oi,l._AnyIndices=[],l.systemStores={},l.systemStores[f.TSS_PLATFORM]=new qn(l),l.systemStores[f.TSS_LAYER]=new Bt(f.TSS_LAYER,"default"),l.systemStores[f.TSS_NEWLAYER]=new Bt(f.TSS_NEWLAYER,""),l.systemStores[f.TSS_OLDLAYER]=new Bt(f.TSS_OLDLAYER,""),l.variableStoreSerializer=c,l}return Object.defineProperty(t.prototype,"Codes",{get:function(){return I},enumerable:!1,configurable:!0}),t.prototype.saveFocus=function(){},t.prototype.registerKeyboard=function(e){var n=new w(e);this.loadedKeyboard=n},t.prototype.context=function(e,n,c){var l=this.cachedContext.get(e,n);if(l!==null)return l;var r=this.KC_(e,n,c);return this.cachedContext.set(e,n,r),r},t.prototype.KC_=function(e,n,c){var l="";return l=c.isSelectionEmpty()?c.getTextBeforeCaret():"",l._kmwLength()0&&r[0].p>o){r.splice(0,1);continue}else if(r.length>0&&r[0].p==o)l.deadContext[e-l.valContext.length-1]=r[0],l.valContext=[r[0].d].concat(l.valContext),r.splice(0,1);else{var g=this.context(++s,1,c);l.valContext=[g].concat(l.valContext)}}this.cachedContextEx.set(e,e,l)}var a=l;a.valContext=a.valContext.slice(0,n);for(var F=0;F255&&(r=e.vkCode),e.LisVirtualKey||r>255?((n&16384)==16384||r>255)&&(l=c==r&&(n&B)==g,l=l&&this.stateMatch(e,n&o)):(n&16384)==0&&(l=r==c),l||this.activeTargetOutput.deadkeys().resetMatched(),l},t.prototype.stateMatch=function(e,n){return(n&e.Lstates)==n},t.prototype.keyInformation=function(e){var n=new Yi;return n.vk=e.LisVirtualKey,n.code=e.Lcode,n.modifiers=e.Lmodifiers,n},t.prototype.deadkeyMatch=function(e,n,c){return n.hasDeadkeyMatch(e,c)},t.prototype.beep=function(e){this.resetContextCache(),this.ruleBehavior.beep=!0},t.prototype._ExplodeStore=function(e){if(typeof e=="string"){var n=this.activeKeyboard.explodedStores;if(n[e])return n[e];for(var c=[],l=0;l=0},t.prototype._Index=function(e,n){return e=this._ExplodeStore(e),this._AnyIndices[n-1]0){c=this._BuildExtendedContext(e,e,n);for(var l=0,r=0;rB&&(e=B)}n.deadkeys().resetMatched(),this.output(e,n,"")},t.prototype.output=function(e,n,c){this.resetContextCache(),n.saveProperties(),n.clearSelection(),n.deadkeys().deleteMatched(),e>=0&&n.deleteCharsBeforeCaret(e),n.insertTextBeforeCaret(c),n.restoreProperties()},t.prototype.contextExOutput=function(e,n,c,l){this.resetContextCache(),e>=0&&this.output(e,n,"");var r=this.ruleContextEx.get(c,c),s=r.deadContext[l-1],B=r.valContext[l-1];if(s)n.insertDeadkeyBeforeCaret(s.d);else if(typeof B=="string")this.output(-1,n,B);else throw new Error("contextExOutput: should never be a numeric valContext with no corresponding deadContext")},t.prototype.deadkeyOutput=function(e,n,c){this.resetContextCache(),e>=0&&this.output(e,n,""),n.insertDeadkeyBeforeCaret(c)},t.prototype.ifStore=function(e,n,c){var l=!0,r=this.systemStores[e];return r&&(l=r.matches(n)),l},t.prototype.setStore=function(e,n,c){if(this.resetContextCache(),e==f.TSS_LAYER&&this.activeDevice.touchable)this.ruleBehavior.setStore[e]=n;else return!1},t.prototype.loadStore=function(e,n,c){if(this.resetContextCache(),this.variableStoreSerializer){var l=this.variableStoreSerializer.loadStore(e,n);return l[n]||c}else return c},t.prototype.saveStore=function(e,n){this.resetContextCache();var c=this.activeKeyboard;if(!c||typeof c.id=="undefined"||c.id=="")return!1;var l={};return l[e]=n,this.ruleBehavior?this.ruleBehavior.saveStore[e]=l:this.variableStoreSerializer.saveStore(this.activeKeyboard.id,e,l),!0},t.prototype.resetContextCache=function(){this.cachedContext.reset(),this.cachedContextEx.reset()},t.prototype.defaultBackspace=function(e){e.isSelectionEmpty()?this.output(1,e,""):this.output(0,e,"")},t.prototype.processNewContextEvent=function(e,n){if(!this.activeKeyboard)throw"No active keyboard for keystroke processing!";return this.process(this.activeKeyboard.processNewContextEvent.bind(this.activeKeyboard),e,n,!0)},t.prototype.processPostKeystroke=function(e,n){if(!this.activeKeyboard)throw"No active keyboard for keystroke processing!";return this.process(this.activeKeyboard.processPostKeystroke.bind(this.activeKeyboard),e,n,!0)},t.prototype.processKeystroke=function(e,n){if(!this.activeKeyboard)throw"No active keyboard for keystroke processing!";return this.process(this.activeKeyboard.process.bind(this.activeKeyboard),e,n,!1)},t.prototype.process=function(e,n,c,l){if(n)if(this.activeKeyboard){if(!e)throw"No callee for keystroke processing!"}else throw"No active keyboard for keystroke processing!";else throw"No target specified for keyboard output!";n.invalidateSelection(),n.deadkeys().resetMatched(),this.resetContextCache();var r=H.from(n,!0),s=this.activeKeyboard.variableStores;this.ruleBehavior=new le,this.activeDevice=c.device,this.activeTargetOutput=n;var B=e(n,c);this.activeTargetOutput=null,this.ruleBehavior.transcription=n.buildTranscriptionFrom(r,c,l),this.ruleBehavior.variableStores=this.activeKeyboard.variableStores,this.activeKeyboard.variableStores=s,this.ruleBehavior.triggerKeyDefault=!B;var o=this.ruleBehavior;return this.ruleBehavior=null,o},t.prototype.applyVariableStores=function(e){this.activeKeyboard.variableStores=e},t.__publishShorthandAPI=function(){var e=this.prototype,n=function(c,l){e[l]&&(e[c]=e[l])};n("KSF","saveFocus"),n("KBR","beepReset"),n("KT","insertText"),n("KR","registerKeyboard"),n("KRS","registerStub"),n("KC","context"),n("KN","nul"),n("KCM","contextMatch"),n("KFCM","fullContextMatch"),n("KIK","isKeypress"),n("KKM","keyMatch"),n("KSM","stateMatch"),n("KKI","keyInformation"),n("KDM","deadkeyMatch"),n("KB","beep"),n("KA","any"),n("KDC","deleteContext"),n("KO","output"),n("KDO","deadkeyOutput"),n("KCXO","contextExOutput"),n("KIO","indexOutput"),n("KIFS","ifStore"),n("KSETS","setStore"),n("KLOAD","loadStore"),n("KSAVE","saveStore")},t.GLOBAL_NAME="KeymanWeb",t}(Me),Ke=ec;(function(){ec.__publishShorthandAPI()})();var tc=J(R(),1);var Di=function(i){(0,d.__extends)(t,i);function t(e,n){var c=i.call(this)||this;return c.stateKeys={K_CAPS:!1,K_NUMLOCK:!1,K_SCROLL:!1},c.modStateFlags=0,n||(n=t.DEFAULT_OPTIONS),c.contextDevice=e,c.baseLayout=n.baseLayout||t.DEFAULT_OPTIONS.baseLayout,c.keyboardInterface=n.keyboardInterface||new Ke(Ae(),De),c.defaultRules=n.defaultOutputRules||t.DEFAULT_OPTIONS.defaultOutputRules,c}return Object.defineProperty(t.prototype,"activeKeyboard",{get:function(){return this.keyboardInterface.activeKeyboard},set:function(e){this.keyboardInterface.activeKeyboard=e,this.resetContext()},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"layerStore",{get:function(){return this.keyboardInterface.systemStores[f.TSS_LAYER]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"newLayerStore",{get:function(){return this.keyboardInterface.systemStores[f.TSS_NEWLAYER]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"oldLayerStore",{get:function(){return this.keyboardInterface.systemStores[f.TSS_OLDLAYER]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"layerId",{get:function(){return this.layerStore.value},set:function(e){this.layerStore.set(e)},enumerable:!1,configurable:!0}),t.prototype.defaultRuleBehavior=function(e,n,c){var l=H.from(n,c),r=new le,s=!1,B="",o;if(e.isSynthetic||n.isSynthetic)if(s=!0,this.defaultRules.isCommand(e))r.triggersDefaultCommand=!0;else if((o=this.defaultRules.forSpecialEmulation(e))!=null)switch(o){case xe.Backspace:this.keyboardInterface.defaultBackspace(n);break;case xe.Enter:n.handleNewlineAtCaret();break;default:r.errorLog="Unexpected 'special emulation' character (\\u"+o.kmwCharCodeAt(0).toString(16)+") went unhandled!"}else s=!1;var g=this.activeKeyboard&&this.activeKeyboard.isMnemonic;if(!s)if((B=this.defaultRules.forAny(e,g))!=null)if(o=this.defaultRules.forSpecialEmulation(e),o==xe.Backspace)this.keyboardInterface.defaultBackspace(n);else{if(o||this.defaultRules.isCommand(e))return null;this.keyboardInterface.output(0,n,B)}else return null;if(r.errorLog)return r;var a=n.buildTranscriptionFrom(l,e,c);return r.transcription=a,r},t.prototype.processNewContextEvent=function(e,n){return this.activeKeyboard?this.keyboardInterface.processNewContextEvent(n,this.activeKeyboard.constructNullKeyEvent(e,this.stateKeys)):null},t.prototype.processPostKeystroke=function(e,n){return this.activeKeyboard?this.keyboardInterface.processPostKeystroke(n,this.activeKeyboard.constructNullKeyEvent(e,this.stateKeys)):null},t.prototype.processKeystroke=function(e,n){var c;if(this.activeKeyboard&&e.Lcode!=0&&(c=this.keyboardInterface.processKeystroke(n,e)),!c||c.triggerKeyDefault){e.Lcode=e.vkCode||e.Lcode,this.keyboardInterface.activeTargetOutput=n;var l=this.defaultRuleBehavior(e,n,!1);l&&(c?c.mergeInDefaults(l):c=l,c.triggerKeyDefault=!1),this.keyboardInterface.activeTargetOutput=null}return c},t.prototype._UpdateVKShift=function(e){var n=0,c=["CAPS","NUM_LOCK","SCROLL_LOCK"],l=["K_CAPS","K_NUMLOCK","K_SCROLL"];if(!this.activeKeyboard)return!0;if(e){n=e.Lmodifiers,this.activeKeyboard.isChiral&&this.activeKeyboard.emulatesAltGr&&(this.modStateFlags&I.modifierBitmasks.ALT_GR_SIM)==I.modifierBitmasks.ALT_GR_SIM&&(n|=I.modifierBitmasks.ALT_GR_SIM,n&=~I.modifierCodes.RALT);for(var r=!1,s=0;s=0)this.OS="iOS",this.formFactor="tablet",this.dyPortrait=this.dyLandscape=0;else if(e.indexOf("iPhone")>=0)this.OS="iOS",this.formFactor="phone",this.dyPortrait=this.dyLandscape=25;else if(e.indexOf("Android")>=0){this.OS="Android",this.formFactor="phone",this.dyPortrait=75,this.dyLandscape=25;try{var n=new RegExp("(?:Android\\s+)(\\d+\\.\\d+\\.\\d+)");this.version=e.match(n)[1]}catch(u){}}else if(e.indexOf("Linux")>=0)this.OS="Linux";else if(e.indexOf("Macintosh")>=0){var c=/Intel Mac OS X (\d+(?:[_\.]\d+)+)/i,l=c.exec(e);if(!l)console.warn("KMW could not properly parse the user agent string.A suboptimal keyboard layout may result."),this.OS="MacOSX";else if(l.length>1&&l[1]){var r=l[1].replace("_","."),s=new z(r);t=z.MAC_POSSIBLE_IPAD_ALIAS.compareTo(s)<=0,this.OS="MacOSX"}}else e.indexOf("Windows NT")>=0&&(this.OS="Windows",e.indexOf("Touch")>=0&&(this.formFactor="phone"),typeof navigator.msMaxTouchPoints=="number"&&navigator.msMaxTouchPoints>0&&(this.touchable=!0))}var B=Math.min(screen.width,screen.height),o=Math.max(screen.width,screen.height),g=B/o;this.OS!="iOS"&&this.formFactor=="phone"&&(B>=600&&g>.5625||g>=.625)&&(this.formFactor="tablet");var a=navigator.platform=="Win32"||navigator.platform=="MacIntel";this.OS=="iOS"&&!("ongesturestart"in window)&&!a&&(this.OS="Android"),this.browser="web",(this.OS=="iOS"||this.OS.toLowerCase()=="macosx")&&(this.browser="safari");var F=/Firefox|Chrome|OPR|Safari|Edge/;if(F.test(navigator.userAgent)&&(navigator.userAgent.indexOf("Firefox")>=0&&"onmozorientationchange"in screen?this.browser="firefox":navigator.userAgent.indexOf("OPR")>=0?this.browser="opera":navigator.userAgent.indexOf(" Edge/")>=0?this.browser="edge":navigator.userAgent.indexOf("Chrome")>=0?this.browser="chrome":navigator.userAgent.indexOf("Safari")>=0&&(this.browser="safari")),t&&this.browser=="safari"&&window.TouchEvent){this.OS="iOS",this.formFactor="tablet",this.dyPortrait=this.dyLandscape=0;var y=screen.height/screen.width;y<1&&(y=1/y),y>1.6&&(this.formFactor="phone",this.dyPortrait=this.dyLandscape=25)}return this.colorScheme=cc.prefersDarkMode()?"dark":"light",this.detected=!0,this.coreSpec},Object.defineProperty(i.prototype,"coreSpec",{get:function(){return new x(this.browser,this.formFactor,this.OS,this.touchable)},enumerable:!1,configurable:!0}),i}();var zt=function(i){(0,d.__extends)(t,i);function t(e,n){var c=i.call(this)||this;if(c.applyCacheBusting=!1,!n){var l=new at;l.detect(),n=l.coreSpec}return c.sourcePath=e,c.hostDevice=n,c.deferForInitialization=new A,c}return t.prototype.initialize=function(e){var n=this;this._paths?this._paths.updateFromOptions(e):this._paths=new Dt(e,this.sourcePath),typeof e.setActiveOnRegister=="boolean"?this.activateFirstKeyboard=e.setActiveOnRegister:this.activateFirstKeyboard=!0,this._spacebarText=e.spacebarText,fe.spacebarTextMode=function(){return n.spacebarText}},t.prototype.finalizeInit=function(){this.deferForInitialization.resolve()},Object.defineProperty(t.prototype,"paths",{get:function(){return this._paths},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"spacebarText",{get:function(){return this._spacebarText},set:function(e){this._spacebarText!=e&&(this._spacebarText=e,this.emit("spacebartext",e))},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"softDevice",{get:function(){return this.hostDevice},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"hardDevice",{get:function(){return Ht(this.hostDevice)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"stubNamespacer",{get:function(){return this._stubNamespacer},set:function(e){this._stubNamespacer=e},enumerable:!1,configurable:!0}),t.prototype.debugReport=function(){return{hostDevice:this.hostDevice,initialized:this.deferForInitialization.hasFinalized}},t.prototype.onRuleFinalization=function(e,n){},t}(ic.default);var Kt=(0,d.__assign)({setActiveOnRegister:!0,spacebarText:ie.LANGUAGE_KEYBOARD},Mt);var lc=J(R(),1);var _t=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this)||this;return n.pendingActivations=[],n.engineConfig=e,n}return Object.defineProperty(t.prototype,"predictionContext",{get:function(){return this._predictionContext},enumerable:!1,configurable:!0}),t.prototype.configure=function(e){this._resetContext=e.resetContext,this._predictionContext=e.predictionContext,this.keyboardCache=e.keyboardCache},t.prototype.insertText=function(e,n,c){var l=this.activeTarget;return l!=null?(n!=null&&e.output(0,l,n),typeof c!="undefined"&&c!==null&&e.deadkeyOutput(0,l,c),l.invalidateSelection(),!0):!1},t.prototype.resetContext=function(){this._resetContext(this.activeTarget),this.predictionContext.resetContext()},t.prototype.findAndPopActivation=function(e){var n;for(n=0;n9?c=0:c=n-1;else if(typeof n=="string"){for(var l=n.length==2?$t:qt,r=0;r1&&n?"languages":"keyboards"),r="?jsonp=keyman.register&languageidtype=bcp47&version="+z.CURRENT.toString(),s=l+r+e,B=this.requestEngine.request(s),o=B.promise,g=B.queryId;return this.cloudResolutionPromises[g]=o,o.finally(function(){delete c.cloudResolutionPromises[g]}),o.corePromise},t.prototype._registerCore=function(e){var n=e.options,c=n.fontBaseUri;if(this.pathConfig.fonts!=""?c=this.pathConfig.fonts:this.pathConfig.updateFontPath(c),typeof e.error=="string"){var l="";if(typeof e.options.keyboardid=="string"){var r=e.options.keyboardid;l=r.substring(0,1).toUpperCase()+r.substring(1)}return new Error($i(l))}if(typeof n=="undefined"||typeof n.context=="undefined")return new Error(en);var s=[];if(n.context=="keyboard"){var B=void 0,o=e.keyboard;if(Array.isArray(o))for(B=0;B0)r.push(g);else if(g.KI||g.KL||g.KLC||g.KFont||g.KOskFont)l.push(new re(g));else{var a=g;if(typeof a.language!="undefined"&&console.warn("The 'language' property for keyboard stubs has been deprecated. Please use the 'languages' property instead."),a.languages||(a.languages=a.language),typeof a.languages=="undefined"){var F="To use keyboard '"+a.id+"', you must specify languages.";s.push(nn(a,F))}else if(Array.isArray(a.languages))for(var y=re.toStubs(a,this.pathConfig.keyboards,this.pathConfig.fonts),u=0,Q=y;u1&&(j=k[1].split(","));for(var ae=0;ae0&&j[ae]=="")){var E=dc(k[0],j[ae],k[2]);Fc(this.cache,X,E)&&X.push(E)}}n.forEach(function(Y){return e.cache.addStub(Y)});var Lt=this.cloudQueryEngine.fetchCloudStubs(X.map(function(Y){return Y.toString()}));return Lt.then(function(Y){for(var ge=0,nt=Y;ge0?t=n[0]:t=document.body}this.linkNode=t,this.doCacheBusting=e||!1}return i.prototype.linkStylesheet=function(t){this.linkedSheets.push(t),this.linkNode.appendChild(t)},i.prototype.addStyleSheetForFont=function(t,e,n){if(!!t&&typeof t.files!="undefined"){var c=t.family,l,r="",s="",B="",o="",g=[];n||(n=x.OperatingSystem.Other);var a=this.fontStyleDefinitions[n]=this.fontStyleDefinitions[n]||{};if(a[c]){var F=a[c];F.parentNode||this.linkStylesheet(F);return}for(typeof t.files=="string"?g[0]=t.files:g=t.files,l=0;l0&&(r=g[l]),g[l].toLowerCase().indexOf(".ttf")>0&&(r=g[l]),g[l].toLowerCase().indexOf(".woff")>0&&(s=g[l]),g[l].toLowerCase().indexOf(".eot")>0&&(B=g[l]),g[l].toLowerCase().indexOf(".svg")>0&&(o=g[l]);r!=""&&r.indexOf("/")<0&&(r=e+r),s!=""&&s.indexOf("/")<0&&(s=e+s),B!=""&&B.indexOf("/")<0&&(B=e+B),o!=""&&o.indexOf("/")<0&&(o=e+o);var y="@font-face {\nfont-family:"+t.family+";\nfont-style:normal;\nfont-weight:normal;\n";if(n==x.OperatingSystem.iOS)if(r!="")this.doCacheBusting&&(r=this.cacheBust(r)),y=y+"src:url('"+r+"') format('truetype');";else return null;else{var u=[];if(n==x.OperatingSystem.Android?(o!=""&&u.push("url('"+o+"') format('svg')"),s!=""&&u.push("url('"+s+"') format('woff')"),r!=""&&u.push("url('"+r+"') format('truetype')")):(s!=""&&u.push("url('"+s+"') format('woff')"),r!=""&&u.push("url('"+r+"') format('truetype')"),o!=""&&u.push("url('"+o+"') format('svg')")),u.length==0)return null;y+="src:"+u.join(",")+";"}y=y+"\n}\n";var Q=Ve(y);return a[c]=Q,this.linkStylesheet(Q),Q}},i.prototype.cacheBust=function(t){return t+"?v="+new Date().getTime()},i.prototype.linkExternalSheet=function(t){try{if(document.querySelector("link[href="+JSON.stringify(t)+"]")!=null)return}catch(n){return}var e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,this.linkStylesheet(e)},i.prototype.unlink=function(t){var e=this.linkedSheets.indexOf(t);return e>-1?(this.linkedSheets.splice(e,1),t.parentNode.removeChild(t),!0):!1},i.prototype.unlinkAll=function(){for(var t=0,e=this.linkedSheets;t1){var o=B[0],g=B[1];n[o]=e(g,o)}else n[B[0]]=""}return n},i.prototype.saveCookie=function(t,e,n){var c="";for(var l in e)c+=l+"="+n(e[l],l)+";";var r=new Date(new Date().valueOf()+1e3*60*60*24*30).toUTCString(),s=" path=/; expires="+r;document.cookie="".concat(t,"=").concat(encodeURIComponent(c),"; ").concat(s)},i}(),se=il;function v(i){var t;if(!i)return 0;var e=i.offsetLeft?i.offsetLeft:0;if(t=i,t.offsetParent){for(;t.offsetParent;)t=t.offsetParent,e+=t.offsetLeft;var n=t.ownerDocument;t.style.position=="fixed"&&n&&n.scrollingElement&&(e+=n.scrollingElement.scrollLeft)}if(t&&t.ownerDocument&&i.ownerDocument!=window.document){var c=t.ownerDocument;if(c&&c.defaultView&&c.defaultView.frameElement)return e+v(c.defaultView.frameElement)-c.documentElement.scrollLeft}return e}function Z(i){var t;if(!i)return 0;var e=i.offsetTop?i.offsetTop:0;if(t=i,t.ownerDocument&&t instanceof t.ownerDocument.defaultView.HTMLElement){for(;t.offsetParent;)t=t.offsetParent,e+=t.offsetTop;var n=t.ownerDocument;t.style.position=="fixed"&&n&&n.scrollingElement&&(e+=n.scrollingElement.scrollTop)}if(t&&t.ownerDocument&&i.ownerDocument!=window.document){var c=t.ownerDocument;if(c&&c.defaultView&&c.defaultView.frameElement)return e+Z(c.defaultView.frameElement)}return e}var uc=function(i){(0,d.__extends)(t,i);function t(e,n){return i.call(this,"KeymanWeb_".concat(e,"_Option_").concat(n))||this}return t.prototype.load=function(){return i.prototype.load.call(this,decodeURIComponent)},t.prototype.save=function(e){i.prototype.save.call(this,e,encodeURIComponent)},t}(se),rn=function(){function i(){}return i.prototype.loadStore=function(t,e){var n=new uc(t,e);return n.load()},i.prototype.saveStore=function(t,e,n){var c=new uc(t,e);c.save(n)},i}();var Ic=function(i){(0,d.__extends)(t,i);function t(e,n,c){var l=i.call(this,e,n,new rn)||this;return l.insertText=function(r,s){l.resetContextCache(),l.engine.contextManager.insertText(l,r,s)},l.KT=l.insertText,l.engine=n,l.stubNamespacer=c,l}return t.prototype.preserveID=function(e){var n;if(document.currentScript)n=document.currentScript.id;else{var c=document.getElementsByTagName("script"),l=c[c.length-1];n=l.id}if(n)n.indexOf(ye(e.KI))!=-1?e.KI=n:console.error("Error when registering keyboard: current SCRIPT tag's ID does not match!");else return},t.prototype.registerKeyboard=function(e){var n=this;i.prototype.registerKeyboard.call(this,e);var c=this.loadedKeyboard;this.preserveID(e),this.engine.config.deferForInitialization.then(function(){n.engine.keyboardRequisitioner.cache.isFetchingKeyboard(c.id)||(n.engine.keyboardRequisitioner.cache.addKeyboard(c),n.loadedKeyboard=null)})},t.prototype.registerStub=function(e){var n=this,c;this.stubNamespacer&&this.stubNamespacer(e);var l=this.engine.config.paths,r=new re(e,l.keyboards,l.fonts);return!((c=this.engine.keyboardRequisitioner)===null||c===void 0)&&c.cache.findMatchingStub(r)?1:(this.engine.config.deferForInitialization.hasFinalized?this.engine.keyboardRequisitioner.cache.addStub(r):this.engine.config.deferForInitialization.then(function(){return n.engine.keyboardRequisitioner.cache.addStub(r)}),null)},t}(Ke),sn=Ic;(function(){Ic.__publishShorthandAPI()})();var Qc=function(i){(0,d.__extends)(t,i);function t(e,n){var c=this;return e&&e._jsGlobal!=window&&(e._jsGlobal.String=window.String),e?c=i.call(this,e)||this:c=i.call(this,new Me(window,De))||this,c.performCacheBusting=n||!1,c}return t.prototype.loadKeyboardInternal=function(e,n,c){var l=this,r=new A;this.performCacheBusting&&(e=this.cacheBust(e));try{var s=this.harness._jsGlobal.document,B=s.createElement("script");c&&(B.id=c),s.head.appendChild(B),B.onerror=function(o){r.reject(n.missingError(o))},B.onload=function(){if(l.harness.loadedKeyboard){var o=l.harness.loadedKeyboard;l.harness.loadedKeyboard=null,r.resolve(o)}else r.reject(n.scriptError())},r.then(function(){B.remove()}).catch(function(){B.remove()}),B.src=e}catch(o){return Promise.reject(o)}return r.corePromise},t.prototype.cacheBust=function(e){return e+"?v="+new Date().getTime()},t}(Tt);var ll=function(){function i(t,e,n){this.left=t.getTextBeforeCaret(),this.startOfBuffer=this.left._kmwLength()<=e.leftContextCodePoints,this.startOfBuffer||(this.left=this.left._kmwSubstr(-e.leftContextCodePoints)),this.right=t.getTextAfterCaret(),this.endOfBuffer=this.right._kmwLength()<=e.rightContextCodePoints,this.endOfBuffer||(this.right=this.right._kmwSubstr(0,e.rightContextCodePoints)),this.casingForm=n=="shift"?"initial":n=="caps"?"upper":null}return i.prototype.toMock=function(){var t=this.left._kmwLength();return new H(this.left+(this.right||""),t)},i.ENGINE_RULE_WINDOW={leftContextCodePoints:64,rightContextCodePoints:32},i}(),ue=ll;var Uc=J(R(),1);var rl=function(){function i(){this._promises=new Map}return Object.defineProperty(i.prototype,"length",{get:function(){return this._promises.size},enumerable:!1,configurable:!0}),i.prototype.make=function(t,e,n){if(this._promises.has(t))return n("Existing request with token ".concat(t));this._promises.set(t,{reject:n,resolve:e})},i.prototype.keep=function(t,e){var n=this._promises.get(t);if(!n)throw new Error("No promise associated with token: ".concat(t));var c=n.resolve;return this._promises.delete(t),c(e)},i.prototype.break=function(t,e){var n=this._promises.get(t);if(!n)throw new Error("No promise associated with token: ".concat(t));this._promises.delete(t),n.reject(e)},i}(),Pe=rl;var sl=function(){function i(t,e,n){this._worker=e,this._worker.onmessage=this.onMessage.bind(this),this._declareLMLayerReady=null,this._predictPromises=new Pe,this._wordbreakPromises=new Pe,this._acceptPromises=new Pe,this._revertPromises=new Pe,this._nextToken=Number.MIN_SAFE_INTEGER,this.sendConfig(t,!!n)}return i.prototype.sendConfig=function(t,e){this._worker.postMessage({message:"config",capabilities:t,testMode:e})},i.prototype.loadModel=function(t,e){var n=this;return e===void 0&&(e="file"),new Promise(function(c,l){n._declareLMLayerReady=c;var r={type:e};e=="file"?r.file=t:r.code=t,n._worker.postMessage({message:"load",source:r})})},i.prototype.unloadModel=function(){this._worker.postMessage({message:"unload"})},i.prototype.predict=function(t,e){var n=this,c=this._nextToken++;return new Promise(function(l,r){n._predictPromises.make(c,l,r),n._worker.postMessage({message:"predict",token:c,transform:t,context:e})})},i.prototype.wordbreak=function(t){var e=this,n=this._nextToken++;return new Promise(function(c,l){e._wordbreakPromises.make(n,c,l),e._worker.postMessage({message:"wordbreak",token:n,context:t})})},i.prototype.acceptSuggestion=function(t,e,n){var c=this,l=this._nextToken++;return new Promise(function(r,s){c._acceptPromises.make(l,r,s),c._worker.postMessage({message:"accept",token:l,suggestion:t,context:e,postTransform:n})})},i.prototype.revertSuggestion=function(t,e){var n=this,c=this._nextToken++;return new Promise(function(l,r){n._revertPromises.make(c,l,r),n._worker.postMessage({message:"revert",token:c,reversion:t,context:e})})},i.prototype.resetContext=function(t){this._worker.postMessage({message:"reset-context",context:t})},i.prototype.onMessage=function(t){var e=t.data;if(e.message==="error")console.error(e.log),e.error&&console.error(e.error);else if(e.message==="ready")this._declareLMLayerReady(t.data.configuration);else if(e.message==="suggestions")this._predictPromises.keep(e.token,e.suggestions);else if(e.message==="currentword")this._wordbreakPromises.keep(e.token,e.word);else if(e.message==="postaccept")this._acceptPromises.keep(e.token,e.reversion);else if(e.message==="postrevert")this._revertPromises.keep(e.token,e.suggestions);else throw new Error("Message not implemented: ".concat(e.message))},i.prototype.shutdown=function(){this._worker.terminate()},i}(),Bn=sl;function Ft(i){return i}var Cc='"use strict";var ae=Object.defineProperty;var v=function(r,e){return ae(r,"name",{value:e,configurable:!0})};/*! https://mths.be/codepointat v0.2.0 by @mathias */String.prototype.codePointAt||function(){"use strict";var r=function(){try{var t={},n=Object.defineProperty,i=n(t,t,t)&&n}catch(a){}return i}(),e=v(function(t){if(this==null)throw TypeError();var n=String(this),i=n.length,a=t?Number(t):0;if(a!=a&&(a=0),!(a<0||a>=i)){var u=n.charCodeAt(a),o;return u>=55296&&u<=56319&&i>a+1&&(o=n.charCodeAt(a+1),o>=56320&&o<=57343)?(u-55296)*1024+o-56320+65536:u}},"codePointAt");r?r(String.prototype,"codePointAt",{value:e,configurable:!0,writable:!0}):String.prototype.codePointAt=e}(),Array.prototype.fill||Object.defineProperty(Array.prototype,"fill",{value:function(r){if(this==null)throw new TypeError("this is null or not defined");for(var e=Object(this),t=e.length>>>0,n=arguments[1],i=n>>0,a=i<0?Math.max(t+i,0):Math.min(i,t),u=arguments[2],o=u===void 0?t:u>>0,l=o<0?Math.max(t+o,0):Math.min(o,t);a>>0;if(typeof r!="function")throw new TypeError("predicate must be a function");for(var n=arguments[1],i=0;i0?1:-1)*Math.floor(Math.abs(u))},"toInteger"),n=Math.pow(2,53)-1,i=v(function(a){var u=t(a);return Math.min(Math.max(u,0),n)},"toLength");return v(function(u){var o=this,l=Object(u);if(u==null)throw new TypeError("Array.from requires an array-like object - not null or undefined");var s=arguments.length>1?arguments[1]:void 0,f;if(typeof s!="undefined"){if(!e(s))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(f=arguments[2])}for(var c=i(l.length),d=e(o)?Object(new o(c)):new Array(c),p=0,g;p=0&&typeof m.length=="number"&&m.length>=0){var O=Math.floor(h.length),k=Math.floor(m.length),A=0;for(h.length=O+k;A=0&&this._nextIndex=0))return(I=new k(0)).length=0,I;for(A=Math.floor(h.length),(I=new k(A)).length=A;E0&&g[g.length-1])&&(S[0]===6||S[0]===2)){c=0;continue}if(S[0]===3&&(!g||S[1]>g[0]&&S[1]=s.length&&(s=void 0),{value:s&&s[d++],done:!s}}};throw new TypeError(f?"Object is not iterable.":"Symbol.iterator is not defined.")},"__values7"),u=v(function(s,f){var c=typeof Symbol=="function"&&s[Symbol.iterator];if(!c)return s;var d=c.call(s),p,g=[],w;try{for(;(f===void 0||f-- >0)&&!(p=d.next()).done;)g.push(p.value)}catch(b){w={error:b}}finally{try{p&&!p.done&&(c=d.return)&&c.call(d)}finally{if(w)throw w.error}}return g},"__read3"),o("__extends",t),o("__assign",n),o("__generator",i),o("__values",a),o("__read",u)})}}),build_exports={};__export(build_exports,{tslib:function(){return tslib_1}}),__reExport(build_exports,__toESM(require_tslib(),1));var tslib_1=__toESM(require_tslib(),1),DeviceSpec=function(){function r(e,t,n,i){switch(e.toLowerCase()){case r.Browser.Chrome:case r.Browser.Edge:case r.Browser.Firefox:case r.Browser.Native:case r.Browser.Opera:case r.Browser.Safari:this.browser=e.toLowerCase();break;default:this.browser=r.Browser.Other}switch(t.toLowerCase()){case r.FormFactor.Desktop:case r.FormFactor.Phone:case r.FormFactor.Tablet:this.formFactor=t.toLowerCase();break;default:throw"Invalid form factor specified for device: "+t}switch(n.toLowerCase()){case r.OperatingSystem.Windows.toLowerCase():case r.OperatingSystem.macOS.toLowerCase():case r.OperatingSystem.Linux.toLowerCase():case r.OperatingSystem.Android.toLowerCase():case r.OperatingSystem.iOS.toLowerCase():this.OS=n.toLowerCase();break;default:this.OS=r.OperatingSystem.Other}this.touchable=i}return v(r,"DeviceSpec2"),r}();(function(r){var e;(function(i){i.Chrome="chrome",i.Edge="edge",i.Firefox="firefox",i.Native="native",i.Opera="opera",i.Safari="safari",i.Other="other"})(e=r.Browser||(r.Browser={}));var t;(function(i){i.Windows="windows",i.macOS="macosx",i.Linux="linux",i.Android="android",i.iOS="ios",i.Other="other"})(t=r.OperatingSystem||(r.OperatingSystem={}));var n;(function(i){i.Desktop="desktop",i.Phone="phone",i.Tablet="tablet"})(n=r.FormFactor||(r.FormFactor={}))})(DeviceSpec||(DeviceSpec={}));function extendString(){String.kmwFromCharCode=function(r){var e=[],t;for(t=0;t1114111||Math.floor(n)!==n)throw new RangeError("Invalid code point "+n);n<65536?e.push(n):(n-=65536,e.push((n>>10)+55296),e.push(n%1024+56320))}return String.fromCharCode.apply(void 0,e)},String.prototype.kmwCharCodeAt=function(r){var e=String(this),t=0;if(r<0||r>=e.length)return NaN;for(var n=0;n=55296&&i<=56319&&e.length>t+1){var a=e.charCodeAt(t+1);if(a>=56320&&a<=57343)return(i-55296<<10)+(a-56320)+65536}return i},String.prototype.kmwIndexOf=function(r,e){var t=String(this),n=t.indexOf(r,e);if(n<0)return n;for(var i=0,a=0;a!==null&&ae){var a=r;r=e,e=a}n=t.kmwCodePointToCodeUnit(r),i=t.kmwCodePointToCodeUnit(e)}return(isNaN(n)||n===null)&&(n=0),(isNaN(i)||i===null)&&(i=t.length),t.substring(n,i)},String.prototype.kmwNextChar=function(r){var e=String(this);if(r===null||r<0||r>=e.length-1)return null;var t=e.charCodeAt(r);if(t>=55296&&t<=56319&&e.length>r+1){var n=e.charCodeAt(r+1);if(n>=56320&&n<=57343)return r==e.length-2?null:r+2}return r+1},String.prototype.kmwPrevChar=function(r){var e=String(this);if(r==null||r<=0||r>e.length)return null;var t=e.charCodeAt(r-1);if(t>=56320&&t<=57343&&r>1){var n=e.charCodeAt(r-2);if(n>=55296&&n<=56319)return r-2}return r-1},String.prototype.kmwCodePointToCodeUnit=function(r){if(r===null)return null;var e=String(this),t=0;if(r<0){t=e.length;for(var n=0;n>r;n--)t=e.kmwPrevChar(t);return t}if(r==e.kmwLength())return e.length;for(var n=0;n=0?e.kmwSubstr(r,1):""},String.prototype.kmwBMPNextChar=function(r){var e=String(this);return r<0||r>=e.length-1?null:r+1},String.prototype.kmwBMPPrevChar=function(r){var e=String(this);return r<=0||r>e.length?null:r-1},String.prototype.kmwBMPCodePointToCodeUnit=function(r){return r},String.prototype.kmwBMPCodeUnitToCodePoint=function(r){return r},String.prototype.kmwBMPLength=function(){var r=String(this);return r.length},String.prototype.kmwBMPSubstr=function(r,e){var t=String(this);return r>-1?t.substr(r,e):t.substr(t.length+r,-r)},String.kmwEnableSupplementaryPlane=function(r){var e=String.prototype;String._kmwFromCharCode=r?String.kmwFromCharCode:String.fromCharCode,e._kmwCharAt=r?e.kmwCharAt:e.charAt,e._kmwCharCodeAt=r?e.kmwCharCodeAt:e.charCodeAt,e._kmwIndexOf=r?e.kmwIndexOf:e.indexOf,e._kmwLastIndexOf=r?e.kmwLastIndexOf:e.lastIndexOf,e._kmwSlice=r?e.kmwSlice:e.slice,e._kmwSubstring=r?e.kmwSubstring:e.substring,e._kmwSubstr=r?e.kmwSubstr:e.kmwBMPSubstr,e._kmwLength=r?e.kmwLength:e.kmwBMPLength,e._kmwNextChar=r?e.kmwNextChar:e.kmwBMPNextChar,e._kmwPrevChar=r?e.kmwPrevChar:e.kmwBMPPrevChar,e._kmwCodePointToCodeUnit=r?e.kmwCodePointToCodeUnit:e.kmwBMPCodePointToCodeUnit,e._kmwCodeUnitToCodePoint=r?e.kmwCodeUnitToCodePoint:e.kmwBMPCodeUnitToCodePoint},String._kmwFromCharCode||String.kmwEnableSupplementaryPlane(!1)}v(extendString,"extendString"),extendString();var models_exports={};__export(models_exports,{DummyModel:function(){return dummy_model_default},PriorityQueue:function(){return priority_queue_default},QuoteBehavior:function(){return quote_behavior_default},SENTINEL_CODE_UNIT:function(){return SENTINEL_CODE_UNIT},TrieModel:function(){return trie_model_default},applyTransform:function(){return applyTransform},buildMergedTransform:function(){return buildMergedTransform},defaultApplyCasing:function(){return defaultApplyCasing},getLastPreCaretToken:function(){return getLastPreCaretToken},isHighSurrogate:function(){return isHighSurrogate},isLowSurrogate:function(){return isLowSurrogate},isSentinel:function(){return isSentinel},tokenize:function(){return tokenize},transformToSuggestion:function(){return transformToSuggestion},wordbreak:function(){return wordbreak}}),extendString();var SENTINEL_CODE_UNIT="\\uFDD0";function applyTransform(r,e){var t,n,i=e.left||"",a=i.kmwLength(),u=a=55296&&r<=56319}v(isHighSurrogate,"isHighSurrogate");function isLowSurrogate(r){return typeof r=="string"&&(r=r.charCodeAt(0)),r>=56320&&r<=57343}v(isLowSurrogate,"isLowSurrogate");function isSentinel(r){return r==SENTINEL_CODE_UNIT}v(isSentinel,"isSentinel");function transformToSuggestion(r,e){var t={transform:r,transformId:r.id,displayAs:r.insert};return(e===0||e)&&(t.p=e),t}v(transformToSuggestion,"transformToSuggestion");function defaultApplyCasing(r,e){switch(r){case"lower":return e.toLowerCase();case"upper":return e.toUpperCase();case"initial":var t=1;return e.length>1&&isHighSurrogate(e.charAt(0))&&isLowSurrogate(e.charCodeAt(1))&&(t=2),e.substring(0,t).toUpperCase().concat(e.substring(t))}}v(defaultApplyCasing,"defaultApplyCasing");var PriorityQueue=function(){function r(e,t){t===void 0&&(t=[]),this.comparator=e,this.heap=Array.from(t),this.heapify()}return v(r,"PriorityQueue2"),r.leftChildIndex=function(e){return e*2+1},r.rightChildIndex=function(e){return e*2+2},r.parentIndex=function(e){return Math.floor((e-1)/2)},r.prototype.heapify=function(e,t){if(e==null||t==null){this.heapify(0,this.count-1);return}for(var n=[],i=-1,a=t;a>=e;a--){var u=r.parentIndex(a);this.siftDown(a)&&u0;){var o=n.shift(),u=r.parentIndex(o);this.siftDown(o)&&u>=0&&i!=u&&(n.push(u),i=u)}},Object.defineProperty(r.prototype,"count",{get:function(){return this.heap.length},enumerable:!1,configurable:!0}),r.prototype.peek=function(){return this.heap[0]},r.prototype.enqueue=function(e){var t=this.heap.length;this.heap.push(e);for(var n=r.parentIndex,i=n(t);t!==0&&this.comparator(this.heap[t],this.heap[i])<0;){var a=this.heap[t];this.heap[t]=this.heap[i],this.heap[i]=a,t=i,i=n(t)}},r.prototype.enqueueAll=function(e){if(e.length!=0){var t=this.count;this.heap=this.heap.concat(e);var n=r.parentIndex(t);this.heapify(n>=0?n:0,r.parentIndex(this.count-1))}},r.prototype.dequeue=function(){if(this.count!=0){var e=this.heap[0],t=this.heap.pop();return this.heap.length>0&&(this.heap[0]=t,this.siftDown(0)),e}},r.prototype.siftDown=function(e){var t=r.leftChildIndex(e),n=r.rightChildIndex(e),i=e;if(t0&&(i=t[t.length-1]),t.length>1){var a=t[t.length-2];if(a.end==i.start&&i.text=="\'"){var u={text:a.text+i.text,start:a.start,end:i.end,length:a.length+i.length};t.pop(),t.pop(),t.push(u),i=u}}var o={left:t.map(function(c){return c.text}),right:n.map(function(c){return c.text}),caretSplitsToken:!1};if(t.length>0&&n.length>0){var l=n[0],s=i.end!=e.left.length,f=l.start!=0;if(s||f)return o;r(i.text+l.text).length==1&&(o.caretSplitsToken=!0)}return o}v(tokenize,"tokenize");function getLastPreCaretToken(r,e){var t=tokenize(r,e);return t.left.length>0?t.left.pop():""}v(getLastPreCaretToken,"getLastPreCaretToken");function wordbreak(r,e){return getLastPreCaretToken(r,e)}v(wordbreak,"wordbreak");var obj_exports={};__export(obj_exports,{ascii:function(){return ascii},default:function(){return default_},defaultWordbreaker:function(){return default_},placeholder:function(){return placeholder}});function placeholder(r){var e=0;return r.split(/\\s+/).map(function(t){var n={start:e,end:e+t.length,text:t,length:t.length};return e=n.end,n})}v(placeholder,"placeholder");function ascii(r){for(var e=/[A-Za-z0-9\']+/g,t=[],n;(n=e.exec(r))!==null;)t.push(new RegExpDerivedSpan(n[0],n.index));return t}v(ascii,"ascii");var RegExpDerivedSpan=function(){function r(e,t){this.text=e,this.start=t}return v(r,"RegExpDerivedSpan2"),Object.defineProperty(r.prototype,"length",{get:function(){return this.text.length},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"end",{get:function(){return this.start+this.text.length},enumerable:!1,configurable:!0}),r}(),propertyMap=["Other","LF","Newline","CR","WSegSpace","Double_Quote","Single_Quote","MidNum","MidNumLet","Numeric","MidLetter","ALetter","ExtendNumLet","Format","Extend","Hebrew_Letter","ZWJ","Katakana","Regional_Indicator","sot","eot"],WORD_BREAK_PROPERTY=[[0,0],[10,1],[11,2],[13,3],[14,0],[32,4],[33,0],[34,5],[35,0],[39,6],[40,0],[44,7],[45,0],[46,8],[47,0],[48,9],[58,10],[59,7],[60,0],[65,11],[91,0],[95,12],[96,0],[97,11],[123,0],[133,2],[134,0],[170,11],[171,0],[173,13],[174,0],[181,11],[182,0],[183,10],[184,0],[186,11],[187,0],[192,11],[215,0],[216,11],[247,0],[248,11],[728,0],[734,11],[768,14],[880,11],[885,0],[886,11],[888,0],[890,11],[894,7],[895,11],[896,0],[902,11],[903,10],[904,11],[907,0],[908,11],[909,0],[910,11],[930,0],[931,11],[1014,0],[1015,11],[1154,0],[1155,14],[1162,11],[1328,0],[1329,11],[1367,0],[1369,11],[1373,0],[1374,11],[1375,10],[1376,11],[1417,7],[1418,11],[1419,0],[1425,14],[1470,0],[1471,14],[1472,0],[1473,14],[1475,0],[1476,14],[1478,0],[1479,14],[1480,0],[1488,15],[1515,0],[1519,15],[1523,11],[1524,10],[1525,0],[1536,13],[1542,0],[1548,7],[1550,0],[1552,14],[1563,0],[1564,13],[1565,0],[1568,11],[1611,14],[1632,9],[1642,0],[1643,9],[1644,7],[1645,0],[1646,11],[1648,14],[1649,11],[1748,0],[1749,11],[1750,14],[1757,13],[1758,0],[1759,14],[1765,11],[1767,14],[1769,0],[1770,14],[1774,11],[1776,9],[1786,11],[1789,0],[1791,11],[1792,0],[1807,13],[1808,11],[1809,14],[1810,11],[1840,14],[1867,0],[1869,11],[1958,14],[1969,11],[1970,0],[1984,9],[1994,11],[2027,14],[2036,11],[2038,0],[2040,7],[2041,0],[2042,11],[2043,0],[2045,14],[2046,0],[2048,11],[2070,14],[2074,11],[2075,14],[2084,11],[2085,14],[2088,11],[2089,14],[2094,0],[2112,11],[2137,14],[2140,0],[2144,11],[2155,0],[2208,11],[2229,0],[2230,11],[2248,0],[2259,14],[2274,13],[2275,14],[2308,11],[2362,14],[2365,11],[2366,14],[2384,11],[2385,14],[2392,11],[2402,14],[2404,0],[2406,9],[2416,0],[2417,11],[2433,14],[2436,0],[2437,11],[2445,0],[2447,11],[2449,0],[2451,11],[2473,0],[2474,11],[2481,0],[2482,11],[2483,0],[2486,11],[2490,0],[2492,14],[2493,11],[2494,14],[2501,0],[2503,14],[2505,0],[2507,14],[2510,11],[2511,0],[2519,14],[2520,0],[2524,11],[2526,0],[2527,11],[2530,14],[2532,0],[2534,9],[2544,11],[2546,0],[2556,11],[2557,0],[2558,14],[2559,0],[2561,14],[2564,0],[2565,11],[2571,0],[2575,11],[2577,0],[2579,11],[2601,0],[2602,11],[2609,0],[2610,11],[2612,0],[2613,11],[2615,0],[2616,11],[2618,0],[2620,14],[2621,0],[2622,14],[2627,0],[2631,14],[2633,0],[2635,14],[2638,0],[2641,14],[2642,0],[2649,11],[2653,0],[2654,11],[2655,0],[2662,9],[2672,14],[2674,11],[2677,14],[2678,0],[2689,14],[2692,0],[2693,11],[2702,0],[2703,11],[2706,0],[2707,11],[2729,0],[2730,11],[2737,0],[2738,11],[2740,0],[2741,11],[2746,0],[2748,14],[2749,11],[2750,14],[2758,0],[2759,14],[2762,0],[2763,14],[2766,0],[2768,11],[2769,0],[2784,11],[2786,14],[2788,0],[2790,9],[2800,0],[2809,11],[2810,14],[2816,0],[2817,14],[2820,0],[2821,11],[2829,0],[2831,11],[2833,0],[2835,11],[2857,0],[2858,11],[2865,0],[2866,11],[2868,0],[2869,11],[2874,0],[2876,14],[2877,11],[2878,14],[2885,0],[2887,14],[2889,0],[2891,14],[2894,0],[2901,14],[2904,0],[2908,11],[2910,0],[2911,11],[2914,14],[2916,0],[2918,9],[2928,0],[2929,11],[2930,0],[2946,14],[2947,11],[2948,0],[2949,11],[2955,0],[2958,11],[2961,0],[2962,11],[2966,0],[2969,11],[2971,0],[2972,11],[2973,0],[2974,11],[2976,0],[2979,11],[2981,0],[2984,11],[2987,0],[2990,11],[3002,0],[3006,14],[3011,0],[3014,14],[3017,0],[3018,14],[3022,0],[3024,11],[3025,0],[3031,14],[3032,0],[3046,9],[3056,0],[3072,14],[3077,11],[3085,0],[3086,11],[3089,0],[3090,11],[3113,0],[3114,11],[3130,0],[3133,11],[3134,14],[3141,0],[3142,14],[3145,0],[3146,14],[3150,0],[3157,14],[3159,0],[3160,11],[3163,0],[3168,11],[3170,14],[3172,0],[3174,9],[3184,0],[3200,11],[3201,14],[3204,0],[3205,11],[3213,0],[3214,11],[3217,0],[3218,11],[3241,0],[3242,11],[3252,0],[3253,11],[3258,0],[3260,14],[3261,11],[3262,14],[3269,0],[3270,14],[3273,0],[3274,14],[3278,0],[3285,14],[3287,0],[3294,11],[3295,0],[3296,11],[3298,14],[3300,0],[3302,9],[3312,0],[3313,11],[3315,0],[3328,14],[3332,11],[3341,0],[3342,11],[3345,0],[3346,11],[3387,14],[3389,11],[3390,14],[3397,0],[3398,14],[3401,0],[3402,14],[3406,11],[3407,0],[3412,11],[3415,14],[3416,0],[3423,11],[3426,14],[3428,0],[3430,9],[3440,0],[3450,11],[3456,0],[3457,14],[3460,0],[3461,11],[3479,0],[3482,11],[3506,0],[3507,11],[3516,0],[3517,11],[3518,0],[3520,11],[3527,0],[3530,14],[3531,0],[3535,14],[3541,0],[3542,14],[3543,0],[3544,14],[3552,0],[3558,9],[3568,0],[3570,14],[3572,0],[3633,14],[3634,0],[3636,14],[3643,0],[3655,14],[3663,0],[3664,9],[3674,0],[3761,14],[3762,0],[3764,14],[3773,0],[3784,14],[3790,0],[3792,9],[3802,0],[3840,11],[3841,0],[3864,14],[3866,0],[3872,9],[3882,0],[3893,14],[3894,0],[3895,14],[3896,0],[3897,14],[3898,0],[3902,14],[3904,11],[3912,0],[3913,11],[3949,0],[3953,14],[3973,0],[3974,14],[3976,11],[3981,14],[3992,0],[3993,14],[4029,0],[4038,14],[4039,0],[4139,14],[4159,0],[4160,9],[4170,0],[4182,14],[4186,0],[4190,14],[4193,0],[4194,14],[4197,0],[4199,14],[4206,0],[4209,14],[4213,0],[4226,14],[4238,0],[4239,14],[4240,9],[4250,14],[4254,0],[4256,11],[4294,0],[4295,11],[4296,0],[4301,11],[4302,0],[4304,11],[4347,0],[4348,11],[4681,0],[4682,11],[4686,0],[4688,11],[4695,0],[4696,11],[4697,0],[4698,11],[4702,0],[4704,11],[4745,0],[4746,11],[4750,0],[4752,11],[4785,0],[4786,11],[4790,0],[4792,11],[4799,0],[4800,11],[4801,0],[4802,11],[4806,0],[4808,11],[4823,0],[4824,11],[4881,0],[4882,11],[4886,0],[4888,11],[4955,0],[4957,14],[4960,0],[4992,11],[5008,0],[5024,11],[5110,0],[5112,11],[5118,0],[5121,11],[5741,0],[5743,11],[5760,4],[5761,11],[5787,0],[5792,11],[5867,0],[5870,11],[5881,0],[5888,11],[5901,0],[5902,11],[5906,14],[5909,0],[5920,11],[5938,14],[5941,0],[5952,11],[5970,14],[5972,0],[5984,11],[5997,0],[5998,11],[6001,0],[6002,14],[6004,0],[6068,14],[6100,0],[6109,14],[6110,0],[6112,9],[6122,0],[6155,14],[6158,13],[6159,0],[6160,9],[6170,0],[6176,11],[6265,0],[6272,11],[6277,14],[6279,11],[6313,14],[6314,11],[6315,0],[6320,11],[6390,0],[6400,11],[6431,0],[6432,14],[6444,0],[6448,14],[6460,0],[6470,9],[6480,0],[6608,9],[6618,0],[6656,11],[6679,14],[6684,0],[6741,14],[6751,0],[6752,14],[6781,0],[6783,14],[6784,9],[6794,0],[6800,9],[6810,0],[6832,14],[6849,0],[6912,14],[6917,11],[6964,14],[6981,11],[6988,0],[6992,9],[7002,0],[7019,14],[7028,0],[7040,14],[7043,11],[7073,14],[7086,11],[7088,9],[7098,11],[7142,14],[7156,0],[7168,11],[7204,14],[7224,0],[7232,9],[7242,0],[7245,11],[7248,9],[7258,11],[7294,0],[7296,11],[7305,0],[7312,11],[7355,0],[7357,11],[7360,0],[7376,14],[7379,0],[7380,14],[7401,11],[7405,14],[7406,11],[7412,14],[7413,11],[7415,14],[7418,11],[7419,0],[7424,11],[7616,14],[7674,0],[7675,14],[7680,11],[7958,0],[7960,11],[7966,0],[7968,11],[8006,0],[8008,11],[8014,0],[8016,11],[8024,0],[8025,11],[8026,0],[8027,11],[8028,0],[8029,11],[8030,0],[8031,11],[8062,0],[8064,11],[8117,0],[8118,11],[8125,0],[8126,11],[8127,0],[8130,11],[8133,0],[8134,11],[8141,0],[8144,11],[8148,0],[8150,11],[8156,0],[8160,11],[8173,0],[8178,11],[8181,0],[8182,11],[8189,0],[8192,4],[8199,0],[8200,4],[8203,0],[8204,14],[8205,16],[8206,13],[8208,0],[8216,8],[8218,0],[8228,8],[8229,0],[8231,10],[8232,2],[8234,13],[8239,12],[8240,0],[8255,12],[8257,0],[8260,7],[8261,0],[8276,12],[8277,0],[8287,4],[8288,13],[8293,0],[8294,13],[8304,0],[8305,11],[8306,0],[8319,11],[8320,0],[8336,11],[8349,0],[8400,14],[8433,0],[8450,11],[8451,0],[8455,11],[8456,0],[8458,11],[8468,0],[8469,11],[8470,0],[8473,11],[8478,0],[8484,11],[8485,0],[8486,11],[8487,0],[8488,11],[8489,0],[8490,11],[8494,0],[8495,11],[8506,0],[8508,11],[8512,0],[8517,11],[8522,0],[8526,11],[8527,0],[8544,11],[8585,0],[9398,11],[9450,0],[11264,11],[11311,0],[11312,11],[11359,0],[11360,11],[11493,0],[11499,11],[11503,14],[11506,11],[11508,0],[11520,11],[11558,0],[11559,11],[11560,0],[11565,11],[11566,0],[11568,11],[11624,0],[11631,11],[11632,0],[11647,14],[11648,11],[11671,0],[11680,11],[11687,0],[11688,11],[11695,0],[11696,11],[11703,0],[11704,11],[11711,0],[11712,11],[11719,0],[11720,11],[11727,0],[11728,11],[11735,0],[11736,11],[11743,0],[11744,14],[11776,0],[11823,11],[11824,0],[12288,4],[12289,0],[12293,11],[12294,0],[12330,14],[12336,0],[12337,17],[12342,0],[12347,11],[12349,0],[12441,14],[12443,17],[12445,0],[12448,17],[12539,0],[12540,17],[12544,0],[12549,11],[12592,0],[12593,11],[12687,0],[12704,11],[12736,0],[12784,17],[12800,0],[13008,17],[13055,0],[13056,17],[13144,0],[40960,11],[42125,0],[42192,11],[42238,0],[42240,11],[42509,0],[42512,11],[42528,9],[42538,11],[42540,0],[42560,11],[42607,14],[42611,0],[42612,14],[42622,0],[42623,11],[42654,14],[42656,11],[42736,14],[42738,0],[42760,11],[42944,0],[42946,11],[42955,0],[42997,11],[43010,14],[43011,11],[43014,14],[43015,11],[43019,14],[43020,11],[43043,14],[43048,0],[43052,14],[43053,0],[43072,11],[43124,0],[43136,14],[43138,11],[43188,14],[43206,0],[43216,9],[43226,0],[43232,14],[43250,11],[43256,0],[43259,11],[43260,0],[43261,11],[43263,14],[43264,9],[43274,11],[43302,14],[43310,0],[43312,11],[43335,14],[43348,0],[43360,11],[43389,0],[43392,14],[43396,11],[43443,14],[43457,0],[43471,11],[43472,9],[43482,0],[43493,14],[43494,0],[43504,9],[43514,0],[43520,11],[43561,14],[43575,0],[43584,11],[43587,14],[43588,11],[43596,14],[43598,0],[43600,9],[43610,0],[43643,14],[43646,0],[43696,14],[43697,0],[43698,14],[43701,0],[43703,14],[43705,0],[43710,14],[43712,0],[43713,14],[43714,0],[43744,11],[43755,14],[43760,0],[43762,11],[43765,14],[43767,0],[43777,11],[43783,0],[43785,11],[43791,0],[43793,11],[43799,0],[43808,11],[43815,0],[43816,11],[43823,0],[43824,11],[43882,0],[43888,11],[44003,14],[44011,0],[44012,14],[44014,0],[44016,9],[44026,0],[44032,11],[55204,0],[55216,11],[55239,0],[55243,11],[55292,0],[64256,11],[64263,0],[64275,11],[64280,0],[64285,15],[64286,14],[64287,15],[64297,0],[64298,15],[64311,0],[64312,15],[64317,0],[64318,15],[64319,0],[64320,15],[64322,0],[64323,15],[64325,0],[64326,15],[64336,11],[64434,0],[64467,11],[64830,0],[64848,11],[64912,0],[64914,11],[64968,0],[65008,11],[65020,0],[65024,14],[65040,7],[65041,0],[65043,10],[65044,7],[65045,0],[65056,14],[65072,0],[65075,12],[65077,0],[65101,12],[65104,7],[65105,0],[65106,8],[65107,0],[65108,7],[65109,10],[65110,0],[65136,11],[65141,0],[65142,11],[65277,0],[65279,13],[65280,0],[65287,8],[65288,0],[65292,7],[65293,0],[65294,8],[65295,0],[65296,9],[65306,10],[65307,7],[65308,0],[65313,11],[65339,0],[65343,12],[65344,0],[65345,11],[65371,0],[65382,17],[65438,14],[65440,11],[65471,0],[65474,11],[65480,0],[65482,11],[65488,0],[65490,11],[65496,0],[65498,11],[65501,0],[65529,13],[65532,0],[65536,11],[65548,0],[65549,11],[65575,0],[65576,11],[65595,0],[65596,11],[65598,0],[65599,11],[65614,0],[65616,11],[65630,0],[65664,11],[65787,0],[65856,11],[65909,0],[66045,14],[66046,0],[66176,11],[66205,0],[66208,11],[66257,0],[66272,14],[66273,0],[66304,11],[66336,0],[66349,11],[66379,0],[66384,11],[66422,14],[66427,0],[66432,11],[66462,0],[66464,11],[66500,0],[66504,11],[66512,0],[66513,11],[66518,0],[66560,11],[66718,0],[66720,9],[66730,0],[66736,11],[66772,0],[66776,11],[66812,0],[66816,11],[66856,0],[66864,11],[66916,0],[67072,11],[67383,0],[67392,11],[67414,0],[67424,11],[67432,0],[67584,11],[67590,0],[67592,11],[67593,0],[67594,11],[67638,0],[67639,11],[67641,0],[67644,11],[67645,0],[67647,11],[67670,0],[67680,11],[67703,0],[67712,11],[67743,0],[67808,11],[67827,0],[67828,11],[67830,0],[67840,11],[67862,0],[67872,11],[67898,0],[67968,11],[68024,0],[68030,11],[68032,0],[68096,11],[68097,14],[68100,0],[68101,14],[68103,0],[68108,14],[68112,11],[68116,0],[68117,11],[68120,0],[68121,11],[68150,0],[68152,14],[68155,0],[68159,14],[68160,0],[68192,11],[68221,0],[68224,11],[68253,0],[68288,11],[68296,0],[68297,11],[68325,14],[68327,0],[68352,11],[68406,0],[68416,11],[68438,0],[68448,11],[68467,0],[68480,11],[68498,0],[68608,11],[68681,0],[68736,11],[68787,0],[68800,11],[68851,0],[68864,11],[68900,14],[68904,0],[68912,9],[68922,0],[69248,11],[69290,0],[69291,14],[69293,0],[69296,11],[69298,0],[69376,11],[69405,0],[69415,11],[69416,0],[69424,11],[69446,14],[69457,0],[69552,11],[69573,0],[69600,11],[69623,0],[69632,14],[69635,11],[69688,14],[69703,0],[69734,9],[69744,0],[69759,14],[69763,11],[69808,14],[69819,0],[69821,13],[69822,0],[69837,13],[69838,0],[69840,11],[69865,0],[69872,9],[69882,0],[69888,14],[69891,11],[69927,14],[69941,0],[69942,9],[69952,0],[69956,11],[69957,14],[69959,11],[69960,0],[69968,11],[70003,14],[70004,0],[70006,11],[70007,0],[70016,14],[70019,11],[70067,14],[70081,11],[70085,0],[70089,14],[70093,0],[70094,14],[70096,9],[70106,11],[70107,0],[70108,11],[70109,0],[70144,11],[70162,0],[70163,11],[70188,14],[70200,0],[70206,14],[70207,0],[70272,11],[70279,0],[70280,11],[70281,0],[70282,11],[70286,0],[70287,11],[70302,0],[70303,11],[70313,0],[70320,11],[70367,14],[70379,0],[70384,9],[70394,0],[70400,14],[70404,0],[70405,11],[70413,0],[70415,11],[70417,0],[70419,11],[70441,0],[70442,11],[70449,0],[70450,11],[70452,0],[70453,11],[70458,0],[70459,14],[70461,11],[70462,14],[70469,0],[70471,14],[70473,0],[70475,14],[70478,0],[70480,11],[70481,0],[70487,14],[70488,0],[70493,11],[70498,14],[70500,0],[70502,14],[70509,0],[70512,14],[70517,0],[70656,11],[70709,14],[70727,11],[70731,0],[70736,9],[70746,0],[70750,14],[70751,11],[70754,0],[70784,11],[70832,14],[70852,11],[70854,0],[70855,11],[70856,0],[70864,9],[70874,0],[71040,11],[71087,14],[71094,0],[71096,14],[71105,0],[71128,11],[71132,14],[71134,0],[71168,11],[71216,14],[71233,0],[71236,11],[71237,0],[71248,9],[71258,0],[71296,11],[71339,14],[71352,11],[71353,0],[71360,9],[71370,0],[71453,14],[71468,0],[71472,9],[71482,0],[71680,11],[71724,14],[71739,0],[71840,11],[71904,9],[71914,0],[71935,11],[71943,0],[71945,11],[71946,0],[71948,11],[71956,0],[71957,11],[71959,0],[71960,11],[71984,14],[71990,0],[71991,14],[71993,0],[71995,14],[71999,11],[72e3,14],[72001,11],[72002,14],[72004,0],[72016,9],[72026,0],[72096,11],[72104,0],[72106,11],[72145,14],[72152,0],[72154,14],[72161,11],[72162,0],[72163,11],[72164,14],[72165,0],[72192,11],[72193,14],[72203,11],[72243,14],[72250,11],[72251,14],[72255,0],[72263,14],[72264,0],[72272,11],[72273,14],[72284,11],[72330,14],[72346,0],[72349,11],[72350,0],[72384,11],[72441,0],[72704,11],[72713,0],[72714,11],[72751,14],[72759,0],[72760,14],[72768,11],[72769,0],[72784,9],[72794,0],[72818,11],[72848,0],[72850,14],[72872,0],[72873,14],[72887,0],[72960,11],[72967,0],[72968,11],[72970,0],[72971,11],[73009,14],[73015,0],[73018,14],[73019,0],[73020,14],[73022,0],[73023,14],[73030,11],[73031,14],[73032,0],[73040,9],[73050,0],[73056,11],[73062,0],[73063,11],[73065,0],[73066,11],[73098,14],[73103,0],[73104,14],[73106,0],[73107,14],[73112,11],[73113,0],[73120,9],[73130,0],[73440,11],[73459,14],[73463,0],[73648,11],[73649,0],[73728,11],[74650,0],[74752,11],[74863,0],[74880,11],[75076,0],[77824,11],[78895,0],[78896,13],[78905,0],[82944,11],[83527,0],[92160,11],[92729,0],[92736,11],[92767,0],[92768,9],[92778,0],[92880,11],[92910,0],[92912,14],[92917,0],[92928,11],[92976,14],[92983,0],[92992,11],[92996,0],[93008,9],[93018,0],[93027,11],[93048,0],[93053,11],[93072,0],[93760,11],[93824,0],[93952,11],[94027,0],[94031,14],[94032,11],[94033,14],[94088,0],[94095,14],[94099,11],[94112,0],[94176,11],[94178,0],[94179,11],[94180,14],[94181,0],[94192,14],[94194,0],[110592,17],[110593,0],[110948,17],[110952,0],[113664,11],[113771,0],[113776,11],[113789,0],[113792,11],[113801,0],[113808,11],[113818,0],[113821,14],[113823,0],[113824,13],[113828,0],[119141,14],[119146,0],[119149,14],[119155,13],[119163,14],[119171,0],[119173,14],[119180,0],[119210,14],[119214,0],[119362,14],[119365,0],[119808,11],[119893,0],[119894,11],[119965,0],[119966,11],[119968,0],[119970,11],[119971,0],[119973,11],[119975,0],[119977,11],[119981,0],[119982,11],[119994,0],[119995,11],[119996,0],[119997,11],[120004,0],[120005,11],[120070,0],[120071,11],[120075,0],[120077,11],[120085,0],[120086,11],[120093,0],[120094,11],[120122,0],[120123,11],[120127,0],[120128,11],[120133,0],[120134,11],[120135,0],[120138,11],[120145,0],[120146,11],[120486,0],[120488,11],[120513,0],[120514,11],[120539,0],[120540,11],[120571,0],[120572,11],[120597,0],[120598,11],[120629,0],[120630,11],[120655,0],[120656,11],[120687,0],[120688,11],[120713,0],[120714,11],[120745,0],[120746,11],[120771,0],[120772,11],[120780,0],[120782,9],[120832,0],[121344,14],[121399,0],[121403,14],[121453,0],[121461,14],[121462,0],[121476,14],[121477,0],[121499,14],[121504,0],[121505,14],[121520,0],[122880,14],[122887,0],[122888,14],[122905,0],[122907,14],[122914,0],[122915,14],[122917,0],[122918,14],[122923,0],[123136,11],[123181,0],[123184,14],[123191,11],[123198,0],[123200,9],[123210,0],[123214,11],[123215,0],[123584,11],[123628,14],[123632,9],[123642,0],[124928,11],[125125,0],[125136,14],[125143,0],[125184,11],[125252,14],[125259,11],[125260,0],[125264,9],[125274,0],[126464,11],[126468,0],[126469,11],[126496,0],[126497,11],[126499,0],[126500,11],[126501,0],[126503,11],[126504,0],[126505,11],[126515,0],[126516,11],[126520,0],[126521,11],[126522,0],[126523,11],[126524,0],[126530,11],[126531,0],[126535,11],[126536,0],[126537,11],[126538,0],[126539,11],[126540,0],[126541,11],[126544,0],[126545,11],[126547,0],[126548,11],[126549,0],[126551,11],[126552,0],[126553,11],[126554,0],[126555,11],[126556,0],[126557,11],[126558,0],[126559,11],[126560,0],[126561,11],[126563,0],[126564,11],[126565,0],[126567,11],[126571,0],[126572,11],[126579,0],[126580,11],[126584,0],[126585,11],[126589,0],[126590,11],[126591,0],[126592,11],[126602,0],[126603,11],[126620,0],[126625,11],[126628,0],[126629,11],[126634,0],[126635,11],[126652,0],[127280,11],[127306,0],[127312,11],[127338,0],[127344,11],[127370,0],[127462,18],[127488,0],[127995,14],[128e3,0],[130032,9],[130042,0],[917505,13],[917506,0],[917536,14],[917632,0],[917760,14],[918e3,0]];function default_(r,e){var t=findBoundaries(r,e);if(t.length==0)return[];for(var n=[],i=0;i=this.text.length?20:isStartOfSurrogatePair(this.text[e])?property(this.text[e]+this.text[e+1]):property(this.text[e],this.options)},r.prototype.match=function(e,t,n,i){var a,u,o,l,s=(a=e==null?void 0:e.includes(this.lookbehind))!==null&&a!==void 0?a:!0;return s=s&&((u=t==null?void 0:t.includes(this.left))!==null&&u!==void 0?u:!0),s=s&&((o=n==null?void 0:n.includes(this.right))!==null&&o!==void 0?o:!0),s&&((l=i==null?void 0:i.includes(this.lookahead))!==null&&l!==void 0?l:!0)},r.prototype.propertyMatch=function(e,t,n,i){var a=this,u=v(function(o){return propertyVal(o,a.options)},"propMapper");return this.match(e==null?void 0:e.map(u),t==null?void 0:t.map(u),n==null?void 0:n.map(u),i==null?void 0:i.map(u))},r}();function isNonSpace(r,e){return!Array.from(r).map(function(t){return property(t,e)}).every(function(t){return t===3||t===1||t===2||t===4})}v(isNonSpace,"isNonSpace");function findBoundaries(r,e){var t,n,i;if(r.length===0)return[];e&&!e.rules&&(e.rules=[]);var a=[],u,o=0,l=new BreakerContext(r,e,o),s=0;do{if(u=o,o=C(o),l=l.next(o),l.match(null,[19],null,null)){a.push(u);continue}if(l.match(null,null,[20],null)){a.push(u);break}if(!l.match(null,[3],[1],null)){var f=[2,3,1];if(l.match(null,f,null,null)){a.push(u);continue}if(l.match(null,null,f,null)){a.push(u);continue}if(!l.match(null,[4],[4],null)){for(var c=[13,14,16];l.match(null,null,c,null);)t=(0,build_exports.__read)([o,C(o)],2),u=t[0],o=t[1],l=l.ignoringRight(o);if(l.right===20){a.push(u);break}for(;l.match(null,null,null,c);)o=C(o),l=l.ignoringLookahead(o);var d=[11,15],p=[8,6];if(e!=null&&e.rules){var g=!1;try{for(var w=(n=void 0,(0,build_exports.__values)(e.rules)),b=w.next();!b.done;b=w.next()){var T=b.value;if(g=T.match(l),g){T.breakIfMatch&&a.push(u);break}}}catch(h){n={error:h}}finally{try{b&&!b.done&&(i=w.return)&&i.call(w)}finally{if(n)throw n.error}}if(g)continue}if(!l.match(null,d,d,null)){var S=[10].concat(p);if(!l.match(null,d,S,d)&&!l.match(d,S,d,null)&&!l.match(null,[15],[6],null)&&!l.match(null,[15],[5],[15])&&!l.match([15],[5],[15],null)&&!l.match(null,[9],[9],null)&&!l.match(null,d,[9],null)&&!l.match(null,[9],d,null)){var _=[7].concat(p);if(!l.match([9],_,[9],null)&&!l.match(null,[9],_,[9])&&!l.match(null,[17],[17],null)){var y=[17,9].concat(d);if(!l.match(null,y,[12],null)&&!l.match(null,[12],[12],null)&&!l.match(null,[12],y,null)){if(l.right===18){if(s+=1,s%2==1)continue}else s=0;a.push(u)}}}}}}}while(u=r.length?r.length:isStartOfSurrogatePair(r[h])?h+2:h+1}}v(findBoundaries,"findBoundaries");function isStartOfSurrogatePair(r){var e=r.charCodeAt(0);return e>=55296&&e<=56319}v(isStartOfSurrogatePair,"isStartOfSurrogatePair");function property(r,e){if(e!=null&&e.propertyMapping){var t=e.propertyMapping(r);if(t)return propertyVal(t,e)}var n=r.codePointAt(0);return searchForProperty(n,0,WORD_BREAK_PROPERTY.length-1)}v(property,"property");function propertyVal(r,e){var t,n,i=v(function(u){return u.toLowerCase()==r.toLowerCase()},"matcher"),a=(n=(t=e==null?void 0:e.customProperties)===null||t===void 0?void 0:t.findIndex(i))!==null&&n!==void 0?n:-1;return a!=-1?-a-1:propertyMap.findIndex(i)}v(propertyVal,"propertyVal");function searchForProperty(r,e,t){if(t=u?searchForProperty(r,n+1,t):i[1]}v(searchForProperty,"searchForProperty");var MAX_SUGGESTIONS=12,TrieModel=function(){function r(e,t){t===void 0&&(t={}),this.languageUsesCasing=t.languageUsesCasing,this.applyCasing=t.applyCasing,this._trie=new Trie(e.root,e.totalWeight,t.searchTermToKey||defaultSearchTermToKey),this.breakWords=t.wordBreaker||default_,this.punctuation=t.punctuation}return v(r,"TrieModel2"),r.prototype.configure=function(e){var t;return this.configuration={leftContextCodePoints:e.maxLeftContextCodePoints,rightContextCodePoints:(t=e.maxRightContextCodePoints)!==null&&t!==void 0?t:0}},r.prototype.toKey=function(e){return this._trie.toKey(e)},r.prototype.predict=function(e,t){if(!e.insert&&!t.left&&!t.right&&t.startOfBuffer&&t.endOfBuffer)return u(this._trie.firstN(MAX_SUGGESTIONS).map(function(o){var l=o.text,s=o.p;return{transform:{insert:l,deleteLeft:0},displayAs:l,p:s}}));var n=applyTransform(e,t),i=e.deleteLeft-e.insert.kmwLength(),a=getLastPreCaretToken(this.breakWords,n);return u(this._trie.lookup(a).map(function(o){var l=o.text,s=o.p;return transformToSuggestion({insert:l,deleteLeft:i+a.kmwLength()},s)}));function u(o){var l,s,f=[];try{for(var c=(0,build_exports.__values)(o),d=c.next();!d.done;d=c.next()){var p=d.value;f.push({sample:p,p:p.p})}}catch(g){l={error:g}}finally{try{d&&!d.done&&(s=c.return)&&s.call(c)}finally{if(l)throw l.error}}return f}},Object.defineProperty(r.prototype,"wordbreaker",{get:function(){return this.breakWords},enumerable:!1,configurable:!0}),r.prototype.traverseFromRoot=function(){return new r.Traversal(this._trie.root,"")},r.Traversal=function(){function e(t,n){this.root=t,this.prefix=n}return v(e,"class_1"),e.prototype.children=function(){var t,n,i,a,u,o,l,s,f,c,d,p,g,w,b,T,S,_;return(0,build_exports.__generator)(this,function(y){switch(y.label){case 0:if(t=this.root,t.type!="internal")return[3,9];n=v(function(C){var h,m,O,k,A,I,E,D,F,q,R,U;return(0,build_exports.__generator)(this,function(M){switch(M.label){case 0:if(h=t.children[C],!isHighSurrogate(C))return[3,12];if(h.type!="internal")return[3,9];m=h,O=v(function(N){var j;return(0,build_exports.__generator)(this,function(V){switch(V.label){case 0:return j=i.prefix+C+N,[4,{char:C+N,traversal:function(){return new r.Traversal(m.children[N],j)}}];case 1:return V.sent(),[2]}})},"_loop_3"),M.label=1;case 1:M.trys.push([1,6,7,8]),k=(R=void 0,(0,build_exports.__values)(m.values)),A=k.next(),M.label=2;case 2:return A.done?[3,5]:(I=A.value,[5,O(I)]);case 3:M.sent(),M.label=4;case 4:return A=k.next(),[3,2];case 5:return[3,8];case 6:return E=M.sent(),R={error:E},[3,8];case 7:try{A&&!A.done&&(U=k.return)&&U.call(k)}finally{if(R)throw R.error}return[7];case 8:return[3,11];case 9:return D=h.entries[0].key,C=C+D[i.prefix.length+1],F=i.prefix+C,[4,{char:C,traversal:function(){return new r.Traversal(h,F)}}];case 10:M.sent(),M.label=11;case 11:return[3,16];case 12:return isSentinel(C)?[2,"continue"]:[3,13];case 13:return C?[3,14]:[2,"continue"];case 14:return q=i.prefix+C,[4,{char:C,traversal:function(){return new r.Traversal(h,q)}}];case 15:M.sent(),M.label=16;case 16:return[2]}})},"_loop_1"),i=this,y.label=1;case 1:y.trys.push([1,6,7,8]),a=(0,build_exports.__values)(t.values),u=a.next(),y.label=2;case 2:return u.done?[3,5]:(o=u.value,[5,n(o)]);case 3:y.sent(),y.label=4;case 4:return u=a.next(),[3,2];case 5:return[3,8];case 6:return l=y.sent(),b={error:l},[3,8];case 7:try{u&&!u.done&&(T=a.return)&&T.call(a)}finally{if(b)throw b.error}return[7];case 8:return[2];case 9:s=this.prefix,f=t.entries.filter(function(C){return C.key!=s&&s.length=n)return o}}}catch(b){i={error:b}}finally{try{s&&!s.done&&(a=l.return)&&a.call(l)}finally{if(i)throw i.error}}else{u.enqueue(r);for(var p=void 0,g=v(function(){if(isNode(p))if(p.type==="leaf")u.enqueueAll(p.entries);else{var b=p;u.enqueueAll(p.values.map(function(T){return b.children[T]}))}else if(o.push({text:p.content,p:p.weight/t}),o.length>=n)return{value:o}},"_loop_4");p=u.dequeue();){var w=g();if(typeof w=="object")return w.value}}return o}v(getSortedResults,"getSortedResults");function isNode(r){return"type"in r}v(isNode,"isNode");function defaultSearchTermToKey(r){return r.normalize("NFD").replace(/[\\u0300-\\u036f]/g,"").toLowerCase()}v(defaultSearchTermToKey,"defaultSearchTermToKey"),extendString();var DummyModel=function(){function r(e){e=e||{},this._futureSuggestions=e.futureSuggestions?e.futureSuggestions.slice():[],e.punctuation&&(this.punctuation=e.punctuation)}return v(r,"DummyModel2"),r.prototype.configure=function(e){return this.configuration={leftContextCodePoints:e.maxLeftContextCodePoints,rightContextCodePoints:e.maxRightContextCodePoints},this.configuration},r.prototype.predict=function(e,t,n){var i=v(function(u){var o,l,s=[],f=u.length;try{for(var c=(0,build_exports.__values)(u),d=c.next();!d.done;d=c.next()){var p=d.value;s.push({sample:p,p:1})}}catch(g){o={error:g}}finally{try{d&&!d.done&&(l=c.return)&&l.call(c)}finally{if(o)throw o.error}}return s},"makeUniformDistribution");if(n)return i(n);var a=this._futureSuggestions.shift();return a?i(a):[]},r}(),dummy_model_default=DummyModel,correction_exports={};__export(correction_exports,{ClassicalDistanceCalculation:function(){return ClassicalDistanceCalculation},ContextTracker:function(){return ContextTracker},QUEUE_NODE_COMPARATOR:function(){return QUEUE_NODE_COMPARATOR},SearchNode:function(){return SearchNode},SearchResult:function(){return SearchResult},SearchSpace:function(){return SearchSpace},TrackedContextState:function(){return TrackedContextState},TrackedContextSuggestion:function(){return TrackedContextSuggestion},TrackedContextToken:function(){return TrackedContextToken}});var ClassicalDistanceCalculation=function(){function r(e){if(this.diagonalWidth=2,this.inputSequence=[],this.matchSequence=[],e){var t=e.resolvedDistances.length;this.resolvedDistances=Array(t);for(var n=0;n2*n)&&(i.sparse=!0),i},r.prototype.getCostAt=function(e,t,n){if(n===void 0&&(n=this.diagonalWidth),e<0||t<0)return e==-1&&t>=-1?t+1:t==-1&&e>=-1?e+1:Number.MAX_VALUE;var i=this.getTrueIndex(e,t,n);return i.sparse?Number.MAX_VALUE:this.resolvedDistances[i.row][i.col]},r.prototype.getFinalCost=function(){for(var e=this,t=e.getHeuristicFinalCost();t>e.diagonalWidth;)e=e.increaseMaxDistance(),t=e.getHeuristicFinalCost();return t},r.prototype.getHeuristicFinalCost=function(){return this.getCostAt(this.inputSequence.length-1,this.matchSequence.length-1)},r.prototype.hasFinalCostWithin=function(e){var t=this,n=t.getHeuristicFinalCost(),i=this.diagonalWidth;do{if(n<=e)return!0;if(i=0&&c>=0){var d=1;if(i=["transpose-start"],f!=e-1){var p=e-f-1;i=i.concat(Array(p).fill("transpose-delete")),d+=p}else{var p=t-c-1;i=i.concat(Array(p).fill("transpose-insert")),d+=p}i.push("transpose-end"),this.getCostAt(f-1,c-1)!=n-d&&(i=null),a=[f-1,c-1]}return i||(l==n-1?(i=["substitute"],a=[e-1,t-1]):u==n-1?(i=["insert"],a=[e,t-1]):o==n-1?(i=["delete"],a=[e-1,t]):(i=["match"],a=[e-1,t-1])),a[0]>=0&&a[1]>=0?this.editPath(a[0],a[1]).concat(i):a[0]>-1?Array(a[0]+1).fill("delete").concat(i):a[1]>-1?Array(a[1]+1).fill("insert").concat(i):i},r.getTransposeParent=function(e,t,n){if(t<0||n<0||e.inputSequence[t].key==e.matchSequence[n].key)return[-1,-1];for(var i=-1,a=t-1;a>=0;a--)if(e.inputSequence[a].key==e.matchSequence[n].key){i=a;break}for(var u=-1,a=n-1;a>=0;a--)if(e.matchSequence[a].key==e.inputSequence[t].key){u=a;break}return[i,u]},r.initialCostAt=function(e,t,n,i,a){var u=e.inputSequence[t].key==e.matchSequence[n].key?0:1,o=e.getCostAt(t-1,n-1)+u,l=i||e.getCostAt(t,n-1)+1,s=a||e.getCostAt(t-1,n)+1,f=Number.MAX_VALUE;if(t>0&&n>0){var c=(0,build_exports.__read)(r.getTransposeParent(e,t,n),2),d=c[0],p=c[1];f=e.getCostAt(d-1,p-1)+(t-d-1)+1+(n-p-1)}return Math.min(o,s,l,f)},r.prototype.getSubset=function(e,t){var n=new r(this);if(e>this.inputSequence.length||t>this.matchSequence.length)throw"Invalid dimensions specified for trim operation";n.inputSequence.splice(e),n.matchSequence.splice(t),n.resolvedDistances.splice(e);for(var i=this.getTrueIndex(e-1,t-1,this.diagonalWidth),a=i.col;a<=2*this.diagonalWidth;a++){var u=i.row-(a-i.col);if(u<0)break;if(a<0)n.resolvedDistances[u]=Array(2*n.diagonalWidth+1).fill(Number.MAX_VALUE);else{var o=2*this.diagonalWidth-a,l=n.resolvedDistances[u].splice(0,a+1),s=Array(o).fill(Number.MAX_VALUE);n.resolvedDistances[u]=l.concat(s)}}return n},r.forDiagonalOfAxis=function(e,t,n,i){for(var a=n-t=0){var f=s==0?o+2:Number.MAX_VALUE;l=r.initialCostAt(e,o,s,f,void 0);var c=l;if(s0&&u){var l=i+1;this.propagateUpdateFrom(e,t+1,n,l,a-1)}if(u&&o){var l=i+(e.inputSequence[t+1].key==e.matchSequence[n+1].key?0:1);this.propagateUpdateFrom(e,t+1,n+1,l,a);for(var s=-1,f=t+2;f0&&c>0){var d=i+(s-t-2)+1+(c-n-2);this.propagateUpdateFrom(e,s,c,d,e.diagonalWidth-1+c-s)}}},Object.defineProperty(r.prototype,"mapKey",{get:function(){var e=this.inputSequence.map(function(n){return n.key}).join(""),t=this.matchSequence.map(function(n){return n.key}).join("");return e+SENTINEL_CODE_UNIT+t+SENTINEL_CODE_UNIT+this.diagonalWidth},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"lastInputEntry",{get:function(){return this.inputSequence[this.inputSequence.length-1]},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"lastMatchEntry",{get:function(){return this.matchSequence[this.matchSequence.length-1]},enumerable:!1,configurable:!0}),r.computeDistance=function(e,t,n){n===void 0&&(n=1);var i=new r;n=n||1,i.diagonalWidth=n;for(var a=0;ae?t.p:e}).reduce(function(t,n){return t-Math.log(n)},0),this._inputCost},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"currentCost",{get:function(){return SearchSpace.EDIT_DISTANCE_COST_SCALE*this.knownCost+this.inputSamplingCost},enumerable:!1,configurable:!0}),r.prototype.buildInsertionEdges=function(){var e,t,n=[];try{for(var i=(0,build_exports.__values)(this.currentTraversal.children()),a=i.next();!a.done;a=i.next()){var u=a.value,o=u.traversal(),l={key:u.char,traversal:o},s=this.calculation.addMatchChar(l),f=new r(this);f.calculation=s,f.priorInput=this.priorInput,f.currentTraversal=o,n.push(f)}}catch(c){e={error:c}}finally{try{a&&!a.done&&(t=i.return)&&t.call(i)}finally{if(e)throw e.error}}return n},r.prototype.buildDeletionEdges=function(e){var t,n,i=[];try{for(var a=(0,build_exports.__values)(e),u=a.next();!u.done;u=a.next()){var o=u.value;if(o.p0:!1},r.prototype.handleNextNode=function(){if(!this.hasNextMatchEntry())return{type:"none"};var e=this.selectionQueue.dequeue(),t=e.correctionQueue.dequeue(),n={type:"intermediate",cost:t.currentCost};if(this.processedEdgeSet[t.mapKey])return this.selectionQueue.enqueue(e),n;this.processedEdgeSet[t.mapKey]=!0;var i=!1;if(t.knownCost>2)return n;t.knownCost==2&&(i=!0);for(var a=0,u=0;u<=e.index;u++)a+=this.minInputCost[u];if(t.currentCost>a+2.5*r.EDIT_DISTANCE_COST_SCALE)return n;if(!i){var o=t.buildInsertionEdges();e.correctionQueue.enqueueAll(o)}if(e.index==this.tierOrdering.length-1)return this.completedPaths.push(t),this.selectionQueue.enqueue(e),{type:"complete",cost:t.currentCost,finalNode:t};var l=this.tierOrdering[e.index+1],s=l.index,f=[];i||(f=t.buildDeletionEdges(this.inputSequence[s-1]));var c=t.buildSubstitutionEdges(this.inputSequence[s-1]);return l.correctionQueue.enqueueAll(f.concat(c)),this.selectionQueue=new priority_queue_default(this.QUEUE_SPACE_COMPARATOR,this.tierOrdering),n},r.prototype.getBestMatches=function(e){var t,n,i,a,u,o,l,s,f,c,d,p,g,w,b,T;return(0,build_exports.__generator)(this,function(S){switch(S.label){case 0:if(t=this,n={},e==0?i=1/0:e==null||Number.isNaN(e)?i=r.DEFAULT_ALLOTTED_CORRECTION_TIME_INTERVAL:i=e,a=function(){function _(y,C){this.largestIntervals=[0],this.loopStart=this.start=Date.now(),this.maxExecutionTime=y,this.maxTrueTime=C}return v(_,"ExecutionTimer2"),_.prototype.startLoop=function(){this.loopStart=Date.now()},_.prototype.markIteration=function(){var y=Date.now(),C=y-this.loopStart;this.executionTime+=C,C&&(this.largestIntervals.length>2&&C>this.largestIntervals[0]?this.largestIntervals[0]=C:this.largestIntervals.push(C),this.largestIntervals.sort(),this.updateOutliers())},_.prototype.updateOutliers=function(){this.largestIntervals.length>2&&this.largestIntervals[2]>=2*(this.largestIntervals[0]+this.largestIntervals[1])&&(this.executionTime-=this.largestIntervals[2],this.largestIntervals.pop())},_.prototype.shouldTimeout=function(){var y=Date.now();return y-this.start>this.maxTrueTime?!0:this.executionTime>this.maxExecutionTime},_.prototype.resetOutlierCheck=function(){this.largestIntervals=[]},_}(),u=function(){function _(){this.currentCost=Number.MIN_SAFE_INTEGER,this.entries=[]}return v(_,"BatchingAssistant2"),_.prototype.checkAndAdd=function(y){var C=null;y.currentCost>this.currentCost&&(C=this.tryFinalize(),this.currentCost=y.currentCost);var h=y.calculation.matchSequence.map(function(m){return m.key}).join("");return t.returnedValues[h]||(t.returnedValues[h]=y),n[h]||(this.entries.push(new SearchResult(y)),n[h]=y),C},_.prototype.tryFinalize=function(){var y=null;return this.entries.length>0&&(y=this.entries,this.entries=[]),y},_}(),o=new u,l=new a(i*1.5,i),s=Object.values(this.returnedValues),!(s.length>0))return[3,6];f=new priority_queue_default(QUEUE_NODE_COMPARATOR,s),l.startLoop(),S.label=1;case 1:return f.count>0?(c=f.dequeue(),c.isFullReplacement?[3,1]:(d=o.checkAndAdd(c),l.markIteration(),d?[4,d]:[3,3])):[3,4];case 2:S.sent(),S.label=3;case 3:return[3,1];case 4:return p=o.tryFinalize(),p?[4,p]:[3,6];case 5:S.sent(),S.label=6;case 6:l.resetOutlierCheck(),l.startLoop(),g=!1,S.label=7;case 7:w=void 0;do w=this.handleNextNode(),l.markIteration(),l.shouldTimeout()&&(g=!0);while(!g&&w.type=="intermediate");if(b=void 0,w.type=="none")return[3,10];if(w.type=="complete"){if(w.finalNode.isFullReplacement)return[3,10];b=o.checkAndAdd(w.finalNode)}return b?[4,b]:[3,9];case 8:S.sent(),S.label=9;case 9:if(!g&&this.hasNextMatchEntry())return[3,7];S.label=10;case 10:return T=o.tryFinalize(),T?[4,T]:[3,12];case 11:S.sent(),S.label=12;case 12:return[2,null]}})},r.EDIT_DISTANCE_COST_SCALE=5,r.MIN_KEYSTROKE_PROBABILITY=1e-4,r.DEFAULT_ALLOTTED_CORRECTION_TIME_INTERVAL=33,r}(),TransformUtils=function(){function r(){}return v(r,"TransformUtils2"),r.isWhitespace=function(e){var t=/^[\\u0009\\u000A\\u000D\\u0020\\u00a0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u200b\\u2028\\u2029\\u202f\\u205f\\u3000]+$/i;return e.insert.match(t)!=null},r.isBackspace=function(e){return e.insert==""&&e.deleteLeft>0&&!e.deleteRight},r.isEmpty=function(e){return e.insert==""&&e.deleteLeft==0&&!e.deleteRight},r}(),transformUtils_default=TransformUtils;function textToCharTransforms(r,e){for(var t=[],n=0;n0&&e.transformDistributions.forEach(function(n){return t.searchSpace[0].addInput(n)})},r.prototype.pushWhitespaceToTail=function(e){e===void 0&&(e=null);var t=new TrackedContextToken;t.transformDistributions=e?[e]:[],t.raw=null,this.tokens.push(t)},r.prototype.replaceTailForBackspace=function(e,t){this.tokens.pop();var n=textToCharTransforms(e,t).map(function(a){return[{sample:a,p:1}]}),i=new TrackedContextToken;i.raw=e,i.transformDistributions=n,this.pushTail(i)},r.prototype.updateTail=function(e,t){var n=this.tail;t=t||(t===""?"":n.raw),e&&e.length>0&&(n.transformDistributions.push(e),this.searchSpace&&this.searchSpace.forEach(function(i){return i.addInput(e)})),n.raw=t},r.prototype.toRawTokenization=function(){var e,t,n=[];try{for(var i=(0,build_exports.__values)(this.tokens),a=i.next();!a.done;a=i.next()){var u=a.value;u.currentText!==null&&n.push(u.currentText)}}catch(o){e={error:o}}finally{try{a&&!a.done&&(t=i.return)&&t.call(i)}finally{if(e)throw e.error}}return n},r}(),CircularArray=function(){function r(e){e===void 0&&(e=r.DEFAULT_ARRAY_SIZE),this.currentHead=0,this.currentTail=0,this.circle=Array(e)}return v(r,"CircularArray2"),Object.defineProperty(r.prototype,"count",{get:function(){var e=this.currentHead-this.currentTail;return e<0&&(e=e+this.circle.length),e},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"maxCount",{get:function(){return this.circle.length},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"oldest",{get:function(){if(this.count!=0)return this.item(0)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"newest",{get:function(){if(this.count!=0)return this.item(this.count-1)},enumerable:!1,configurable:!0}),r.prototype.enqueue=function(e){var t=null,n=(this.currentHead+1)%this.maxCount;return n==this.currentTail&&(t=this.circle[this.currentTail],this.currentTail=(this.currentTail+1)%this.maxCount),this.circle[this.currentHead]=e,this.currentHead=n,t},r.prototype.dequeue=function(){if(this.currentTail==this.currentHead)return null;var e=this.circle[this.currentTail];return this.currentTail=(this.currentTail+1)%this.maxCount,e},r.prototype.popNewest=function(){if(this.currentTail==this.currentHead)return null;var e=this.circle[this.currentHead];return this.currentHead=(this.currentHead-1+this.maxCount)%this.maxCount,e},r.prototype.item=function(e){if(e>=this.count)throw"Invalid array index";var t=(this.currentTail+e)%this.maxCount;return this.circle[t]},r.DEFAULT_ARRAY_SIZE=5,r}(),ContextTracker=function(r){(0,build_exports.__extends)(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return v(e,"ContextTracker2"),e.attemptMatchContext=function(t,n,i){var a=n.toRawTokenization(),u=ClassicalDistanceCalculation.computeDistance(a.map(function(h){return{key:h}}),t.map(function(h){return{key:h}}),1),o=u.editPath(),l=!1,s=!1;if(o.length>1){if(o[0]=="insert"&&!(o[1]=="substitute"&&o.length==2)||o[0].indexOf("transpose")>=0)return null;o[0]=="delete"&&(l=!0)}var f=o.length-1,c=!1;if(o[f]=="delete"||o[0].indexOf("transpose")>=0||(o[f]=="insert"?s=!0:f>0&&o[f-1]=="insert"&&o[f]=="substitute"&&(s=!0,c=!0),f>0&&o[f-1]=="delete"&&o[f]=="substitute"))return null;for(var d=1;d1)if(l&&p.popHead(),s){var _=t[t.length-1],y=new TrackedContextToken;y.raw=_,b||!w?(p.pushWhitespaceToTail(i!=null?i:[]),y.transformDistributions=[]):(p.pushWhitespaceToTail(),y.transformDistributions=i?[i]:[]),p.pushTail(y)}else T?p.replaceTailForBackspace(S,w.id):p.updateTail(w?i:null,S);else if(o[f]=="insert"){var C=new TrackedContextToken;C.raw=t[0],C.transformDistributions=[i],p.pushTail(C)}else T?p.replaceTailForBackspace(S,w.id):p.updateTail(w?i:null,S);return p},e.modelContextState=function(t,n,i){var a=t.map(function(l){var s=new TrackedContextToken;return s.raw=l,s.raw?s.transformDistributions=textToCharTransforms(s.raw).map(function(f){return[{sample:f,p:1}]}):s.transformDistributions=[],s}),u=new TrackedContextState(i);for(a.length>0&&u.pushTail(a.splice(0,1)[0]);a.length>0;)u.pushWhitespaceToTail(),u.pushTail(a.splice(0,1)[0]);if(u.tokens.length==0){var o=new TrackedContextToken;o.raw="",u.pushTail(o)}return u},e.prototype.analyzeState=function(t,n,i){if(!t.traverseFromRoot)throw"This lexical model does not provide adequate data for correction algorithms and context reuse";var a=tokenize(t.wordbreaker||default_,n);if(a.left.length>0)for(var u=this.count-1;u>=0;u--){var o=e.attemptMatchContext(a.left,this.item(u),i);if(o)return o.taggedContext=n,o!=this.item(u)&&this.enqueue(o),o}var l=e.modelContextState(a.left,i,t);return l.taggedContext=n,this.enqueue(l),l},e}(CircularArray),ModelCompositor=function(){function r(e,t){this.SUGGESTION_ID_SEED=0,this.testMode=!1,this.lexicalModel=e,e.traverseFromRoot&&(this.contextTracker=new ContextTracker),this.punctuation=r.determinePunctuationFromModel(e),this.testMode=!!t}return v(r,"ModelCompositor2"),r.prototype.predictFromCorrections=function(e,t){var n,i,a=[],u=v(function(c){var d=o.lexicalModel.predict(c.sample,t),p=d.map(function(g){var w=c.sample,b=c.p;w.id!==void 0&&(g.sample.transformId=w.id);var T={sample:g.sample,p:g.p*b};return T},o);a=a.concat(p)},"_loop_1"),o=this;try{for(var l=(0,build_exports.__values)(e),s=l.next();!s.done;s=l.next()){var f=s.value;u(f)}}catch(c){n={error:c}}finally{try{s&&!s.done&&(i=l.return)&&i.call(l)}finally{if(n)throw n.error}}return a},r.prototype.predict=function(e,t){var n,i,a,u,o=[],l=this.lexicalModel,s=this.punctuation;e instanceof Array?e.length==0&&e.push({sample:{insert:"",deleteLeft:0},p:1}):e=[{sample:e,p:1}];var f=e.sort(function(x,P){return P.p-x.p})[0].sample,c=transformUtils_default.isWhitespace(f),d=transformUtils_default.isBackspace(f),p=applyTransform(f,t),g=this.wordbreak(p),w=null,b=[],T,S=null;if(this.contextTracker){var y=this.contextTracker.analyzeState(this.lexicalModel,t,null);S=this.contextTracker.analyzeState(this.lexicalModel,p,transformUtils_default.isEmpty(f)?null:e);var C=S.searchSpace[0],h=0,m=S.tokens,O=m.length,k=m.length-y.tokens.length;O==0||k>0?(h=0,transformUtils_default.isWhitespace(f)&&(T=f,t=p,y=S)):k<0?h=this.wordbreak(p).kmwLength()+f.deleteLeft:h=this.wordbreak(t).kmwLength();var A=m[m.length-1],I=A.transformDistributions.length<=1,E=void 0,D=this.testMode?0:SearchSpace.DEFAULT_ALLOTTED_CORRECTION_TIME_INTERVAL;try{for(var F=(0,build_exports.__values)(C.getBestMatches(D)),q=F.next();!q.done;q=F.next()){var R=q.value,_=R.map(function(P){var W=P.matchString,H;P.inputSequence.length>0?H=P.inputSequence[P.inputSequence.length-1].sample:H=f;var ie={insert:W,deleteLeft:h,id:f.id},ee=P.totalCost;return I&&(ee*=r.SINGLE_CHAR_KEY_PROB_EXPONENT),{sample:ie,p:Math.exp(-ee)}},this),U=this.predictFromCorrections(_,t);U.length>0&&E===void 0&&(E=-Math.log(_[0].p)),b=b.concat(U);var M=R[0].totalCost;if(M>=E+8)break;if(b.length>=r.MAX_SUGGESTIONS){if(M>=E+4)break;if(b.sort(function(P,W){return W.p-P.p}),b[r.MAX_SUGGESTIONS-1].p>Math.exp(-M))break}}}catch(x){n={error:x}}finally{try{q&&!q.done&&(i=F.return)&&i.call(F)}finally{if(n)throw n.error}}}else{var _=void 0;c?(_=[{sample:f,p:1}],T=f):_=e.map(function(x){var P=x.sample;return transformUtils_default.isWhitespace(P)&&!c||transformUtils_default.isBackspace(P)&&!d?null:x}),_=_.filter(function(x){return!!x}),b=this.predictFromCorrections(_,t)}var N={},j=null;l.languageUsesCasing&&(j=this.detectCurrentCasing(p));var V=this.wordbreak(t);try{for(var G=(0,build_exports.__values)(b),B=G.next();!B.done;B=G.next()){var L=B.value,Q=L.sample.displayAs,X=Q==g;if(this.lexicalModel.languageUsesCasing&&(X=X||Q==this.lexicalModel.applyCasing("lower",g)),X)if(w)w.p&&L.p&&(w.p+=L.p);else{var z=L.sample.transform,Y={insert:g,deleteLeft:z.deleteLeft,deleteRight:z.deleteRight,id:z.id},te=transformToSuggestion(Y,L.p);w=this.toAnnotatedSuggestion(te,"keep",quote_behavior_default.noQuotes),w.matchesModel=!0,w.transformId=L.sample.transformId}else{j&&j!="lower"&&(this.applySuggestionCasing(L.sample,V,j),Q=L.sample.displayAs);var J=N[Q];J?J.p+=L.p:N[Q]=L}}}catch(x){a={error:x}}finally{try{B&&!B.done&&(u=G.return)&&u.call(G)}finally{if(a)throw a.error}}if(!w&&g!=""){var Y=(0,build_exports.__assign)({},f),$=transformToSuggestion(Y,1);$.displayAs=g,w=this.toAnnotatedSuggestion($,"keep"),w.matchesModel=!1}for(var re in N){var ne=N[re];o.push(ne)}o=o.sort(function(x,P){return P.p-x.p});var K=o.splice(0,r.MAX_SUGGESTIONS).map(function(x){return x.sample.p&&(x.sample["lexical-p"]=x.sample.p,x.sample["correction-p"]=x.p/x.sample.p,x.sample.p=x.p),x.sample});w&&(K=[w].concat(K));var Z=this;return K.forEach(function(x){if(!t.right)x.transform.insert+=s.insertAfterWord;else{var P=Z.tokenize(t);P&&P.caretSplitsToken&&(x.transform.insert+=s.insertAfterWord)}if(T){var W=buildMergedTransform(T,x.transform);W.id=x.transformId;var H=x;H.transform=W}x.id=Z.SUGGESTION_ID_SEED,Z.SUGGESTION_ID_SEED++}),S&&(S.tail.replacements=K.map(function(x){return{suggestion:x,tokenWidth:1}})),K},r.prototype.applySuggestionCasing=function(e,t,n){var i=t.kmwLength()-e.transform.deleteLeft;i>0&&(e.transform.deleteLeft+=i,e.transform.insert=t.kmwSubstr(0,i)+e.transform.insert),e.transform.insert=this.lexicalModel.applyCasing(n,e.transform.insert),e.displayAs=this.lexicalModel.applyCasing(n,e.displayAs)},r.prototype.toAnnotatedSuggestion=function(e,t,n){n===void 0&&(n=quote_behavior_default.default);var i=quote_behavior_default,a=i.noQuotes;return(t=="keep"||t=="revert")&&(a=i.useQuotes),{transform:e.transform,transformId:e.transformId,displayAs:i.apply(n,e.displayAs,this.punctuation,a),tag:t,p:e.p}},r.determinePunctuationFromModel=function(e){var t=DEFAULT_PUNCTUATION;if(!e.punctuation)return t;var n=e.punctuation,i=n.insertAfterWord;i!==""&&!i&&(i=t.insertAfterWord);var a=n.quotesForKeepSuggestion;a||(a=t.quotesForKeepSuggestion);var u=n.isRTL;return{insertAfterWord:i,quotesForKeepSuggestion:a,isRTL:u}},r.prototype.acceptSuggestion=function(e,t,n){var i=e.transform,a=t.left.kmwSubstr(-i.deleteLeft,i.deleteLeft),u=i.insert.kmwLength(),o={insert:a,deleteLeft:u},l=t;n&&(o=buildMergedTransform(o,n),l=applyTransform(n,l));var s,f=this.tokenize(l);f?(f.left.length>0?s=f.left[f.left.length-1]:s="",s+=f.caretSplitsToken?f.right[0]:""):s=this.wordbreak(l);var c=transformToSuggestion(o);c.displayAs=s;var d=this.toAnnotatedSuggestion(c,"revert");if(e.transformId!=null&&(d.transformId=-e.transformId),e.id!=null?d.id=-e.id:(d.id=-this.SUGGESTION_ID_SEED,this.SUGGESTION_ID_SEED++),this.contextTracker){var p=this.contextTracker.newest;p||(p=this.contextTracker.analyzeState(this.lexicalModel,t)),p.tail.activeReplacementId=e.id;var g=applyTransform(e.transform,t);this.contextTracker.analyzeState(this.lexicalModel,g)}return d},r.prototype.applyReversion=function(e,t){var n=this,i=v(function(){var s=applyTransform(e.transform,t),f=n.predict({insert:"",deleteLeft:0},s);return f.forEach(function(c){c.transformId=-e.transformId}),f},"fallbackSuggestions");if(!this.contextTracker)return i();for(var a=!1,u=this.contextTracker.count-1;u>=0;u--){var o=this.contextTracker.item(u);if(o.tail.activeReplacementId==-e.id){a=!0;break}}if(!a)return i();for(;this.contextTracker.newest.tail.activeReplacementId!=-e.id;)this.contextTracker.popNewest();this.contextTracker.newest.tail.revert();var l=this.contextTracker.newest.tail.replacements.map(function(s){return s.suggestion});return l.forEach(function(s){s.transformId=-e.transformId}),l},r.prototype.wordbreak=function(e){var t=this.lexicalModel;if(t.wordbreaker||!t.wordbreak){var n=t.wordbreaker||default_;return wordbreak(n,e)}else return t.wordbreak(e)},r.prototype.tokenize=function(e){var t=this.lexicalModel;return t.wordbreaker?tokenize(t.wordbreaker,e):null},r.prototype.resetContext=function(e){if(this.contextTracker){var t=tokenize(this.lexicalModel.wordbreaker||default_,e),n=ContextTracker.modelContextState(t.left,null,this.lexicalModel);this.contextTracker.enqueue(n)}},r.prototype.detectCurrentCasing=function(e){var t,n=this.lexicalModel,i=this.wordbreak(e);if(!n.languageUsesCasing)throw"Invalid attempt to detect casing: languageUsesCasing is set to false";if(!n.applyCasing)throw"Invalid LMLayer state: languageUsesCasing is set to true, but no applyCasing function exists";return e.casingForm=="upper"||e.casingForm=="initial"?e.casingForm:n.applyCasing("lower",i)==i?"lower":n.applyCasing("upper",i)==i?i.kmwLength()>1?"upper":"initial":n.applyCasing("initial",i)==i?"initial":(t=e.casingForm)!==null&&t!==void 0?t:null},r.MAX_SUGGESTIONS=12,r.SINGLE_CHAR_KEY_PROB_EXPONENT=16,r}(),model_compositor_default=ModelCompositor,DEFAULT_PUNCTUATION={quotesForKeepSuggestion:{open:"\\u201C",close:"\\u201D"},insertAfterWord:" "};extendString();var LMLayerWorker=function(){function r(e){e===void 0&&(e={importScripts:null,postMessage:null}),this._testMode=!1,this._postMessage=e.postMessage||postMessage,this._importScripts=e.importScripts||importScripts,this.setupConfigState()}return v(r,"LMLayerWorker2"),r.prototype.error=function(e,t){this.cast("error",{log:e,error:t&&t.stack?t.stack:void 0})},r.prototype.onMessage=function(e){var t=e.data.message;if(!t)throw new Error("Missing required \'message\' property: ".concat(e.data));var n=e.data;if(n.message=="load"){var i=n,a=!1;if(this._currentModelSource&&i.source.type==this._currentModelSource.type&&(i.source.type=="file"&&i.source.file==this._currentModelSource.file||i.source.type=="raw"&&i.source.code==this._currentModelSource.code)&&(a=!0),a){typeof console!="undefined"&&console.warn("Duplicate model load message detected - squashing!");return}else this._currentModelSource=i.source}else n.message=="unload"&&(this._currentModelSource=null);this.state.handleMessage(n)},r.prototype.cast=function(e,t){var n=this._postMessage;n((0,build_exports.__assign)({message:e},t))},r.prototype.loadModel=function(e){try{var t=e.configure(this._platformCapabilities);t.leftContextCodePoints||(t.leftContextCodePoints=t.leftContextCodeUnits),t.rightContextCodePoints||(t.rightContextCodePoints=t.rightContextCodeUnits),t.leftContextCodePoints||(t.leftContextCodePoints=this._platformCapabilities.maxLeftContextCodePoints),t.rightContextCodePoints||(t.rightContextCodePoints=this._platformCapabilities.maxRightContextCodePoints||0),e.languageUsesCasing&&!e.applyCasing&&(e.applyCasing=defaultApplyCasing);var n=this.transitionToReadyState(e);t.wordbreaksAfterSuggestions===void 0&&(t.wordbreaksAfterSuggestions=n.punctuation.insertAfterWord!=""),this.cast("ready",{configuration:t})}catch(i){this.error("loadModel failed!",i)}},r.prototype.loadModelFile=function(e){try{this._importScripts(e)}catch(t){this.error("Error occurred when attempting to load dictionary",t)}},r.prototype.unloadModel=function(){this.transitionToLoadingState()},r.prototype.setupConfigState=function(){var e=this;this.state={name:"unconfigured",handleMessage:function(t){if(t.message!=="config")throw new Error("invalid message; expected \'config\' but got ".concat(t.message));e._platformCapabilities=t.capabilities,e._testMode=!!t.testMode,e.transitionToLoadingState()}}},r.prototype.transitionToLoadingState=function(){var e=this;this.state={name:"modelless",handleMessage:function(t){if(t.message!=="load")throw new Error("invalid message; expected \'load\' but got ".concat(t.message));if(t.source.type=="file")e.loadModelFile(t.source.file);else{var n=t.source.code,i=new Function("LMLayerWorker","models","correction","wordBreakers",n);i(e,models_exports,correction_exports,obj_exports)}}}},r.prototype.transitionToReadyState=function(e){var t=this,n=new model_compositor_default(e,this._testMode);return this.state={name:"ready",handleMessage:function(i){switch(i.message){case"predict":var a=i.transform,c=i.context,f=n.predict(a,c);t.cast("suggestions",{token:i.token,suggestions:f});break;case"wordbreak":var u=wordbreak(e.wordbreaker||default_,i.context);t.cast("currentword",{token:i.token,word:u});break;case"unload":t.unloadModel();break;case"accept":var o=i.suggestion,c=i.context,l=i.postTransform,s=n.acceptSuggestion(o,c,l);t.cast("postaccept",{token:i.token,reversion:s});break;case"revert":var s=i.reversion,c=i.context,f=n.applyReversion(s,c);t.cast("postrevert",{token:i.token,suggestions:f});break;case"reset-context":var c=i.context;n.resetContext(c);break;default:throw new Error("invalid message; expected one of {\'predict\', \'wordbreak\', \'accept\', \'revert\', \'reset-context\', \'unload\'} but got ".concat(i.message))}},compositor:n},n},r.install=function(e){var t=new r({postMessage:e.postMessage,importScripts:e.importScripts.bind(e)});return e.onmessage=t.onMessage.bind(t),t.self=e,e.LMLayerWorker=t,e.models=models_exports,e.correction=correction_exports,e.wordBreakers=obj_exports,t},r}(),obj_default=LMLayerWorker;typeof self!="undefined"&&"postMessage"in self&&"importScripts"in self?obj_default.install(self):window.LMLayerWorker=obj_default;\n',bc="";var Bl=function(){function i(){}return i.constructInstance=function(){return new Worker(this.asBlobURI(Cc))},i.asBlobURI=function(t){var e=Ft(t);e+="\n"+bc;var n=new Blob([e],{type:"text/javascript"});return URL.createObjectURL(n)},i}(),on=Bl;var hc=function(){function i(t,e){this.suggestions=t,this.transcriptionID=e}return i}();var ol=function(i){(0,d.__extends)(t,i);function t(e,n){n===void 0&&(n=!1);var c=i.call(this)||this;c.recentTranscriptions=[],c._mayPredict=!0,c._mayCorrect=!0,c._state="inactive";var l={maxLeftContextCodePoints:64,maxRightContextCodePoints:n?0:64};return e&&(c.lmEngine=new Bn(l,e)),c}return Object.defineProperty(t.prototype,"activeModel",{get:function(){return this.currentModel},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isConfigured",{get:function(){return!!this.configuration},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"state",{get:function(){return this._state},enumerable:!1,configurable:!0}),t.prototype.unloadModel=function(){this.lmEngine.unloadModel(),delete this.currentModel,delete this.configuration,this._state="inactive",this.emit("statechange","inactive")},t.prototype.loadModel=function(e){var n=this;if(!e)throw new Error("Null reference not allowed.");var c=e.path?"file":"raw",l=c=="file"?e.path:e.code;return this.currentModel=e,this.mayPredict&&(this._state="active",this.emit("statechange","active")),this.lmEngine.loadModel(l,c).then(function(r){n.configuration=r,n._state="configured",n.emit("statechange","configured")}).catch(function(r){var s;r instanceof Error?s=r.message:s=String(r),console.error("Could not load model '"+e.id+"': "+s),n.currentModel=null,n._state="inactive",n.emit("statechange","inactive")})},t.prototype.invalidateContext=function(e,n){if(this.emit("invalidatesuggestions","context"),!this.currentModel||!this.configuration)return Promise.resolve([]);if(this.isActive){if(e){var c=e.buildTranscriptionFrom(e,null,!1);return this.predict_internal(c,!0,n)}}else return Promise.resolve([])},t.prototype.wordbreak=function(e,n){if(!this.isActive)return null;var c=new ue(H.from(e,!1),this.configuration,n);return this.lmEngine.wordbreak(c)},t.prototype.predict=function(e,n){return!this.isActive||!this.currentModel||!this.configuration?null:(this.emit("invalidatesuggestions","new"),this.predict_internal(e,!1,n))},t.prototype.applySuggestion=function(e,n,c){var l=this;if(!n)throw"Accepting suggestions requires a destination OutputTarget instance.";var r=this.getPredictionState(e.transformId);if(r){var s=H.from(r.preInput,!1);s.apply(e.transform);var B=s.buildTransformFrom(n);n.apply(B),this.emit("suggestionapplied",n);var o=H.from(r.preInput,!1);o.apply(r.transform);var g=new ue(r.preInput,this.configuration,c()),a=this.lmEngine.acceptSuggestion(e,g,r.transform);return a=a.then(function(F){var y={transform:r.transform,transformId:-r.token,displayAs:F.displayAs,id:F.id,tag:F.tag};return l.predictFromTarget(n,c()),y}),a}else return console.warn("Could not apply the Suggestion!"),null},t.prototype.applyReversion=function(e,n){var c=this;if(!n)throw"Accepting suggestions requires a destination OutputTarget instance.";var l=this.getPredictionState(-e.transformId);if(!l){console.warn("Could not apply the Suggestion!");return}var r=H.from(l.preInput,!1);r.apply(e.transform);var s=r.buildTransformFrom(n);n.apply(s);var B=this.lmEngine.revertSuggestion(e,new ue(l.preInput,this.configuration,null));return B.then(function(o){var g=new hc(o,s.id);return c.emit("suggestionsready",g),c.currentPromise=null,o})},t.prototype.predictFromTarget=function(e,n){if(!e)return null;var c=e.buildTranscriptionFrom(e,null,!1);return this.predict(c,n)},t.prototype.predict_internal=function(e,n,c){var l=this;if(!e)return null;var r=new ue(e.preInput,this.configuration,c);this.recordTranscription(e),n&&this.lmEngine.resetContext(r);var s=e.alternates;(!s||s.length==0)&&(s=[{sample:e.transform,p:1}]);var B=e.transform,o=this.currentPromise=this.lmEngine.predict(s,r);return o.then(function(g){if(o==l.currentPromise){var a=new hc(g,B.id);l.emit("suggestionsready",a),l.currentPromise=null}return g})},t.prototype.recordTranscription=function(e){this.recentTranscriptions.push(e),this.recentTranscriptions.length>t.TRANSCRIPTION_BUFFER&&this.recentTranscriptions.splice(0,1)},t.prototype.getPredictionState=function(e){var n=this.recentTranscriptions.filter(function(c){return c.token==e});return n.length==0?null:n[0]},t.prototype.shutdown=function(){this.lmEngine.shutdown()},Object.defineProperty(t.prototype,"isActive",{get:function(){return this.canEnable()?(this.activeModel||!1)&&this._mayPredict:(this._mayPredict=!1,!1)},enumerable:!1,configurable:!0}),t.prototype.canEnable=function(){return!!this.lmEngine},Object.defineProperty(t.prototype,"mayPredict",{get:function(){return this._mayPredict},set:function(e){if(!!this.canEnable()){var n=this._mayPredict;if(this._mayPredict=e,n!=e&&this.activeModel){var c=e?"active":"inactive";this._state=c,this.emit("statechange",c),this.isConfigured&&(this._state="configured",this.emit("statechange","configured"))}}},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"mayCorrect",{get:function(){return this._mayCorrect},set:function(e){this._mayCorrect=e},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"wordbreaksAfterSuggestions",{get:function(){return this.configuration.wordbreaksAfterSuggestions},enumerable:!1,configurable:!0}),t.prototype.tryAcceptSuggestion=function(e){return this.emit("tryaccept",e),!1},t.prototype.tryRevertSuggestion=function(){return this.emit("tryrevert"),!1},t.TRANSCRIPTION_BUFFER=10,t}(Uc.default),an=ol;var al=function(){function i(t,e,n){if(!t)throw new Error("device must be defined");n||(n=i.DEFAULT_OPTIONS),this.contextDevice=t,this.kbdProcessor=new Ot(t,n),this.lngProcessor=new an(e)}return Object.defineProperty(i.prototype,"languageProcessor",{get:function(){return this.lngProcessor},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"keyboardProcessor",{get:function(){return this.kbdProcessor},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"keyboardInterface",{get:function(){return this.keyboardProcessor.keyboardInterface},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"activeKeyboard",{get:function(){return this.keyboardInterface.activeKeyboard},set:function(t){this.keyboardInterface.activeKeyboard=t,this.resetContext()},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"activeModel",{get:function(){return this.languageProcessor.activeModel},enumerable:!1,configurable:!0}),i.prototype.processKeyEvent=function(t,e){var n=t.srcKeyboard&&this.activeKeyboard!=t.srcKeyboard,c=this.activeKeyboard;try{return n&&(this.keyboardInterface.activeKeyboard=t.srcKeyboard),this._processKeyEvent(t,e)}finally{n&&(this.keyboardInterface.activeKeyboard=c)}},i.prototype._processKeyEvent=function(t,e){var n,c=t.device.formFactor,l=t.isSynthetic;if((c==x.FormFactor.Desktop||!this.activeKeyboard||this.activeKeyboard.usesDesktopLayoutOnDevice(t.device))&&l&&this.keyboardProcessor.selectLayer(t))return new le;if(this.keyboardProcessor.doModifierPress(t,e,!l)&&!l)return new le;if(this.languageProcessor.isActive){if((t.kName=="K_BKSP"||t.Lcode==I.keyCodes.K_BKSP)&&this.languageProcessor.tryRevertSuggestion())return new le;if((t.kName=="K_SPACE"||t.Lcode==I.keyCodes.K_SPACE)&&this.languageProcessor.tryAcceptSuggestion("space"))return new le}var r=H.from(e,!0),s=this.keyboardProcessor.layerId,B=this.keyboardProcessor.processKeystroke(t,e);t.kNextLayer&&this.keyboardProcessor.selectLayer(t);var o=I.isKnownOSKModifierKey(t.kName);ot((n=B==null?void 0:B.transcription)===null||n===void 0?void 0:n.transform)&&t.kNextLayer&&(o=!0);var g=B!=null;if(g){var a=o?null:this.buildAlternates(B,t,r);B.finalize(this.keyboardProcessor,e,!1),a&&a.length>0&&(B.transcription.alternates=a)}else B=new le,B.transcription=e.buildTranscriptionFrom(e,null,!1),B.triggersDefaultCommand=!0;var F=B.setStore[f.TSS_LAYER]||t.kNextLayer;this.keyboardProcessor.newLayerStore.set(F?this.keyboardProcessor.layerId:""),this.keyboardProcessor.oldLayerStore.set(F?s:"");var y=this.keyboardProcessor.processPostKeystroke(this.contextDevice,e);return y&&y.finalize(this.keyboardProcessor,e,!0),B.predictionPromise=this.languageProcessor.predict(B.transcription,this.keyboardProcessor.layerId),B.triggersDefaultCommand||e.doInputEvent(),g?B:null},i.prototype.buildAlternates=function(t,e,n){var c;if(this.languageProcessor.isActive&&!t.triggersDefaultCommand){var l=e.keyDistribution,r=new ue(n,ue.ENGINE_RULE_WINDOW,this.keyboardProcessor.layerId),s=r.toMock();if(this.languageProcessor.isActive&&l&&e.kbdLayer){var B=Number.MAX_VALUE,o=Ae(),g=void 0;o.performance&&o.performance.now&&(g=function(){return o.performance.now()},B=g()+16);var a=Math.exp(-5);l.sort(function(L,P){return P.p-L.p});var F=this.activeKeyboard.layout(e.device.formFactor);c=[];for(var y=0,u=0,Q=l;u=B)break;var h=H.from(s,!1),b=F.getLayer(e.kbdLayer).getKey(C.keyId);if(!b){console.warn("Potential fat-finger key could not be found in layer!");continue}var U=this.keyboardProcessor.activeKeyboard.constructKeyEvent(b,e.device,this.keyboardProcessor.stateKeys),V=this.keyboardProcessor.processKeystroke(U,h);if(V&&!V.beep&&C.p>0){var X=V.transcription.transform;X.id=t.transcription.token,c.push({sample:X,p:C.p}),y+=C.p}}c.forEach(function(L){L.p/=y})}}return c},i.prototype.resetContext=function(t){this.keyboardProcessor.resetContext(t),this.languageProcessor.invalidateContext(t,this.keyboardProcessor.layerId)},i.DEFAULT_OPTIONS={baseLayout:"us"},i}(),gn=al;var xc=J(R(),1),gl=function(i){(0,d.__extends)(t,i);function t(e,n){var c=i.call(this)||this;c.initNewContext=!0,c._currentSuggestions=[],c.recentAccept=!1,c.swallowPrediction=!1,c.doRevert=!1,c.recentRevert=!1,c.doTryAccept=function(r){!c.recentAccept&&c.selected?c.accept(c.selected):c.recentAccept&&r=="space"&&(c.recentAccept=!1)},c.doTryRevert=function(){c.doRevert?(c.doRevert=!1,c.recentAccept=!1):c.recentAccept&&(c.showRevert(),c.swallowPrediction=!0)},c.invalidateSuggestions=function(r){c.initNewContext=!1,(!c.swallowPrediction||r=="context")&&(c.recentAccept=!1,c.doRevert=!1,c.recentRevert=!1,r=="context"&&(c.swallowPrediction=!1,c.initNewContext=!0)),r!="new"&&c.clearSuggestions()},c.updateSuggestions=function(r){var s=r.suggestions;c._currentSuggestions=s,c.keepSuggestion=null;for(var B=0,o=s;B0?1:0},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"target",{get:function(){var t;return(t=this.source)===null||t===void 0?void 0:t.target},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"isFromTouch",{get:function(){return!this.isFromMouse},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"isFromMouse",{get:function(){return this.source instanceof MouseEvent},enumerable:!1,configurable:!0}),i}(),K=Il;var Ql=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this,e)||this;return n.hasActiveClick=!1,n.ignoreSequence=!1,n._mouseStart=n.onMouseStart.bind(n),n._mouseMove=n.onMouseMove.bind(n),n._mouseEnd=n.onMouseEnd.bind(n),n}return t.prototype.registerEventHandlers=function(){this.config.eventRoot.addEventListener("mousedown",this._mouseStart,!0),this.config.eventRoot.addEventListener("mousemove",this._mouseMove,!1),this.config.eventRoot.addEventListener("mouseup",this._mouseEnd,!0)},t.prototype.unregisterEventHandlers=function(){this.config.eventRoot.removeEventListener("mousedown",this._mouseStart,!0),this.config.eventRoot.removeEventListener("mousemove",this._mouseMove,!1),this.config.eventRoot.removeEventListener("mouseup",this._mouseEnd,!0)},t.prototype.preventPropagation=function(e){e.preventDefault(),e.cancelBubble=!0,e.returnValue=!1,typeof e.stopImmediatePropagation=="function"?e.stopImmediatePropagation():typeof e.stopPropagation=="function"&&e.stopPropagation()},t.prototype.onMouseStart=function(e){if(!this.config.targetRoot.contains(e.target)){this.ignoreSequence=!0;return}this.preventPropagation(e),this.onInputStart(K.fromEvent(e)),this.hasActiveClick=!0},t.prototype.onMouseMove=function(e){if(!this.ignoreSequence){var n=K.fromEvent(e);if(e.buttons){if(!this.hasActiveClick)return}else{this.hasActiveClick&&(this.hasActiveClick=!1,this.onInputMoveCancel(n));return}this.preventPropagation(e),this.config.coordConstrainedWithinInteractiveBounds(n)?this.onInputMove(n):this.onInputMoveCancel(n)}},t.prototype.onMouseEnd=function(e){if(this.ignoreSequence){this.ignoreSequence=!1;return}e.buttons||(this.hasActiveClick=!1),this.onInputEnd(K.fromEvent(e))},t}(It),Qt=Ql;var Cl=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this,e)||this;return n._touchStart=n.onTouchStart.bind(n),n._touchMove=n.onTouchMove.bind(n),n._touchEnd=n.onTouchEnd.bind(n),n}return t.prototype.registerEventHandlers=function(){this.config.eventRoot.addEventListener("touchstart",this._touchStart,!0),this.config.eventRoot.addEventListener("touchmove",this._touchMove,!1),this.config.eventRoot.addEventListener("touchend",this._touchEnd,!0)},t.prototype.unregisterEventHandlers=function(){this.config.eventRoot.removeEventListener("touchstart",this._touchStart,!0),this.config.eventRoot.removeEventListener("touchmove",this._touchMove,!1),this.config.eventRoot.removeEventListener("touchend",this._touchEnd,!0)},t.prototype.preventPropagation=function(e){e.preventDefault(),e.cancelBubble=!0,typeof e.stopImmediatePropagation=="function"?e.stopImmediatePropagation():typeof e.stopPropagation=="function"&&e.stopPropagation()},t.prototype.onTouchStart=function(e){this.onInputStart(K.fromEvent(e))},t.prototype.onTouchMove=function(e){this.preventPropagation(e);var n=K.fromEvent(e);this.config.coordConstrainedWithinInteractiveBounds(n)?this.onInputMove(n):this.onInputMoveCancel(n)},t.prototype.onTouchEnd=function(e){this.onInputEnd(K.fromEvent(e))},t}(It),Ct=Cl;var bl=function(){function i(t){this.totalLength=0,this.x=t.x,this.totalLength=0}return i.prototype.updateTo=function(t){var e=this.x;this.x=t.x;var n={deltaX:this.x-e};return this.totalLength+=Math.abs(n.deltaX),n},Object.defineProperty(i.prototype,"hasScrolled",{get:function(){return this.totalLength>i.HAS_SCROLLED_FUDGE_FACTOR},enumerable:!1,configurable:!0}),i.HAS_SCROLLED_FUDGE_FACTOR=10,i}(),hl=function(){function i(t,e,n){this.baseElement=t,this.rowClassMatch=e,this.selectedTargetMatch=n}return i.prototype.findTargetFromTouch=function(t,e,n){for(var c=t.x;e&&e.className!==void 0&&e.className.indexOf(this.rowClassMatch)<0;)e=e.parentNode;if(!e)return null;var l,r=0,s=24,B=1e5,o,g;for(l=0;l=0&&F=0&&y40&&(s=.6*e.offsetWidth),o-c>=0&&o-c=0&&c-g0)return;(e==null||e.id.indexOf("popup")<0)&&(this.pendingTarget&&this.highlight(this.pendingTarget,!1),this.clearHolds(),this.pendingTarget=null)}var n=t.x,c=n<2&&this.touchX>5||n>window.innerWidth-2&&this.touchX0&&this.touchCount--,this.pendingTarget?(this.highlight(this.pendingTarget,!1),this.pendingTarget.className.indexOf("hidden")<0&&l>0&&!c&&this.select(this.pendingTarget),this.clearHolds(),this.pendingTarget=null):(e=this.findBestTarget(t),e&&this.highlight(e,!1))},i.prototype.touchMove=function(t){if(!(t.activeInputCount>1||this.touchCount==0)){if(this.currentTarget&&this.scrollTouchState!=null){var e=this.scrollTouchState.updateTo(t).deltaX;this.currentTarget.scrollLeft-=window.devicePixelRatio*e;return}var n=t.y,c=this.pendingTarget,l=this.findBestTarget(t,!0);if(this.hasModalPopup()){c&&this.highlight(c,!1),this.pendingTarget=null;return}if(l=this.dealiasSubTarget(l),this.currentTarget=l,c&&l&&l!==c&&this.highlight(c,!1),l&&this.hasSubmenu(l)){if(l&&l.id.indexOf("popup")<0)return;l&&l.className.indexOf(this.selectedTargetMatch)<0&&this.highlight(l,!0)}else{var r=this.baseElement,s=Z(r),B=r.offsetHeight,o=Math.max(5,s-.25*B),g=s+B+.25*B;c&&(t.yg)&&(this.highlight(c,!1),this.clearHolds(),this.pendingTarget=null)}l&&this.pendingTarget&&(this.pendingTarget=l),this.pendingTarget&&l&&(c!=l||l.className.indexOf(this.selectedTargetMatch)<0)&&this.highlight(l,!0),c&&l&&l!=c&&l.id!=""&&this.hold(l)}},i}(),Xc=hl;var Ze=function(){function i(t){var e=m("div");e.id=i.BANNER_ID,e.className=i.BANNER_CLASS,this.div=e,this.height=t,this.update()}return Object.defineProperty(i.prototype,"height",{get:function(){return this._height},set:function(t){this._height=t>0?t:0,this.update()},enumerable:!1,configurable:!0}),i.prototype.update=function(){var t=this.div.style,e=t.height,n=t.display;return this._height>0?(t.height=this._height+"px",t.display="block"):(t.height="0px",t.display="none"),e!==t.height||n!==t.display},i.prototype.appendStyleSheet=function(){},i.prototype.getDiv=function(){return this.div},i.prototype.configureForKeyboard=function(t,e){},i.DEFAULT_HEIGHT=37,i.BANNER_CLASS="kmw-banner-bar",i.BANNER_ID="kmw-banner-bar",i}();var bt=function(i){(0,d.__extends)(t,i);function t(){return i.call(this,0)||this}return t}(Ze);var mc=function(i){(0,d.__extends)(t,i);function t(e,n){var c=this;e.length>0?(c=i.call(this)||this,n&&(c.height=n)):c=i.call(this,0)||this,e.indexOf("base64")>=0?console.log("Loading img from base64 data"):console.log("Loading img with src '"+e+"'"),c.img=document.createElement("img"),c.img.setAttribute("src",e);var l=c.img.style;return l.width="100%",l.height="100%",c.getDiv().appendChild(c.img),console.log("Image loaded."),c}return t.prototype.setImagePath=function(e){this.img&&this.img.setAttribute("src",e)},t}(Ze);var Ul=function(){function i(t,e){this.rtl=!1,this.index=t,this.rtl=e,this.constructRoot();var n=this.display=m("span");this.div.appendChild(n)}return i.prototype.constructRoot=function(){var t=this.div=m("div"),e=t.style;t.className="kmw-suggest-option",t.id=i.BASE_ID+this.index;var n=100-me.MARGIN*(me.SUGGESTION_LIMIT-1),c=n/me.SUGGESTION_LIMIT;e.width=c+"%",this.div.suggestion=this},i.prototype.matchKeyboardProperties=function(t){var e=this.div;if(t){t.KLC&&(e.lang=t.KLC);var n=t.KFont;n&&n.family&&n.family!=""&&(e.style.fontFamily=this.fontFamily=n.family)}},Object.defineProperty(i.prototype,"suggestion",{get:function(){return this._suggestion},enumerable:!1,configurable:!0}),i.prototype.update=function(t){this._suggestion=t,this.updateText()},i.prototype.updateText=function(){var t=this.generateSuggestionText(this.rtl);this.div.replaceChild(t,this.display),this.display=t},i.prototype.isEmpty=function(){return!this._suggestion},i.prototype.generateSuggestionText=function(t){var e=this._suggestion,n,c=m("span");if(c.className="kmw-suggestion-text",e==null)return c;if(e.displayAs==null||e.displayAs=="")n="\xA0";else{var l=t?8238:8237;n=String.fromCharCode(l)+e.displayAs}return c.innerHTML=n,c},i.BASE_ID="kmw-suggestion-",i}();var me=function(i){(0,d.__extends)(t,i);function t(e,n){var c=i.call(this,n||Ze.DEFAULT_HEIGHT)||this;return c.currentSuggestions=[],c.options=[],c.onSuggestionUpdate=function(l){c.currentSuggestions=l,c.options.forEach(function(r,s){s0&&this.options.splice(0,this.options.length);for(var n=0;n10)&&(c=0),n.className="kmw-key kmw-key-"+Le[c]},i.prototype.setToggleState=function(t){var e;switch(e=this.spec.sp,Le[e]){case"shift":case"shift-on":t===void 0&&(t=Le[e]=="shift"),this.spec.sp=1+(t?1:0);break;case"special":case"special-on":t===void 0&&(t=Le[e]=="special"),this.spec.sp=3+(t?1:0);break;default:return}this.setButtonClass()},i.prototype.isFrameKey=function(){var t=this.spec.sp||0;switch(Le[t]){case"default":case"deadkey":return!1;default:return!0}},i.prototype.allowsKeyTip=function(){return this.isFrameKey()?!1:!this.btn.classList.contains("kmw-spacebar")},i.prototype.highlight=function(t){var e=this.btn.classList;t?e.contains(i.HIGHLIGHT_CLASS)||e.add(i.HIGHLIGHT_CLASS):e.remove(i.HIGHLIGHT_CLASS)},i.getTextMetrics=function(t,e,n){n={fontFamily:n.fontFamily,fontSize:n.fontSize},n.fontFamily||(n.fontFamily=getComputedStyle(document.body).fontFamily),(!n.fontSize||n.fontSize=="")&&(n.fontSize="1em");var c=n.fontFamily,l=Se(n.fontSize),r;l.absolute?r=l.val+"px":r=l.val*e+"px";var s=i.getTextMetrics.canvas||(i.getTextMetrics.canvas=document.createElement("canvas")),B=s.getContext("2d");B.font=r+" "+c;var o=B.measureText(t);return o},i.prototype.getIdealFontSize=function(t,e,n,c){var l=getComputedStyle(this.btn),r=parseFloat(l.width),s=1,B=Se(n.fontSize||"1em");l.fontSize?c||(n=l):(s=t.getKeyEmFontSize(),r=this.getKeyWidth(t));var o=Se(n.fontSize||"1em"),g=i.getTextMetrics(e,s,n),a=.9,F=.9,y=2,u=2,Q,C;g.fontBoundingBoxAscent&&(Q=g.fontBoundingBoxAscent+g.fontBoundingBoxDescent);var h=Q?Q+u:0;n.height&&n.height.indexOf("px")!=-1&&(C=Number.parseFloat(n.height.substring(0,n.height.indexOf("px"))));var b=r*a/(g.width+y),U=h&&C?C*F/h:void 0,V=b;return U&&Ul&&er&&n90)&&(e=0)}var n=document.createElement("div");return n.className="kmw-key-label",e>0&&(n.innerText=String.fromCharCode(e)),n},t.prototype.processSubkeys=function(e,n){var c,l=e.subKeys=this.spec.sk;for(c=0;c0)return this.keys[0].displaysKeyCap},set:function(t){for(var e=0,n=this.keys;e4&&t.device.formFactor=="phone"&&(c.className=c.className+" kmw-5rows"),l.fontFamily="font"in e?e.font:"",this.nextlayer=c.layer=n.id,typeof n.nextlayer=="string"&&(c.nextLayer=this.nextlayer=n.nextlayer);var s=n.row;this.rows=[];for(var B=0;B=0&&t.layerGroup.layers.caps&&!e.subKeys&&t.touchCount==1},i.prototype.cleanup=function(){this.timerId&&window.clearTimeout(this.timerId),this.timerId=null},i.prototype.cancel=function(){this._state=te.Cancelled,this.cleanup()},i.prototype.incrementTouch=function(t){var e;return this._state==te.Waiting&&(!((e=t==null?void 0:t.keyId)===null||e===void 0)&&e.includes("K_SHIFT")?++this._touches==this.count&&this.realize():this.cancel()),this._state},i.prototype.realize=function(){if(this._state==te.Waiting){this._state=te.Realized,this.cleanup();var t=$.constructNullKeyEvent(this.vkbd.device);t.kNextLayer=this._destinationLayerId,t.Lstates=I.stateBitmasks.CAPS,t.LmodifierChange=!0,this.vkbd.raiseKeyEvent(t,null)}},i}(),In=fl;var Sl=function(i){(0,d.__extends)(t,i);function t(e,n){if(typeof n!="string"||n=="")throw"The 'layer' parameter for subkey construction must be properly defined.";return i.call(this,e,n)||this}return t.prototype.getId=function(){return"popup-"+this.layer+"-"+this.spec.id},t.prototype.construct=function(e,n,c){var l=this.spec,r=document.createElement("div"),s=e.getDefaultKeyObject(),B=r.style;for(var o in s)typeof l[o]!="string"&&(l[o]=s[o]);r.className="kmw-key-square-ex",c&&(B.marginTop="5px"),typeof l.width!="undefined"?B.width=l.width*n.offsetWidth/100+"px":B.width=n.offsetWidth+"px",B.height=n.offsetHeight+"px";var g=document.createElement("div"),a=this.btn=Vt(g,new xt(this,l.id));this.setButtonClass(),a.id=this.getId();var F=a.style;return F.height=B.height,F.lineHeight=n.style.lineHeight,F.width=B.width,F.position="absolute",a.appendChild(this.label=this.generateKeyText(e)),r.appendChild(a),this.square=r},t.prototype.allowsKeyTip=function(){return!1},t}(Qe),Wc=Sl;var Hl=function(){function i(t,e){var n=this;this.promise=new Promise(function(h){n.resolver=h}),this.vkbd=t,this.baseKey=e,this.currentSelection=e,e.key.highlight(!0);var c=e.subKeys,l=this.element=document.createElement("div"),r;l.id="kmw-popup-keys";var s=l.style;s.fontFamily=t.fontFamily;var B=getComputedStyle(e);s.fontSize=B.fontSize,s.visibility="hidden";var o=c.length,g,a;for(g=Math.min(Math.ceil(o/9),2),a=Math.ceil(o/g),s.width=a*e.offsetWidth+a*5+"px",r=0;r1&&y>0&&(F=!0);var u=e.key.layer;(typeof u!="string"||u=="")&&(u=t.layerId);var Q=new Wc(c[r],u),C=Q.construct(t,e,F);l.appendChild(C)}this.shim=document.createElement("div"),this.shim.id="kmw-popup-shim",t.device.formFactor==x.FormFactor.Phone&&this.selectDefaultSubkey(t,e,l)}return i.prototype.finalize=function(t){if(this.resolver){var e=null;this.currentSelection&&(e=this.vkbd.initKeyEvent(this.currentSelection,t),this.currentSelection.key.highlight(!1)),this.resolver(e)}this.resolver=null},i.prototype.reposition=function(t){var e=this.element,n=this.baseKey,c=t.topContainer,l=n.key.row.element,r=e.style,s=n.offsetLeft+n.offsetParent.offsetLeft+.5*(n.offsetWidth-e.offsetWidth),B=t.width-e.offsetWidth;s>B&&(s=B),s<0&&(s=0),r.left=s+"px";var o=c.getBoundingClientRect(),g=l.getBoundingClientRect();r.top=g.top-o.top-e.offsetHeight-3+"px",r.visibility="visible";var a=t.isEmbedded,F=getComputedStyle(e),y=parseFloat(F.top),u=0,Q=0;y0){var l=document.createElement("div"),r=l.style;l.id="kmw-popup-callout",n.appendChild(l);var s=t.getBoundingClientRect(),B=n.getBoundingClientRect(),o=Math.floor(s.top-B.top-9+e);return r.top=o+"px",r.left=s.left-B.left+"px",r.width=s.width+"px",r.height=s.bottom-B.top-o-1+"px",l}else return null},i.prototype.selectDefaultSubkey=function(t,e,n){for(var c,l,r=e.subKeys,s=0;s5)this.initialX=Number.MAX_SAFE_INTEGER,this.currentSelection=null;else{this.currentSelection.key.highlight(!0);return}this.baseKey.key.highlight(!1);for(var l=0;lwindow.innerWidth-B-p?(this.cap.style.left=b-B-1+"px",s-=p-1):this.cap.style.left=p+"px",F.left=s-p+"px";var E=getComputedStyle(this.element),oe=u.height,S=parseFloat(E.bottom),Ue=parseFloat(E.height),k=Math.ceil(U/2);if(this.cap.style.width=B+"px",this.tip.style.height=k+"px",this.cap.style.top=k-3+"px",this.cap.style.height=Q.bottom-u.top-Math.floor(C-U)-k+"px",this.constrain&&Ue+S>oe){var j=Ue+S-oe;F.height=U-j+"px";var ae=Math.max(0,U-j-U/2+2);this.cap.style.height=ae+"px"}F.display="block"}else this.element.style.display="none";this.key=t,this.state=e},i}(),Nc=Nl;function He(){try{if(this.device.formFactor=="desktop")return 1;var i=document.documentElement.clientWidth;if(screen.width>i)return 1;var t=screen.width;return D()?screen.widthscreen.height&&(t=screen.height),Math.round(100*t/i)/100}catch(e){return 1}}var Tl=function(i){(0,d.__extends)(t,i);function t(e){var n=this,c,l;n=i.call(this)||this,n._layerId="default",n.layerIndex=0,n.isStatic=!1,n._fixedWidthScaling=!1,n._fixedHeightScaling=!0,n.stateKeys={K_CAPS:!1,K_NUMLOCK:!1,K_SCROLL:!1},n.repeatDelete=function(){this.deleting&&(this.modelKeyClick(this.deleteKey),this.deleting=window.setTimeout(this.repeatDelete,100))}.bind(n),n.config=e,n.config.device=e.device||e.hostDevice,n.config.isEmbedded=e.isEmbedded||!1,e.isStatic&&(n.isStatic=e.isStatic),n._fixedWidthScaling=n.device.touchable&&!n.isStatic,n._fixedHeightScaling=n.device.touchable&&!n.isStatic;var r=document.createElement("div");n.config.styleSheetManager=e.styleSheetManager||new Fe(r);var s;if(e.keyboard)s=n.kbdLayout=e.keyboard.layout(e.device.formFactor),n.layoutKeyboardProperties=e.keyboardMetadata,n.isRTL=e.keyboard.isRTL;else{var B=ee.buildDefaultLayout(null,null,e.device.formFactor);s=n.kbdLayout=st.polyfill(B,null,e.device.formFactor),n.layoutKeyboardProperties=null,n.isRTL=!1}"font"in s?n.fontFamily=s.font:n.fontFamily="";var o=e.device.formFactor;n.layoutKeyboard=e.keyboard,n.layoutKeyboard||(n.layoutKeyboard=new w(null)),n.layerGroup=new Hc(n,n.layoutKeyboard,o),n.layoutKeyboard.markLayoutCalibrated(o),r.appendChild(n.layerGroup.element),n.kbdDiv=r,n.isStatic||(n.hostDevice.touchable?n.inputEngine=n.touchInputConfiguration:n.inputEngine=n.mouseInputConfiguration,n.inputEngine.registerEventHandlers()),r.classList.add(e.device.formFactor,"kmw-osk-inner-frame");var g=(l=(c=n.layoutKeyboard)===null||c===void 0?void 0:c.id.replace("Keyboard_",""))!==null&&l!==void 0?l:"",a=g.indexOf("::");a!=-1&&(g=g.substring(a+2));var F="kmw-keyboard-"+g;return n.element.classList.add(F),n}return Object.defineProperty(t.prototype,"layerId",{get:function(){return this._layerId},set:function(e){var n=e!=this._layerId;if(this.layerGroup.layers[e])this._layerId=e;else throw new Error("Keyboard ".concat(this.layoutKeyboard.id," does not have a layer with id ").concat(e));n&&(this.updateState(),this.refreshLayout())},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"currentLayer",{get:function(){var e;return this.layerId?(e=this.layerGroup)===null||e===void 0?void 0:e.layers[this.layerId]:null},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"lgKey",{get:function(){var e,n;return(n=(e=this.currentLayer)===null||e===void 0?void 0:e.globeKey)===null||n===void 0?void 0:n.btn},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"hkKey",{get:function(){var e,n;return(n=(e=this.currentLayer)===null||e===void 0?void 0:e.hideKey)===null||n===void 0?void 0:n.btn},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"spaceBar",{get:function(){var e,n;return(n=(e=this.currentLayer)===null||e===void 0?void 0:e.spaceBarKey)===null||n===void 0?void 0:n.btn},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"mouseInputConfiguration",{get:function(){var e={targetRoot:this.element,eventRoot:document.body,inputStartHandler:this.touch.bind(this),inputMoveHandler:this.moveOver.bind(this),inputMoveCancelHandler:this.moveCancel.bind(this),inputEndHandler:this.release.bind(this),coordConstrainedWithinInteractiveBounds:this.detectWithinInteractiveBounds.bind(this)};return new Qt(e)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"touchInputConfiguration",{get:function(){var e={targetRoot:this.element,eventRoot:this.element,inputStartHandler:this.touch.bind(this),inputMoveHandler:this.moveOver.bind(this),inputMoveCancelHandler:this.moveCancel.bind(this),inputEndHandler:this.release.bind(this),coordConstrainedWithinInteractiveBounds:this.detectWithinInteractiveBounds.bind(this)};return new Ct(e)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"element",{get:function(){return this.kbdDiv},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"device",{get:function(){return this.config.device},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"hostDevice",{get:function(){return this.config.hostDevice},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"fontRootPath",{get:function(){return this.config.pathConfig.fonts},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"styleSheetManager",{get:function(){return this.config.styleSheetManager},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"topContainer",{get:function(){return this.config.topContainer},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isEmbedded",{get:function(){return this.config.isEmbedded},enumerable:!1,configurable:!0}),t.prototype.postInsert=function(){},Object.defineProperty(t.prototype,"width",{get:function(){return this._width},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"height",{get:function(){return this._height},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"layoutWidth",{get:function(){if(this.usesFixedWidthScaling){var e=this.width,n=getComputedStyle(this.element);if(n.border){var c=new G(n.borderWidth).val;e-=c*2}return G.inPixels(e)}else return G.forScalar(1)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"layoutHeight",{get:function(){if(this.usesFixedHeightScaling){var e=this.height,n=getComputedStyle(this.element);if(n.border){var c=new G(n.borderWidth).val;e-=c*2}return G.inPixels(e)}else return G.forScalar(1)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"internalHeight",{get:function(){return this.usesFixedHeightScaling?G.inPixels(this.layoutHeight.val-this.getVerticalLayerGroupPadding()):G.forScalar(1)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"fontSize",{get:function(){return this._fontSize||(this._fontSize=new G("1em")),this._fontSize},set:function(e){this._fontSize=e,this.kbdDiv.style.fontSize=e.styleString},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"usesFixedWidthScaling",{get:function(){return this._fixedWidthScaling},set:function(e){this._fixedWidthScaling=e},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"usesFixedHeightScaling",{get:function(){return this._fixedHeightScaling},set:function(e){this._fixedHeightScaling=e},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"usesFixedPositioning",{get:function(){for(var e=this.element;e;){if(getComputedStyle(e).position=="fixed")return!0;e=e.offsetParent}return!1},enumerable:!1,configurable:!0}),t.prototype.setSize=function(e,n,c){this._width=e,this._height=n,this.kbdDiv&&(this.kbdDiv.style.width=e?this._width+"px":"",this.kbdDiv.style.height=n?this._height+"px":"",!this.device.touchable&&n&&(this.fontSize=new G(this._height/8+"px")),c||this.refreshLayout())},t.prototype.getDefaultKeyObject=function(){return new Rc(void 0,"",M.DEFAULT_KEY.width,M.DEFAULT_KEY.sp,null,M.DEFAULT_KEY.pad)},t.prototype.getTouchCoordinatesOnKeyboard=function(e){var n={x:v(this.kbdDiv),y:Z(this.kbdDiv)},c={x:e.x-n.x,y:e.y-n.y};return c.x/=this.layerGroup.element.offsetWidth,c.y/=this.kbdDiv.offsetHeight,c},t.prototype.getTouchProbabilities=function(e,n){var c=this.getTouchCoordinatesOnKeyboard(e),l=this.layerGroup.element,r=l.offsetWidth,s=this.kbdDiv.offsetHeight;if(!r||!s)return null;var B=l.offsetWidth/this.kbdDiv.offsetHeight,o=this.kbdLayout.getLayer(this.layerId).getTouchProbabilities(c,B);if(!n||!this.subkeyGesture||!this.subkeyGesture.baseKey.key)return o;var g=1,a=1,F=this.subkeyGesture.baseKey.key.spec.coreID,y=0,u=null;y=3,u=n.coreID,u==F?(a+=y,y=0):u="".concat(F,"::").concat(u);for(var Q=g+a+y,C=1/Q,h=0;h0&&U.push({keyId:u,p:y*C}),U.push({keyId:F,p:a*C}),U=U.concat(o),U},t.prototype.getInteractiveBoundingRect=function(){var e=v(this.element),n=Z(this.element),c=this.currentLayer.rows.length,l=.333*this.height/c,r={left:e-l,right:e+this.width+l,top:n-l,bottom:n+this.height+l};return r},t.prototype.applyScreenMarginBoundsThresholding=function(e,n){var c=window.screenLeft-window.pageXOffset,l=window.screenTop-window.pageYOffset,r=(0,d.__assign)({},e),s=new K(n.x+c,n.y+l);return s.x>=5&&e.left+c<=2&&(r.left=2-c),s.x<=screen.width-5&&e.right+c>=screen.width-2&&(r.right=screen.width-2-c),s.y>=5&&e.top+l<=2&&(r.top=2-l),s.y<=screen.height-5&&e.bottom+l>=screen.height-2&&(r.bottom=screen.height-2-l),r},t.prototype.detectWithinInteractiveBounds=function(e){if(e.x===null&&e.y===null)return!0;var n=this.getInteractiveBoundingRect(),c=n;return this.initTouchCoord&&this.applyScreenMarginBoundsThresholding(n,this.initTouchCoord),e.xc.right?!1:!(e.yc.bottom)},t.prototype.touch=function(e){var n=e.target,c=this.keyTarget(n);if(this.initTouchCoord=e,this.currentTarget=c,this.cancelDelete(),!(this.subkeyGesture&&this.subkeyGesture.isVisible())&&(this.touchCount=e.activeInputCount,(c&&(c.className.indexOf("key-hidden")>=0||c.className.indexOf("key-blank")>=0)||n.className.indexOf("kmw-key-row")>=0)&&(e.isFromMouse||(c=this.findNearestKey(e,n))),c!=null)){var l=c.keyId;if(this.highlightKey(c,!0),l=="K_LOPT"||l=="K_ROPT")window.setTimeout(function(){this.modelKeyClick(c),this.highlightKey(c,!0)}.bind(this),0),this.keyPending=null,this.touchPending=null;else if(l=="K_BKSP")this.modelKeyClick(c,e),this.deleteKey=c,this.deleting=window.setTimeout(this.repeatDelete,500),this.keyPending=null,this.touchPending=null;else{if(this.keyPending){if(this.highlightKey(this.keyPending,!1),this.subkeyGesture&&this.subkeyGesture instanceof je){var r=this.subkeyGesture;r.updateTouch(e),r.finalize(e)}else this.modelKeyClick(this.keyPending,this.touchPending);this.touchCount--}else this.initGestures(c,e);this.keyPending=c,this.touchPending=e}}},t.prototype.release=function(e){var n=this.currentTarget;if(this.cancelDelete(),this.pendingMultiTap&&this.pendingMultiTap.realized){this.pendingMultiTap=null,this.highlightKey(this.keyPending,!1),this.keyPending=null,this.touchPending=null;return}if(this.pendingMultiTap&&this.pendingMultiTap.cancelled&&(this.pendingMultiTap=null),this.subkeyGesture&&this.subkeyGesture.isVisible()){if(e.activeInputCount>0)return;if(this.subkeyGesture instanceof je){var c=this.subkeyGesture;c.finalize(e)}this.highlightKey(this.keyPending,!1),this.keyPending=null,this.touchPending=null;return}if(n&&n.id&&this.optionKey(n,n.id,!1),!this.detectWithinInteractiveBounds(e)){this.moveCancel(e),this.touchCount--;return}var l=this.touchCount;if(this.touchCount>0&&this.touchCount--,this.keyPending)this.highlightKey(this.keyPending,!1),this.keyPending.className.indexOf("hidden")<0&&l>0&&this.modelKeyClick(this.keyPending,e),this.clearPopup(),this.keyPending=null,this.touchPending=null;else{var r=e;if(n=this.keyTarget(r.target),!n){var s=document.elementFromPoint(e.x-window.pageXOffset,e.y-window.pageYOffset);n=this.findNearestKey(e,s)}this.highlightKey(n,!1)}},t.prototype.moveCancel=function(e){e.activeInputCount>1||this.updateGestures(null,this.keyPending,e)||(this.cancelDelete(),this.highlightKey(this.keyPending,!1),this.showKeyTip(null,!1),this.clearPopup(),this.keyPending=null,this.touchPending=null)},t.prototype.moveOver=function(e){if(this.touchCount==0){this.cancelDelete();return}var n=e.x-window.pageXOffset,c=e.y-window.pageYOffset;this.touchPending=e;var l=document.elementFromPoint(n,c),r=this.keyPending,s=this.keyTarget(l);(s&&s.className.indexOf("key-hidden")>=0||l&&!s&&l.className.indexOf("key-row")>=0)&&(s=this.findNearestKey(e,l)),s&&typeof s.id=="string"&&s.id.indexOf("-K_BKSP")<0&&this.cancelDelete(),!(e.activeInputCount>1)&&(this.updateGestures(s,r,e)||(this.currentTarget=s,s&&this.keyPending&&(this.highlightKey(r,!1),this.keyPending=s,this.touchPending=e),r&&s&&s!=r&&s.id!=""&&(this.clearPopup(),this.initGestures(s,e)),this.keyPending&&(r!=s||s.className.indexOf(Qe.HIGHLIGHT_CLASS)<0)&&this.highlightKey(s,!0)))},t.prototype.keyTarget=function(e){var n=e;try{if(n){if(n.classList.contains("kmw-key"))return Gt(n);if(n.parentNode&&n.parentNode.classList.contains("kmw-key"))return Gt(n.parentNode);if(n.firstChild&&n.firstChild.classList.contains("kmw-key"))return Gt(n.firstChild)}}catch(c){}return null},t.prototype.findNearestKey=function(e,n){if(!e)return null;for(var c=e.x;n&&n.className!==void 0&&n.className.indexOf("key-row")<0;)n=n.parentNode;if(!n)return null;var l,r=0,s,B=24,o=1e5,g,a;for(l=0;l=0||y.className.indexOf("key-blank")>=0))){if(g=F.offsetLeft,a=g+F.offsetWidth,c>=g&&c<=a)return y;s=g-c,s>=0&&s=0&&s40&&(B=.6*n.offsetWidth),g-c>=0&&g-c=0&&c-a=0)){var c=this.keytip!=null&&e.key.allowsKeyTip();c?this.showKeyTip(e,n):(this.showKeyTip(null,!1),e.key.highlight(n))}},t.prototype.getKeyEmFontSize=function(){if(!this.fontSize)return 0;if(this.device.formFactor=="desktop"){var e=.8;return this.fontSize.scaledBy(e).val}else{var n=getComputedStyle(document.body).fontSize,c=Se(n).val,l=1;if(!this.isStatic){if(this.fontSize.absolute)return this.fontSize.val;l=this.fontSize.val}return c*l}},t.prototype.updateState=function(){if(!!this.currentLayer){var e,n=this.kbdDiv.childNodes[0].childNodes;for(this.nextLayer=this.layerId,this.currentLayer.nextlayer&&(this.nextLayer=this.currentLayer.nextlayer),e=0;ec&&(c=o)}var g=0,a=c+g;return a},t.prototype.appendStyleSheet=function(){var e=this,n=this.layoutKeyboard,c=this.layoutKeyboardProperties;if(c!=null){this.styleSheet&&this.styleSheet.parentNode&&this.styleSheet.parentNode.removeChild(this.styleSheet);var l=c.textFont,r=c.oskFont;this.styleSheetManager.addStyleSheetForFont(l,this.fontRootPath,this.device.OS),this.styleSheetManager.addStyleSheetForFont(r,this.fontRootPath,this.device.OS);var s=this.addFontStyle(l,r);n!=null&&typeof n.oskStyling=="string"&&(s=s+n.oskStyling),this.styleSheet=Ve(s),this.styleSheet.addEventListener("load",function(){e.refreshLayout()}),this.styleSheetManager.linkStylesheet(this.styleSheet)}},t.prototype.addFontStyle=function(e,n){var c="",l=function(r){return r.family.replace(/\u0022/g,"").replace(/,/g,'","')};return(e||n)&&(c='\n.kmw-key-text {\n font-family: "'.concat(l(n||e),'";\n}\n\n.kmw-suggestion-text {\n font-family: "').concat(l(e||n),'";\n}\n')),c},t.buildDocumentationKeyboard=function(e,n,c,l,r,s){if(!e)return null;var B=typeof l=="undefined"?"desktop":l,o=typeof r=="undefined"?"default":r,g={};g.formFactor=B,B!="desktop"?(g.OS=x.OperatingSystem.iOS,g.touchable=!0):(g.OS=x.OperatingSystem.Windows,g.touchable=!1);var a=e.layout(B),F=new x("other",g.formFactor,g.OS,g.touchable),y=new t({keyboard:e,keyboardMetadata:n,hostDevice:F,isStatic:!0,topContainer:null,pathConfig:{fonts:c,resources:""},styleSheetManager:null});y.layerGroup.element.className=y.kbdDiv.className,y.layerGroup.element.classList.add(g.formFactor+"-static");var u=y.kbdDiv.childNodes[0],Q=document.createElement("div");Q.classList.add(g.OS.toLowerCase(),g.formFactor),a!=null?(y.layerId=o,y.setSize(800,s),y.fontSize=vc(F,s,!1),y.refreshLayout(),u.style.fontSize=y.kbdDiv.style.fontSize,u.style.height=y.kbdDiv.style.height,u.style.maxHeight=y.kbdDiv.style.maxHeight):u.innerHTML="

No "+B+" layout is defined for "+e.name+".

",u.style.border="1px solid #ccc";var C=function(){if(document.contains(u))try{getComputedStyle(u)&&u.style.fontSize&&(y.fontSize=new G(u.style.fontSize)),y.appendStyleSheet();var b=y.styleSheet,U=b.parentElement;y.refreshLayout(),u.style.fontSize=y.kbdDiv.style.fontSize,y.shutdown(),u.appendChild(b)}finally{h.disconnect()}},h=new MutationObserver(C);return h.observe(document.body,{childList:!0,subtree:!0}),Q.append(u),Q},t.prototype.onHide=function(){this.hkKey&&this.highlightKey(this.hkKey,!1)},t.prototype.startLongpress=function(e){var n=this,c=new Qn(this,e);return c.promise.then(function(l){l&&(n.topContainer.appendChild(l.element),n.topContainer.appendChild(l.shim),l.reposition(n))}),c},t.prototype.initGestures=function(e,n){var c=this;if(this.pendingMultiTap)switch(this.pendingMultiTap.incrementTouch(e)){case te.Cancelled:this.pendingMultiTap=null;break;case te.Realized:return}if(!this.pendingMultiTap&&In.isValidTarget(this,e)&&(this.pendingMultiTap=new In(this,e,2),this.pendingMultiTap.timeout.then(function(){c.pendingMultiTap=null})),e.subKeys){var l=this,r=this.startLongpress(e);if(r==null)return;this.pendingSubkey=r,r.promise.then(function(s){l.pendingSubkey==r&&(l.pendingSubkey=null),s&&(l.showKeyTip(null,!1),l.subkeyGesture=s,s.promise.then(function(B){B&&l.raiseKeyEvent(B,null),l.clearPopup()}))})}},t.prototype.updateGestures=function(e,n,c){var l=n,r=e;return!e&&this.pendingMultiTap&&(this.pendingMultiTap.cancel(),this.pendingMultiTap=null),this.subkeyGesture?(l&&l.key.highlight(!1),this.subkeyGesture.updateTouch(c),this.keyPending=null,this.touchPending=null,!0):(this.currentTarget=null,r&&r.subKeys!=null&&this.initTouchCoord&&this.pendingSubkey&&this.pendingSubkey instanceof Qn&&this.initTouchCoord.y-c.y>this.getLongpressFlickThreshold()&&this.pendingSubkey.resolve(),!!(this.subkeyGesture||this.pendingSubkey))},t.prototype.getLongpressFlickThreshold=function(){var e=this.currentLayer.rowHeight,n=e/4;return Math.max(n,5)},t.prototype.optionKey=function(e,n,c){n.indexOf("K_LOPT")>=0?this.emit("globekey",e,c):n.indexOf("K_ROPT")>=0&&c&&this.emit("hiderequested",e)},t.prototype.showKeyTip=function(e,n){var c=this.keytip;if(c!=null){var l=this.subkeyGesture,r=l&&l.isVisible();n=r?!1:n,c.show(e,n,this)}},t.prototype.createKeyTip=function(){if(this.device.formFactor=="phone"&&this.keytip==null){var e=this.isEmbedded;this.keytip=new Nc(e)}this.keytip&&this.keytip.element&&this.topContainer.appendChild(this.keytip.element)},t.prototype.createGlobeHint=function(){return this.config.embeddedGestureConfig.createGlobeHint?this.config.embeddedGestureConfig.createGlobeHint(this):null},t.prototype.shutdown=function(){var e,n,c,l;this.styleSheet&&this.styleSheet.parentNode&&this.styleSheet.parentNode.removeChild(this.styleSheet),this.inputEngine&&this.inputEngine.unregisterEventHandlers(),this.deleting&&window.clearTimeout(this.deleting),this.keyPending=null,this.touchPending=null,(e=this.keytip)===null||e===void 0||e.show(null,!1,this),(n=this.subkeyGesture)===null||n===void 0||n.clear(),(c=this.pendingMultiTap)===null||c===void 0||c.cancel(),(l=this.pendingSubkey)===null||l===void 0||l.cancel()},t.prototype.raiseKeyEvent=function(e,n){if(e.kName=="K_LOPT"||e.kName=="K_ROPT")return this.optionKey(n,e.kName,!0),!0;this.emit("keyevent",e)},t.specialCharacters=Qe.specialCharacters,t}(Tc.default),Ce=Tl;var Ec=J(R(),1),kc=function(i){(0,d.__extends)(t,i);function t(){return i!==null&&i.apply(this,arguments)||this}return t}(Ec.default),qe=kc,$e=function(i){(0,d.__extends)(t,i);function t(){return i!==null&&i.apply(this,arguments)||this}return Object.defineProperty(t.prototype,"enabled",{get:function(){return!0},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"activate",{get:function(){return!0},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"conditionsMet",{get:function(){return!0},enumerable:!1,configurable:!0}),t}(kc);var El=function(){function i(){this.map={}}return i.prototype.promiseForTouchpoint=function(t){return this.map[t]||(this.map[t]=new A),this.map[t]},i.prototype.maintainTouches=function(t){for(var e=Object.keys(this.map),n=0;n0&&(g-=this.bannerView.height+5),this.vkbd.setSize(this.computedWidth,g,e);var a=this._Box.style;a.width=a.maxWidth=this.computedWidth+"px",a.height=a.maxHeight=this.computedHeight+"px",this.vkbd.showLanguage()}else{var a=this._Box.style;a.width="auto",a.height="auto",a.maxWidth=a.maxHeight=""}}}},t.prototype.refreshLayoutIfNeeded=function(e){this.needsLayout&&this.refreshLayout(e)},t.prototype.postKeyboardLoad=function(){this._Visible=!1,this.postKeyboardAdjustments(),this.displayIfActive&&this.present()},t.prototype.loadActiveKeyboard=function(){var e,n,c,l;this.setBoxStyling(),this.vkbd&&this.vkbd.shutdown(),this.keyboardView=null,this.needsLayout=!0,this._Box.innerHTML="";var r="osk/";this.config.isEmbedded&&(r="");for(var s=0,B=t.STYLESHEET_FILES;s=0)){if(this._Box){var e=this._Box.style;e.display="none",e.transition="",e.opacity="1",this._Visible=!1}this.vkbd&&this.vkbd.onHide()}},t.prototype.mayShow=function(){return!(!this.activationModel.conditionsMet||!this.keyboardView||this.keyboardView instanceof ht||!this.activationModel.enabled||!this._Box)},t.prototype.mayHide=function(e){return!(this.activationModel.conditionsMet&&!this.mayDisable||this.activationModel instanceof $e||!e&&this.hostDevice.formFactor=="desktop"&&document.body.className.indexOf("osk-always-visible")>=0)},t.prototype.useHideAnimation=function(){var e=this._Box.style,n=this;return new Promise(function(c){var l=function(){return n._Box.removeEventListener("transitionend",l,!1),n._Box.removeEventListener("webkitTransitionEnd",l,!1),n._Box.removeEventListener("transitioncancel",l,!1),n._Box.removeEventListener("webkitTransitionCancel",l,!1),n._animatedHideTimeout!=0&&window.clearTimeout(n._animatedHideTimeout),n._animatedHideTimeout=0,n._Visible&&n.activationModel.conditionsMet?(e.transition="",e.opacity="1",c(!1),!1):(c(!0),!0)},r=function(){n._Box.removeEventListener("transitionrun",r,!1),n._Box.removeEventListener("webkitTransitionRun",r,!1),n._Box.addEventListener("transitionend",l,!1),n._Box.addEventListener("webkitTransitionEnd",l,!1),n._Box.addEventListener("transitioncancel",l,!1),n._Box.addEventListener("webkitTransitionCancel",l,!1)};n._Box.addEventListener("transitionrun",r,!1),n._Box.addEventListener("webkitTransitionRun",r,!1),e.transition="opacity 0.5s linear 0",e.opacity="0",n._animatedHideTimeout=window.setTimeout(l,200)})},t.prototype.hideNow=function(){if(!(!this.mayHide(!1)||!this._Box)){this._animatedHideTimeout&&(window.clearTimeout(this._animatedHideTimeout),this._animatedHideTimeout=0);var e=this._Box.style;e.transition="",e.opacity="0",this.finalizeHide()}},t.prototype.shutdown=function(){this.removeBaseMouseEventListeners(),this.removeBaseTouchEventListeners();var e=this._Box;e.parentElement&&e.parentElement.removeChild(e),this.kbdStyleSheetManager.unlinkAll(),this.uiStyleSheetManager.unlinkAll()},t.prototype.getRect=function(){var e={};return e.left=e.left=v(this._Box),e.top=e.top=Z(this._Box),e.width=this.computedWidth,e.height=this.computedHeight,e},t.prototype.isEnabled=function(){return this.displayIfActive},t.prototype.isVisible=function(){return this._Visible},t.prototype.hide=function(){this.activationModel.enabled=!1,this.startHide(!0)},t.prototype.show=function(e){arguments.length>0?this.activationModel.enabled=e:this.activationModel.conditionsMet&&(this.activationModel.enabled=!this.activationModel.enabled)},t.prototype.doShow=function(e){this.legacyEvents.callEvent("show",e)},t.prototype.doHide=function(e){var n={HiddenByUser:e};this.legacyEvents.callEvent("hide",n)},t.prototype.addEventListener=function(e,n){this.legacyEvents.addEventListener(e,n)},t.prototype.removeEventListener=function(e,n){this.legacyEvents.removeEventListener(e,n)},t.STYLESHEET_FILES=["kmwosk.css","globe-hint.css"],t}(wc.default),Je=kl;var Oc=J(R(),1);var Yl=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this)||this;return n.mouseCancellingHandler=function(c){return c.preventDefault(),c.cancelBubble=!0,!1},n._element=n.buildTitleBar(),n.helpEnabled=!1,n.configEnabled=!1,e&&(n.element.onmousedown=e.mouseDownHandler),n}return Object.defineProperty(t.prototype,"helpEnabled",{get:function(){return this._helpEnabled},set:function(e){this._helpEnabled=e,this._helpButton.style.display=e?"inline":"none"},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"configEnabled",{get:function(){return this._configEnabled},set:function(e){this._configEnabled=e,this._configButton.style.display=e?"inline":"none"},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"layoutHeight",{get:function(){return t.DISPLAY_HEIGHT},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"element",{get:function(){return this._element},enumerable:!1,configurable:!0}),t.prototype.setPinCJKOffset=function(){this._unpinButton.style.left="15px"},t.prototype.showPin=function(e){this._unpinButton.style.display=e?"block":"none"},t.prototype.setTitle=function(e){this._caption.innerHTML=e},t.prototype.setTitleFromKeyboard=function(e){var n=""+(e==null?void 0:e.name)+"";this._caption.innerHTML=n},t.prototype.buildTitleBar=function(){var e=this,n=m("div");n.id="keymanweb_title_bar",n.className="kmw-title-bar";var c=this._caption=m("span");c.className="kmw-title-bar-caption",c.style.color="#fff",n.appendChild(c);var l=this._closeButton=this.buildCloseButton();return this._closeButton.onclick=function(){return e.emit("close"),!1},n.appendChild(l),l=this._helpButton=this.buildHelpButton(),this._helpButton.onclick=function(){return e.emit("help"),!1},n.appendChild(l),l=this._configButton=this.buildConfigButton(),this._configButton.onclick=function(){return e.emit("config"),!1},n.appendChild(l),l=this._unpinButton=this.buildUnpinButton(),this._unpinButton.onclick=function(){return e.emit("unpin"),!1},n.appendChild(l),n},t.prototype.buildCloseButton=function(){var e=m("div");return e.id="kmw-close-button",e.className="kmw-title-bar-image",e.onmousedown=this.mouseCancellingHandler,e},t.prototype.buildHelpButton=function(){var e=m("div");return e.id="kmw-help-image",e.className="kmw-title-bar-image",e.title="KeymanWeb Help",e.onmousedown=this.mouseCancellingHandler,e},t.prototype.buildConfigButton=function(){var e=m("div");return e.id="kmw-config-image",e.className="kmw-title-bar-image",e.title="KeymanWeb Configuration Options",e.onmousedown=this.mouseCancellingHandler,e},t.prototype.buildUnpinButton=function(){var e=m("div");return e.id="kmw-pin-image",e.className="kmw-title-bar-image",e.title="Pin the On Screen Keyboard to its default location on the active text box",e.onmousedown=this.mouseCancellingHandler,e},t.prototype.refreshLayout=function(){},t.DISPLAY_HEIGHT=G.inPixels(20),t}(Oc.default),Cn=Yl;var Dc=J(R(),1);var wl=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this)||this;return n.mouseCancellingHandler=function(c){return c.preventDefault(),c.cancelBubble=!0,!1},n._element=n.buildResizeBar(),e&&(n._resizeHandle.onmousedown=e.mouseDownHandler),n}return Object.defineProperty(t.prototype,"layoutHeight",{get:function(){return t.DISPLAY_HEIGHT},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"element",{get:function(){return this._element},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"handle",{get:function(){return this._resizeHandle},enumerable:!1,configurable:!0}),t.prototype.allowResizing=function(e){this._resizeHandle.style.display=e?"block":"none"},t.prototype.buildResizeBar=function(){var e=this,n=m("div");n.className="kmw-footer",n.onmousedown=this.mouseCancellingHandler;var c=m("div");c.className="kmw-footer-caption",c.innerHTML='KeymanWeb',c.id="keymanweb-osk-footer-caption",c.addEventListener("dblclick",function(r){return e.emit("showbuild"),!1},!1),n.appendChild(c);var l=m("div");return l.className="kmw-footer-resize",n.appendChild(l),this._resizeHandle=l,n},t.prototype.refreshLayout=function(){},t.DISPLAY_HEIGHT=G.inPixels(16),t}(Dc.default),Mc=wl;var Ol=function(){function i(t){this._VPreviousMouseMove=document.onmousemove,this._VPreviousMouseUp=document.onmouseup,this._VPreviousCursor=document.body.style.cursor,this._VPreviousMouseButton=typeof t.which=="undefined"?t.button:t.which}return i.prototype.restore=function(){document.onmousemove=this._VPreviousMouseMove,document.onmouseup=this._VPreviousMouseUp,document.body.style.cursor&&(document.body.style.cursor=this._VPreviousCursor)},i.prototype.matchesCausingClick=function(t){return this._VPreviousMouseButton==(typeof t.which=="undefined"?t.button:t.which)},i}(),Dl=function(){function i(t){this.startHandler=this._VMoveMouseDown.bind(this),this.cursorType=t}return Object.defineProperty(i.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this._enabled=t},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"isActive",{get:function(){return!!this._mouseStartSnapshot},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"mouseDownHandler",{get:function(){return this.startHandler},enumerable:!1,configurable:!0}),i.prototype._VMoveMouseDown=function(t){return!t||!this._enabled?!0:(this._mouseStartSnapshot||(this._mouseStartSnapshot=new Ol(t)),this._startCoord=K.fromEvent(t),document.onmousemove=this._VMoveMouseMove.bind(this),document.onmouseup=this._VMoveMouseUp.bind(this),document.body.style.cursor&&(document.body.style.cursor=this.cursorType),t.preventDefault(),t.cancelBubble=!0,this.onDragStart(),!1)},i.prototype._VMoveMouseMove=function(t){if(!t||!this.enabled)return!0;if(t.preventDefault(),t.cancelBubble=!0,this._mouseStartSnapshot.matchesCausingClick(t)){var e=K.fromEvent(t),n=e.x-this._startCoord.x,c=e.y-this._startCoord.y;return this.onDragMove(n,c),!1}else return this._VMoveMouseUp(t)},i.prototype._VMoveMouseUp=function(t){return t?(this._mouseStartSnapshot.restore(),this._mouseStartSnapshot=null,t.preventDefault(),t.cancelBubble=!0,this.onDragRelease(),!1):!0},i}(),bn=Dl;var Ml=function(i){(0,d.__extends)(t,i);function t(){var e=i!==null&&i.apply(this,arguments)||this;return e._enabled=!0,e.actValue=null,e}return Object.defineProperty(t.prototype,"activate",{get:function(){return this._enabled&&!!this.actValue},enumerable:!1,configurable:!0}),t.prototype.checkState=function(e){this.activate!=e&&this.emit("activate",this.activate)},Object.defineProperty(t.prototype,"enabled",{get:function(){return this._enabled},set:function(e){var n=this.activate;this._enabled=e,this.checkState(n)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"activationTrigger",{get:function(){return this.actValue},set:function(e){var n=this.activate,c=this.actValue;this.actValue=e,this.checkState(n),c!=e&&this.emit("triggerchange",e)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"conditionsMet",{get:function(){return!!this.activationTrigger},enumerable:!1,configurable:!0}),t}(qe),et=Ml;var zc=function(i){(0,d.__extends)(t,i);function t(){return i.call(this,"KeymanWeb_OnScreenKeyboard")||this}return t.prototype.loadWithDefaults=function(e){return(0,d.__assign)((0,d.__assign)({},e),this.load())},t.prototype.load=function(){var e=i.prototype.load.call(this,function(n,c){switch(c){case"version":return n;default:return Number.parseInt(n,10)}});return e.width||delete e.width,e.height||delete e.height,e},t.prototype.save=function(e){i.prototype.save.call(this,e)},t}(se);var zl=function(i){(0,d.__extends)(t,i);function t(e){var n=this;e.activator=e.activator||new et,n=i.call(this,e)||this,n.userPositioned=!1,n.specifiedPosition=!1,n.noDrag=!1,n.layoutSerializer=new zc,n.restorePosition=function(g){var a=this._Visible,F=new A;this.emit("dragmove",F.corePromise),this.loadPersistedLayout(),this.userPositioned=!1,g||(delete this.dfltX,delete this.dfltY),this.savePersistedLayout(),a&&this.present(),this.titleBar.showPin(!1),F.resolve(),this.doResizeMove()}.bind(n),n.typedActivationModel.on("triggerchange",function(){return n.setDisplayPositioning()}),document.body.appendChild(n._Box),n.titleBar=new Cn(n.titleDragHandler),n.titleBar.on("help",function(){n.legacyEvents.callEvent("helpclick",{})}),n.titleBar.on("config",function(){n.legacyEvents.callEvent("configclick",{})}),n.titleBar.on("close",function(){return n.startHide(!0)}),n.titleBar.on("unpin",function(){return n.restorePosition(!0)}),n.resizeBar=new Mc(n.resizeDragHandler),n.resizeBar.on("showbuild",function(){return n.emit("showbuild")}),n.headerView=n.titleBar;for(var c=function(g){var a=n.headerView;if(a&&a instanceof Cn)switch(g){case"configclick":a.configEnabled=n.legacyEvents.listenerCount("configclick")>0;break;case"helpclick":a.helpEnabled=n.legacyEvents.listenerCount("helpclick")>0;break;default:return}},l=new yt(n),r=new yt(n.legacyEvents),s=0,B=[l,r];s.9*screen.width&&(l=.9*screen.width),r>.5*screen.height&&(r=.5*screen.height),(c||!n)&&(this.headerView&&this.headerView.layoutHeight.absolute&&(r+=this.headerView.layoutHeight.val),this.footerView&&this.footerView.layoutHeight.absolute&&(r+=this.footerView.layoutHeight.val)),this.setSize(l,r),(this.x==-1||this.y==-1||!this._Box)&&(this.userPositioned=!1),this.x.9*screen.width&&(s=.9*screen.width),r.width=s+"px",this.setSize(s,this.computedHeight,!0)}if("height"in e){var B=e.height-(n.offsetHeight-l.offsetHeight);B<.1*screen.height&&(B=.1*screen.height),B>.5*screen.height&&(B=.5*screen.height),r.height=B+"px",r.fontSize=B/8+"px",this.setSize(this.computedWidth,B,!0)}"nosize"in e&&(this.resizingEnabled=!e.nosize)}"nomove"in e&&(this.noDrag=e.nomove,this.movementEnabled=!this.noDrag),this.savePersistedLayout()}},t.prototype.getPos=function(){var e=this._Box,n={left:this._Visible?e.offsetLeft:this.x,top:this._Visible?e.offsetTop:this.y};return n},t.prototype.setPos=function(e){if(typeof this._Box!="undefined"){if(this.userPositioned){var n=e.left,c=e.top;typeof n!="undefined"&&(n<-.8*this._Box.offsetWidth&&(n=-.8*this._Box.offsetWidth),this.userPositioned&&(this._Box.style.left=n+"px",this.x=n)),typeof c!="undefined"&&(c<0&&(c=0),this.userPositioned&&(this._Box.style.top=c+"px",this.y=c))}this.titleBar.showPin(this.userPositioned)}},t.prototype.setDisplayPositioning=function(){var e=this._Box.style;if(e.position="absolute",this.activationModel.activate&&(e.display="block"),e.left="0px",this.specifiedPosition||this.userPositioned)e.left=this.x+"px",e.top=this.y+"px";else{var n=this.typedActivationModel.activationTrigger||null;this.dfltX?e.left=this.dfltX:typeof n!="undefined"&&n!=null&&(e.left=v(n)+"px"),this.dfltY?e.top=this.dfltY:typeof n!="undefined"&&n!=null&&(e.top=Z(n)+n.offsetHeight+"px")}this.specifiedPosition=!1},t.prototype.presentAtPosition=function(e,n){!this.mayShow()||(this.specifiedPosition=e>=0||n>=0,this.specifiedPosition&&(this.x=e,this.y=n),this.specifiedPosition=this.specifiedPosition||this.userPositioned,this.present())},t.prototype.present=function(){if(!!this.mayShow()){this.titleBar.showPin(this.userPositioned),i.prototype.present.call(this);var e={};e.x=this._Box.offsetLeft,e.y=this._Box.offsetTop,e.userLocated=this.userPositioned,this.doShow(e)}},t.prototype.startHide=function(e){i.prototype.startHide.call(this,e),e&&this.savePersistedLayout()},t.prototype.show=function(e){e!==void 0?i.prototype.show.call(this,e):i.prototype.show.call(this),this.savePersistedLayout()},t.prototype.userLocated=function(){return this.userPositioned},Object.defineProperty(t.prototype,"movementEnabled",{get:function(){return this.titleDragHandler.enabled},set:function(e){this.titleDragHandler.enabled=e,this.titleBar.showPin(e&&this.userPositioned)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"resizingEnabled",{get:function(){return this.resizeDragHandler.enabled},set:function(e){this.resizeDragHandler.enabled=e,this.resizeBar.allowResizing(e)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isBeingMoved",{get:function(){return this.titleDragHandler.isActive},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isBeingResized",{get:function(){return this.resizeDragHandler.isActive},enumerable:!1,configurable:!0}),t.prototype.enableMoveResizeHandlers=function(){this.titleDragHandler.enabled=!this.noDrag,this.resizeDragHandler.enabled=!0},Object.defineProperty(t.prototype,"titleDragHandler",{get:function(){var e=this;return this._moveHandler?this._moveHandler:(this._moveHandler=new(function(n){(0,d.__extends)(c,n);function c(){return n.call(this,"move")||this}return c.prototype.onDragStart=function(){this.startX=e._Box.offsetLeft,this.startY=e._Box.offsetTop,e.activeKeyboard.keyboard.isCJK&&e.titleBar.setPinCJKOffset(),this.dragPromise&&this.dragPromise.resolve(),this.dragPromise=new A,e.emit("dragmove",this.dragPromise.corePromise)},c.prototype.onDragMove=function(l,r){e.titleBar.showPin(!0),e.userPositioned=!0,e._Box.style.left=this.startX+l+"px",e._Box.style.top=this.startY+r+"px";var s=e.getRect();e.setSize(s.width,s.height,!0),e.x=s.left,e.y=s.top},c.prototype.onDragRelease=function(){e.vkbd&&(e.vkbd.currentKey=null),this.dragPromise.resolve(),this.dragPromise.then(function(){e.userPositioned=!0,e.doResizeMove(),e.savePersistedLayout()}),this.dragPromise=null},c}(bn)),this._moveHandler)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"resizeDragHandler",{get:function(){var e=this;return this._resizeHandler?this._resizeHandler:(this._resizeHandler=new(function(n){(0,d.__extends)(c,n);function c(){return n.call(this,"se-resize")||this}return c.prototype.onDragStart=function(){this.startWidth=e.computedWidth,this.startHeight=e.computedHeight,this.dragPromise&&this.dragPromise.resolve(),this.dragPromise=new A,e.emit("resizemove",this.dragPromise.corePromise)},c.prototype.onDragMove=function(l,r){var s=this.startWidth+l,B=this.startHeight+r;s<.2*screen.width&&(s=.2*screen.width),B<.1*screen.height&&(B=.1*screen.height),s>.9*screen.width&&(s=.9*screen.width),B>.5*screen.height&&(B=.5*screen.height),e.setSize(s,B,!0)},c.prototype.onDragRelease=function(){e.vkbd&&(e.vkbd.currentKey=null),e.vkbd&&(this.startWidth=e.computedWidth,this.startHeight=e.computedHeight),e.refreshLayout(),this.dragPromise.resolve(),this.dragPromise.then(function(){e.doResizeMove(),e.savePersistedLayout()}),this.dragPromise=null},c}(bn)),this._resizeHandler)},enumerable:!1,configurable:!0}),t}(Je),We=zl;var Kl=function(i){(0,d.__extends)(t,i);function t(e){var n=this;return e.isEmbedded?e.activator=e.activator||new $e:e.activator=e.activator||new et,n=i.call(this,e)||this,n.isResizing=!1,n.restorePosition=function(c){}.bind(n),document.body.appendChild(n._Box),n}return t.prototype._Unload=function(){this.keyboardView=null,this.bannerView=null,this._Box=null},t.prototype.setBoxStyling=function(){var e=this._Box.style;e.zIndex="9999",e.display="none",e.width="100%",e.position="fixed"},t.prototype.refreshLayout=function(e){if(!this.isResizing){try{this.isResizing=!0,this.doResize()}finally{this.isResizing=!1}i.prototype.refreshLayout.call(this,e)}},t.prototype.doResize=function(){if(this.vkbd){var e=this.getDefaultKeyboardHeight();this.setSize(this.getDefaultWidth(),e+this.banner.height)}},t.prototype.postKeyboardAdjustments=function(){this.doResize()},t.prototype.getDefaultKeyboardHeight=function(){var e,n,c=this.targetDevice;if(this.configuration.heightOverride)return this.configuration.heightOverride();var l=(e=document==null?void 0:document.documentElement)===null||e===void 0?void 0:e.clientWidth,r=(n=document==null?void 0:document.documentElement)===null||n===void 0?void 0:n.clientHeight;if(typeof l=="undefined"&&(l=Math.min(screen.height,screen.width),r=Math.max(screen.height,screen.width),D())){var s=l;l=r,r=s}var B=Math.floor(Math.min(r,l)/2),o=B;return c.formFactor=="phone"&&(D()?o=Math.floor(r/1.6):o=Math.floor(r/2.4)),this.targetDevice.OS==x.OperatingSystem.iOS&&(o=o/He()),o},t.prototype.getDefaultWidth=function(){var e,n=this.targetDevice;if(this.configuration.widthOverride)return this.configuration.widthOverride();var c;return c=(e=document==null?void 0:document.documentElement)===null||e===void 0?void 0:e.clientWidth,typeof c=="undefined"&&(this.targetDevice.OS==x.OperatingSystem.iOS?c=window.innerWidth:n.OS==x.OperatingSystem.Android?c=screen.availWidth:c=screen.width),c},t.prototype.setRect=function(e){},t.prototype.getPos=function(){var e=this._Box,n={left:this._Visible?e.offsetLeft:this.x,top:this._Visible?e.offsetTop:this.y};return n},t.prototype.setPos=function(e){},t.prototype.setDisplayPositioning=function(){var e=this._Box.style;this.vkbd&&(e.position="fixed",e.left=e.bottom="0px",e.border="none",e.borderTop="1px solid gray")},t.prototype.present=function(){i.prototype.present.call(this),this.legacyEvents.callEvent("show",{})},t}(Je),hn=Kl;var _l=function(i){(0,d.__extends)(t,i);function t(){var e=i!==null&&i.apply(this,arguments)||this;return e.flag=!0,e}return Object.defineProperty(t.prototype,"enabled",{get:function(){return this.flag},set:function(e){this.activate=e},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"activate",{get:function(){return this.flag},set:function(e){this.flag!=e&&(this.flag=e,this.emit("activate",e))},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"conditionsMet",{get:function(){return!0},enumerable:!1,configurable:!0}),t}(qe),Un=_l;var Pl=function(i){(0,d.__extends)(t,i);function t(e){var n=this;return e.activator=e.activator||new Un,n=i.call(this,e)||this,n.restorePosition=function(c){}.bind(n),n}return Object.defineProperty(t.prototype,"element",{get:function(){return this._Box},enumerable:!1,configurable:!0}),t.prototype._Unload=function(){this.keyboardView=null,this.bannerView=null,this._Box=null},t.prototype.setBoxStyling=function(){var e=this._Box.style;e.display="none",e.position="relative"},t.prototype.postKeyboardAdjustments=function(){},t.prototype.getDefaultKeyboardHeight=function(){return this.keyboardView instanceof Ce?this.keyboardView.height:this.computedHeight},t.prototype.getDefaultWidth=function(){return this.computedWidth},t.prototype.setRect=function(e){},t.prototype.getPos=function(){var e=this._Box,n={left:this._Visible?e.offsetLeft:void 0,top:this._Visible?e.offsetTop:void 0};return n},t.prototype.setPos=function(e){},t.prototype.present=function(){i.prototype.present.call(this),this.legacyEvents.callEvent("show",{})},t.prototype.setDisplayPositioning=function(){},t.prototype.allowsDeviceChange=function(e){return!0},t}(Je),xn=Pl;var pn={};kn(pn,{AnchoredOSKView:function(){return Gn},FloatingOSKView:function(){return Xn},InlinedOSKView:function(){return jl}});function Vn(i){return{hostDevice:i.config.hostDevice,pathConfig:i.config.paths,predictionContextManager:i.contextManager.predictionContext,isEmbedded:!1}}var Gn=function(i){(0,d.__extends)(t,i);function t(e,n){var c=(0,d.__assign)((0,d.__assign)({},Vn(e)),n||{});return i.call(this,c)||this}return t}(hn),Xn=function(i){(0,d.__extends)(t,i);function t(e,n){var c=(0,d.__assign)((0,d.__assign)({},Vn(e)),n||{});return i.call(this,c)||this}return t}(We),jl=function(i){(0,d.__extends)(t,i);function t(e,n){var c=(0,d.__assign)((0,d.__assign)({},Vn(e)),n||{});return i.call(this,c)||this}return t}(xn);var Kc=J(R(),1),ql=function(i){(0,d.__extends)(t,i);function t(){var e=i!==null&&i.apply(this,arguments)||this;return e.events=new Kc.default,e.changed=!1,e}return t.prototype.focus=function(){var e=this.getElement();e.focus&&e.focus()},t.prototype.isForcingScroll=function(){return!1},t.prototype.dispatchInputEventOn=function(e){var n;window.InputEvent&&(n=new InputEvent("input",{bubbles:!0,cancelable:!1})),e&&n&&e.dispatchEvent(n)},t}(wt),_=ql;var $l=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this)||this;return n.root=e,n._cachedSelectionStart=-1,n}return Object.defineProperty(t.prototype,"isSynthetic",{get:function(){return!1},enumerable:!1,configurable:!0}),t.prototype.getElement=function(){return this.root},t.prototype.clearSelection=function(){this.getCaret(),this.root.value=this.root.value._kmwSubstring(0,this.processedSelectionStart)+this.root.value._kmwSubstring(this.processedSelectionEnd),this.setCaret(this.processedSelectionStart)},t.prototype.isSelectionEmpty=function(){return this.root.selectionStart==this.root.selectionEnd},t.prototype.hasSelection=function(){return!0},t.prototype.invalidateSelection=function(){this._cachedSelectionStart=-1},t.prototype.getCaret=function(){return this.root.selectionStart!=this._cachedSelectionStart&&(this._cachedSelectionStart=this.root.selectionStart,this.processedSelectionStart=this.root.value._kmwCodeUnitToCodePoint(this.root.selectionStart),this.processedSelectionEnd=this.root.value._kmwCodeUnitToCodePoint(this.root.selectionEnd)),this.root.selectionDirection=="forward"?this.processedSelectionEnd:this.processedSelectionStart},t.prototype.getDeadkeyCaret=function(){return this.getCaret()},t.prototype.setCaret=function(e){this.setSelection(e,e,"none")},t.prototype.setSelection=function(e,n,c){var l=this.root.value._kmwCodePointToCodeUnit(e),r=this.root.value._kmwCodePointToCodeUnit(n);this.root.setSelectionRange(l,r,c),this.processedSelectionStart=e,this.processedSelectionEnd=n,this.forceScroll(),this.root.setSelectionRange(l,r,c)},t.prototype.forceScroll=function(){var e=this.getElement(),n=e.selectionStart,c=e.selectionEnd;this._activeForcedScroll=!0;try{e.blur(),e.focus()}finally{e.selectionStart=n,e.selectionEnd=c,this._activeForcedScroll=!1}},t.prototype.isForcingScroll=function(){return this._activeForcedScroll},t.prototype.getSelectionDirection=function(){return this.root.selectionDirection},t.prototype.getTextBeforeCaret=function(){return this.getCaret(),this.getText()._kmwSubstring(0,this.processedSelectionStart)},t.prototype.getSelectedText=function(){return this.getCaret(),this.getText()._kmwSubstring(this.processedSelectionStart,this.processedSelectionEnd)},t.prototype.setTextBeforeCaret=function(e){this.getCaret();var n=this.processedSelectionEnd-this.processedSelectionStart,c=this.getSelectionDirection(),l=e._kmwLength();this.root.value=e+this.getText()._kmwSubstring(this.processedSelectionStart),this.setSelection(l,l+n,c)},t.prototype.setTextAfterCaret=function(e){var n=this.getCaret(),c=this.getSelectionDirection();this.root.value=this.getTextBeforeCaret()+e,this.setSelection(this.processedSelectionStart,this.processedSelectionEnd,c)},t.prototype.getTextAfterCaret=function(){return this.getCaret(),this.getText()._kmwSubstring(this.processedSelectionEnd)},t.prototype.getText=function(){return this.root.value},t.prototype.deleteCharsBeforeCaret=function(e){if(e>0){var n=this.getTextBeforeCaret(),c=this.processedSelectionStart;e>c&&(e=c),this.adjustDeadkeys(-e),this.setTextBeforeCaret(n.kmwSubstring(0,c-e)),this.setCaret(c-e)}},t.prototype.insertTextBeforeCaret=function(e){if(!!e){var n=this.getCaret(),c=this.getTextBeforeCaret(),l=this.getText()._kmwSubstring(this.processedSelectionStart);this.adjustDeadkeys(e._kmwLength()),this.root.value=c+e+l,this.setCaret(n+e._kmwLength())}},t.prototype.handleNewlineAtCaret=function(){var e=this.root;e&&(e.type=="search"||e.type=="submit")?(e.disabled=!1,e.form.submit()):this.events.emit("unhandlednewline",e)},t.prototype.doInputEvent=function(){this.dispatchInputEventOn(this.root)},t}(_),mn=$l;var er=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this)||this;return n.root=e,n._cachedSelectionStart=-1,n}return Object.defineProperty(t.prototype,"isSynthetic",{get:function(){return!1},enumerable:!1,configurable:!0}),t.prototype.getElement=function(){return this.root},t.prototype.clearSelection=function(){this.getCaret(),this.root.value=this.root.value._kmwSubstring(0,this.processedSelectionStart)+this.root.value._kmwSubstring(this.processedSelectionEnd),this.setCaret(this.processedSelectionStart)},t.prototype.isSelectionEmpty=function(){return this.root.selectionStart==this.root.selectionEnd},t.prototype.hasSelection=function(){return!0},t.prototype.invalidateSelection=function(){this._cachedSelectionStart=-1},t.prototype.getCaret=function(){return this.root.selectionStart!=this._cachedSelectionStart&&(this._cachedSelectionStart=this.root.selectionStart,this.processedSelectionStart=this.root.value._kmwCodeUnitToCodePoint(this.root.selectionStart),this.processedSelectionEnd=this.root.value._kmwCodeUnitToCodePoint(this.root.selectionEnd)),this.root.selectionDirection=="forward"?this.processedSelectionEnd:this.processedSelectionStart},t.prototype.getDeadkeyCaret=function(){return this.getCaret()},t.prototype.setCaret=function(e){this.setSelection(e,e,"none")},t.prototype.setSelection=function(e,n,c){var l=this.root.value._kmwCodePointToCodeUnit(e),r=this.root.value._kmwCodePointToCodeUnit(n);this.root.setSelectionRange(l,r,c),this.processedSelectionStart=e,this.processedSelectionEnd=n,this.forceScroll(),this.root.setSelectionRange(l,r,c)},t.prototype.forceScroll=function(){var e=this.getElement(),n=e.selectionStart,c=e.selectionEnd;this._activeForcedScroll=!0;try{e.blur(),e.focus()}finally{e.selectionStart=n,e.selectionEnd=c,this._activeForcedScroll=!1}},t.prototype.isForcingScroll=function(){return this._activeForcedScroll},t.prototype.getSelectionDirection=function(){return this.root.selectionDirection},t.prototype.getTextBeforeCaret=function(){return this.getCaret(),this.getText()._kmwSubstring(0,this.processedSelectionStart)},t.prototype.setTextBeforeCaret=function(e){this.getCaret();var n=this.processedSelectionEnd-this.processedSelectionStart,c=this.getSelectionDirection(),l=e._kmwLength();this.root.value=e+this.getText()._kmwSubstring(this.processedSelectionStart),this.setSelection(l,l+n,c)},t.prototype.setTextAfterCaret=function(e){var n=this.getCaret(),c=this.getSelectionDirection();this.root.value=this.getTextBeforeCaret()+e,this.setSelection(this.processedSelectionStart,this.processedSelectionEnd,c)},t.prototype.getTextAfterCaret=function(){return this.getCaret(),this.getText()._kmwSubstring(this.processedSelectionEnd)},t.prototype.getSelectedText=function(){return this.getCaret(),this.getText()._kmwSubstring(this.processedSelectionStart,this.processedSelectionEnd)},t.prototype.getText=function(){return this.root.value},t.prototype.deleteCharsBeforeCaret=function(e){if(e>0){var n=this.getTextBeforeCaret(),c=this.processedSelectionStart;e>c&&(e=c),this.adjustDeadkeys(-e),this.setTextBeforeCaret(n.kmwSubstring(0,c-e)),this.setCaret(c-e)}},t.prototype.insertTextBeforeCaret=function(e){if(!!e){var n=this.getCaret(),c=this.getTextBeforeCaret(),l=this.getText()._kmwSubstring(this.processedSelectionStart);this.adjustDeadkeys(e._kmwLength()),this.root.value=c+e+l,this.setCaret(n+e._kmwLength())}},t.prototype.handleNewlineAtCaret=function(){this.insertTextBeforeCaret("\n")},t.prototype.doInputEvent=function(){this.dispatchInputEventOn(this.root)},t}(_),Zn=er;var Ln=function(){function i(t,e){this.node=t,this.offset=e}return i}(),Jn=function(){function i(t,e){this.start=t,this.end=e}return i}(),Be=function(){function i(t,e){this.cmd=t,this.stateType=e}return i}(),tr=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this)||this;if(n.root=e,e.contentWindow&&e.contentWindow.document&&e.contentWindow.document.designMode=="on")n.doc=e.contentWindow.document,n.docRoot=e.contentWindow.document.documentElement;else throw"Specified IFrame is not in design-mode!";return n}return Object.defineProperty(t.prototype,"isSynthetic",{get:function(){return!1},enumerable:!1,configurable:!0}),t.prototype.getElement=function(){return this.root},t.prototype.focus=function(){this.doc.defaultView.focus()},t.prototype.isSelectionEmpty=function(){return this.hasSelection()?this.doc.getSelection().isCollapsed:!0},t.prototype.hasSelection=function(){var e=this.doc.getSelection(),n=document.getSelection();return n.anchorNode==e.anchorNode&&n.focusNode==e.focusNode,!0},t.prototype.clearSelection=function(){if(this.hasSelection()){var e=this.doc.getSelection();e.isCollapsed||e.deleteFromDocument()}else console.warn("Attempted to clear an unowned Selection!")},t.prototype.invalidateSelection=function(){},t.prototype.getCarets=function(){var e=this.doc.getSelection(),n=e.anchorNode.compareDocumentPosition(e.focusNode);if(e.isCollapsed){var c=new Ln(e.anchorNode,e.anchorOffset);return new Jn(c,c)}else{var l=new Ln(e.anchorNode,e.anchorOffset),r=new Ln(e.focusNode,e.focusOffset);return l.node==r.node&&(n=r.offset-l.offset>0?2:4),n&2?new Jn(l,r):new Jn(r,l)}},t.prototype.getDeadkeyCaret=function(){return this.getTextBeforeCaret().kmwLength()},t.prototype.getTextBeforeCaret=function(){if(!this.hasSelection())return this.getText();var e=this.getCarets().start;return e.node.nodeType!=3?"":e.node.textContent.substr(0,e.offset)},t.prototype.getSelectedText=function(){return""},t.prototype.getTextAfterCaret=function(){if(!this.hasSelection())return"";var e=this.getCarets().end;return e.node.nodeType!=3?"":e.node.textContent.substr(e.offset)},t.prototype.getText=function(){return this.docRoot.innerText},t.prototype.deleteCharsBeforeCaret=function(e){if(!(!this.hasSelection()||e<=0)){var n=this.getCarets().start;if(e>n.offset&&(e=n.offset),n.node.nodeType!=3){console.warn("Deletion of characters requested without available context!");return}var c=this.doc.createRange(),l=n.offset-n.node.nodeValue.substr(0,n.offset)._kmwSubstr(-e).length;c.setStart(n.node,l),c.setEnd(n.node,n.offset),this.adjustDeadkeys(-e),c.deleteContents()}},t.prototype.insertTextBeforeCaret=function(e){if(!!this.hasSelection()){var n=this.getCarets().start,c=e._kmwLength(),l=this.doc.getSelection();if(c!=0){this.adjustDeadkeys(c);var r=this.root.ownerDocument.createRange();if(n.node.nodeType==3){var s=n.node;s.insertData(n.offset,e),r.setStart(s,n.offset+e.length)}else{var B=this.doc.createTextNode(e),o=this.doc.createRange();o.setStart(n.node,n.offset),o.collapse(!0),o.insertNode(B),r.setStart(B,e.length)}r.collapse(!0),l.removeAllRanges();try{l.addRange(r)}catch(g){n.node.parentElement.scrollIntoView(),l.addRange(r)}l.collapseToEnd()}}},t.prototype.handleNewlineAtCaret=function(){},t.prototype.setTextAfterCaret=function(e){if(!!this.hasSelection()){var n=this.getCarets().end,c=e._kmwLength(),l=this.doc.getSelection();if(c!=0)if(n.node.nodeType==3){var r=n.node;r.replaceData(n.offset,r.length,e)}else{var s=n.node.ownerDocument.createTextNode(e),B=this.root.ownerDocument.createRange();B.setStart(n.node,n.offset),B.collapse(!0),B.insertNode(s)}}},t.prototype.saveProperties=function(){var e=[new Be("backcolor",1),new Be("fontname",1),new Be("fontsize",1),new Be("forecolor",1),new Be("bold",0),new Be("italic",0),new Be("strikethrough",0),new Be("subscript",0),new Be("superscript",0),new Be("underline",0)];this.doc.defaultView&&e.push(new Be("hilitecolor",1));for(var n=0;n0?2:4),n&2?new Rn(l,r):new Rn(r,l)}},t.prototype.getDeadkeyCaret=function(){return this.getTextBeforeCaret().kmwLength()},t.prototype.getTextBeforeCaret=function(){if(!this.hasSelection())return this.getText();var e=this.getCarets().start;return e.node.nodeType!=3?"":e.node.textContent.substr(0,e.offset)},t.prototype.getSelectedText=function(){return""},t.prototype.getTextAfterCaret=function(){if(!this.hasSelection())return"";var e=this.getCarets().end;return e.node.nodeType!=3?"":e.node.textContent.substr(e.offset)},t.prototype.getText=function(){return this.root.innerText},t.prototype.deleteCharsBeforeCaret=function(e){if(!(!this.hasSelection()||e<=0)){var n=this.getCarets().start;if(e>n.offset&&(e=n.offset),n.node.nodeType!=3){console.warn("Deletion of characters requested without available context!");return}var c=this.root.ownerDocument.createRange(),l=n.offset-n.node.nodeValue.substr(0,n.offset)._kmwSubstr(-e).length;c.setStart(n.node,l),c.setEnd(n.node,n.offset),this.adjustDeadkeys(-e),c.deleteContents()}},t.prototype.insertTextBeforeCaret=function(e){if(!!this.hasSelection()){var n=this.getCarets().start,c=e._kmwLength(),l=this.root.ownerDocument.getSelection();if(c!=0){this.adjustDeadkeys(c);var r=this.root.ownerDocument.createRange();if(n.node.nodeType==3){var s=n.node;s.insertData(n.offset,e),r.setStart(s,n.offset+e.length)}else{var B=n.node.ownerDocument.createTextNode(e),o=this.root.ownerDocument.createRange();o.setStart(n.node,n.offset),o.collapse(!0),o.insertNode(B),r.setStart(B,e.length)}r.collapse(!0),l.removeAllRanges();try{l.addRange(r)}catch(g){n.node.parentElement.scrollIntoView(),l.addRange(r)}l.collapseToEnd()}}},t.prototype.handleNewlineAtCaret=function(){},t.prototype.setTextAfterCaret=function(e){if(!!this.hasSelection()){var n=this.getCarets().end,c=e._kmwLength(),l=this.root.ownerDocument.getSelection();if(c!=0)if(n.node.nodeType==3){var r=n.node;r.replaceData(n.offset,r.length,e)}else{var s=n.node.ownerDocument.createTextNode(e),B=this.root.ownerDocument.createRange();B.setStart(n.node,n.offset),B.collapse(!0),B.insertNode(s)}}},t.prototype.doInputEvent=function(){this.dispatchInputEventOn(this.root)},t}(_),Xt=nr;function N(i,t){var e;if(!i)return!1;if(i.Window)return t=="Window";if(i.defaultView)e=i.defaultView[t];else if(i.ownerDocument)e=i.ownerDocument.defaultView[t];else if(i.target){var n=i;this.instanceof(n.target,"Window")?e=n.target[t]:this.instanceof(n.target,"Document")?e=n.target.defaultView[t]:this.instanceof(n.target,"HTMLElement")&&(e=n.target.ownerDocument.defaultView[t])}return e?i instanceof e:!1}function pt(i){if(N(i,"HTMLInputElement"))return new mn(i);if(N(i,"HTMLTextAreaElement"))return new Zn(i);if(N(i,"HTMLIFrameElement")){var t=i;return t.contentWindow&&t.contentWindow.document&&t.contentWindow.document.designMode=="on"?new ne(t):i.isContentEditable?new Xt(i):null}else if(i.isContentEditable)return new Xt(i);return null}var Ne=function(){function i(){var t=this;this.pending=!1;var e=this.bg=document.createElement("div"),n=this.lb=document.createElement("div"),c=this.lt=document.createElement("div"),l=this.gr=document.createElement("div"),r=this.bx=document.createElement("div");e.className="kmw-wait-background",n.className="kmw-wait-box",this.dismiss=null,c.className="kmw-wait-text",l.className="kmw-wait-graphic",r.className="kmw-alert-close",n.onmousedown=n.onclick=function(s){r.style.display=="block"&&(e.style.display="none",t.dismiss&&t.dismiss())},n.addEventListener("touchstart",n.onclick,!1),e.onmousedown=e.onclick=function(s){s.preventDefault(),s.stopPropagation()},e.addEventListener("touchstart",e.onclick,!1),n.appendChild(r),n.appendChild(c),n.appendChild(l),e.appendChild(n),document.body.appendChild(e)}return Object.defineProperty(i.prototype,"rootElement",{get:function(){return this.bg},enumerable:!1,configurable:!0}),i.prototype.wait=function(t){var e=this,n=this.bg;typeof n=="undefined"||n==null||(t?(this.pending=!0,window.setTimeout(function(){e.pending&&(window.scrollTo(0,0),e.bx.style.display="none",e.lt.className="kmw-wait-text",e.lt.innerHTML=t,e.gr.style.display="block",n.style.display="block")},1e3)):this.pending&&(this.lt.innerHTML="",this.pending=!1,n.style.display="none"))},i.prototype.alert=function(t,e){var n=this.bg;this.bx.style.display="block",this.lt.className="kmw-alert-text",this.lt.innerHTML=t,this.gr.style.display="none",n.style.display="block",this.dismiss=arguments.length>1?e:null},i.prototype.shutdown=function(){this.bg.parentNode.removeChild(this.bg)},i}();function tt(){return document.readyState==="complete"?Promise.resolve():new Promise(function(i,t){var e=function(){window.removeEventListener("load",e),i()};window.addEventListener("load",e)})}var _c=function(i){(0,d.__extends)(t,i);function t(){return i!==null&&i.apply(this,arguments)||this}return t.prototype.initialize=function(e){var n=this;this._options?this._options=(0,d.__assign)((0,d.__assign)({},this._options),e):this._options=(0,d.__assign)({},e),i.prototype.initialize.call(this,e),this._options=e,this._ui=e.ui,this._attachType=e.attachType,tt().then(function(){var c;e.useAlerts&&!n.alertHost?n._alertHost=new Ne:!e.useAlerts&&n.alertHost&&((c=n._alertHost)===null||c===void 0||c.shutdown(),n._alertHost=null)})},Object.defineProperty(t.prototype,"options",{get:function(){return this._options},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"attachType",{get:function(){return this._attachType},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"alertHost",{get:function(){return this._alertHost},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"signalUser",{set:function(e){(!e||e!=this.alertHost)&&this.alertHost.shutdown(),this._alertHost=e},enumerable:!1,configurable:!0}),t.prototype.debugReport=function(){var e=i.prototype.debugReport.call(this);return e.attachType=this.attachType,e.ui=this._ui,e.keymanEngine="app/browser",e},t.prototype.onRuleFinalization=function(e,n){var c=e.transcription.transform;ot(c)||n instanceof _&&(n.changed=!0)},t}(zt);var Pc=(0,d.__assign)({ui:"",attachType:"",useAlerts:!0},Kt);var An=function(){function i(t,e,n){this.interface=t,this.keyboard=e}return i}();function be(i){var t=i==null?void 0:i.target;return he(t)}function he(i){if(i==null)return null;if(i.body&&(i=i.body),i.nodeType==3&&(i=i.parentNode),N(i,"HTMLInputElement")){var t=i.type.toLowerCase();if(!(t=="text"||t=="search"))return null}return i._kmwAttachment.interface}var jc=J(R(),1);var fn=function(i){(0,d.__extends)(t,i);function t(e,n){var c=this;if(!e)throw new Error("Cannot attach to a null/undefined document");return c=i.call(this)||this,c.baseFont="",c.appliedFont="",c.embeddedPageContexts=[],c._inputList=[],c._sortedInputs=[],c._InputModeObserverCore=function(l){c.disableInputModeObserver();try{for(var r=0,s=l;r=0:!1,o=s.target.className.indexOf("kmw-disabled")>=0;if(B&&!o?c._EnableControl(s.target):!B&&o&&c._DisableControl(s.target),!o&&s.attributeName=="readonly"){var g=s.oldValue?s.oldValue!=null:!1,a=s.target;if(a instanceof a.ownerDocument.defaultView.HTMLInputElement||a instanceof a.ownerDocument.defaultView.HTMLTextAreaElement){var F=a.readOnly;g&&!F?c._EnableControl(s.target):!g&&F&&c._DisableControl(s.target)}}}},c._AutoAttachObserverCore=function(l){for(var r=[],s=[],B=0;B=0)},t.prototype.enableInputElement=function(e){var n;this.isKMWDisabled(e)||(e instanceof e.ownerDocument.defaultView.HTMLIFrameElement?this._AttachToIframe(e):(this.setupElementAttachment(e),e._kmwAttachment.inputMode=(n=e.inputMode)!==null&&n!==void 0?n:"text",this.disableInputModeObserver(),e.inputMode="none",this.enableInputModeObserver(),e.classList.add("keymanweb-font"),this._inputList.push(e),this.emit("enabled",e)))},t.prototype.disableInputElement=function(e){var n;if(!!e)if(e.ownerDocument.defaultView&&e instanceof e.ownerDocument.defaultView.HTMLIFrameElement||e instanceof HTMLIFrameElement)this._DetachFromIframe(e);else{if(this.isAttached(e)){var c=(n=e._kmwAttachment)===null||n===void 0?void 0:n.inputMode;this.disableInputModeObserver(),e.inputMode=c,this.enableInputModeObserver()}var l=e.className.indexOf("keymanweb-font");l>=0&&(e.className=e.className.replace("keymanweb-font","").trim());var r=this.inputList.indexOf(e);r>-1&&this._inputList.splice(r,1),this.emit("disabled",e)}},t.prototype.enableTouchElement=function(e){return this.isKMWDisabled(e)?(this.emit("disabled",e),!1):(this.isAttached(e)||this.setupElementAttachment(e),this.enableInputElement(e),!0)},t.prototype.disableTouchElement=function(e){if(this.isAttached(e)){var n=e._kmwAttachment.inputMode;this.disableInputModeObserver(),e.inputMode=n,this.enableInputModeObserver()}},t.prototype._AttachToIframe=function(e){var n=this;try{var c=e.contentWindow.document;if(c){if(c.designMode.toLowerCase()=="on")this.setupElementAttachment(e),c.body._kmwAttachment=e._kmwAttachment,this._inputList.push(e),this.emit("enabled",e);else if(this.embeddedPageContexts.filter(function(r){return r.document==c}).length==0){var l=new t(c,(0,d.__assign)((0,d.__assign)({},this.options),{owner:e}));this.embeddedPageContexts.push(l),l.on("enabled",function(r){return n.emit("enabled",r)}),l.on("disabled",function(r){return n.emit("disabled",r)}),l.install(this.manualAttach)}}}catch(r){}},t.prototype._DetachFromIframe=function(e){var n=this,c=function(){n.clearElementAttachment(e);var B=n._inputList.indexOf(e);B!=-1&&n._inputList.splice(B,1),n.emit("disabled",e)};try{var l=e.contentWindow.document;if(l){if(l.designMode.toLowerCase()=="on")l.body._kmwAttachment=null,c();else for(var r=0;r=0&&(e.className=n.replace("kmw-disabled","").trim())},t.prototype.listInputs=function(){for(var e=[],n=document.getElementsByTagName("input"),c=document.getElementsByTagName("textarea"),l=0;l=l.length?c-l.length:c,c=c<0?c+l.length:c,l[c]},t.prototype._GetDocumentEditables=function(e){var n=[];if(e.ownerDocument&&e instanceof e.ownerDocument.defaultView.HTMLElement){var c=e.ownerDocument.defaultView;(e instanceof c.HTMLInputElement||e instanceof c.HTMLTextAreaElement||e instanceof c.HTMLIFrameElement)&&n.push(e)}if(e.getElementsByTagName){var l=function(r){return dt(e.getElementsByTagName(r))};n=n.concat(l("INPUT"),l("TEXTAREA"),l("IFRAME"))}return e.querySelectorAll&&(n=n.concat(dt(e.querySelectorAll("[contenteditable]")))),e.ownerDocument&&e instanceof e.ownerDocument.defaultView.HTMLElement&&e.isContentEditable&&n.push(e),n},t.prototype._SetupDocument=function(e){for(var n=this._GetDocumentEditables(e),c=0;c0&&n.length==0)c=1;else if(e.length==0&&n.length>0)c=2;else{var s=e[0],B=n[0];s.offsetTopB.offsetTop?c=2:s.offsetLeftB.offsetLeft&&(c=2)}switch(c){case 0:l=r;break;case 1:l=getComputedStyle(e[0]).fontFamily||"";break;case 2:l=getComputedStyle(n[0]).fontFamily||"";break}return(typeof l=="undefined"||l=="monospace")&&(l=r),l},t.prototype.buildAttachmentFontStyle=function(e){var n=e,c=this.baseFont;n&&typeof n.family!="undefined"&&(c=n.family),c=c.replace(/\u0022/g,"");var l=new RegExp("\\s?"+c+",?"),r=this.appliedFont.replace(/\u0022/g,"");r=r.replace(l,""),r=r.replace(/,$/,""),r==""?r=c:r=c+","+r,r='"'+r.replace(/\,\s?/g,'","')+'"';var s=".keymanweb-font{\nfont-family:"+r+" !important;\n}\n";return this.appliedFont=r,s},t.prototype.setAttachmentFont=function(e,n,c){this.stylesheetManager.unlinkAll(),this.stylesheetManager.addStyleSheetForFont(e,n,c),this.stylesheetManager.linkStylesheet(Ve(this.buildAttachmentFontStyle(e)))},t.prototype.shutdown=function(){var e,n,c,l;try{(e=this.enablementObserver)===null||e===void 0||e.disconnect(),(n=this.attachmentObserver)===null||n===void 0||n.disconnect(),(c=this.inputModeObserver)===null||c===void 0||c.disconnect(),(l=this.stylesheetManager)===null||l===void 0||l.unlinkAll(),this.inputModeObserver=null,this.embeddedPageContexts.forEach(function(o){try{o.shutdown()}catch(g){}});for(var r=0,s=this.inputList;r"+n.name),c.then(function(){var r;(r=e.engineConfig.alertHost)===null||r===void 0||r.wait()})}),this.engineConfig.deferForInitialization.then(function(){var n=e.engineConfig.hostDevice,c=function(l){return l.stopPropagation()};e.page.on("enabled",function(l){if(!(l._kmwAttachment.interface instanceof ne))n.touchable&&(e.domEventTracker.detachDOMEvent(l,"touchstart",e.nonKMWTouchHandler),e.domEventTracker.attachDOMEvent(l,"touchmove",c,!1),e.domEventTracker.attachDOMEvent(l,"touchend",c,!1)),e.domEventTracker.attachDOMEvent(l,"focus",e._ControlFocus),e.domEventTracker.attachDOMEvent(l,"blur",e._ControlBlur),e.domEventTracker.attachDOMEvent(l,"click",e._Click);else{var r=l.contentWindow.document;n.browser=="firefox"?(e.domEventTracker.attachDOMEvent(r,"focus",e._ControlFocus),e.domEventTracker.attachDOMEvent(r,"blur",e._ControlBlur)):(e.domEventTracker.attachDOMEvent(r.body,"focus",e._ControlFocus),e.domEventTracker.attachDOMEvent(r.body,"blur",e._ControlBlur))}}),e.page.on("disabled",function(l){var r;if(!N(l,"HTMLIFrameElement"))n.touchable&&e.domEventTracker.attachDOMEvent(l,"touchstart",e.nonKMWTouchHandler,!1),e.domEventTracker.detachDOMEvent(l,"focus",e._ControlFocus),e.domEventTracker.detachDOMEvent(l,"blur",e._ControlBlur),e.domEventTracker.detachDOMEvent(l,"click",e._Click);else{var s=l.contentWindow.document;n.browser=="firefox"?(e.domEventTracker.detachDOMEvent(s,"focus",e._ControlFocus),e.domEventTracker.detachDOMEvent(s,"blur",e._ControlBlur)):(e.domEventTracker.detachDOMEvent(s.body,"focus",e._ControlFocus),e.domEventTracker.detachDOMEvent(s.body,"blur",e._ControlBlur))}var B=(r=e.mostRecentTarget)===null||r===void 0?void 0:r.getElement();B&&B==l&&e.forgetActiveTarget()}),e.page.install(e.engineConfig.attachType=="manual")})},Object.defineProperty(t.prototype,"activeTarget",{get:function(){var e=this.focusAssistant.maintainingFocus;return this.currentTarget||(e?this.mostRecentTarget:null)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"lastActiveTarget",{get:function(){return this.mostRecentTarget},enumerable:!1,configurable:!0}),t.prototype.deactivateCurrentTarget=function(){var e=this.activeTarget||this.lastActiveTarget;e&&this.page.isAttached(e.getElement())&&this._BlurKeyboardSettings(e.getElement()),this.activeTarget||this.setActiveTarget(null,!0)},t.prototype.forgetActiveTarget=function(){this.focusAssistant.maintainingFocus=!1,this.focusAssistant.restoringFocus=!1;var e=this.activeTarget||this.mostRecentTarget;e&&this._BlurKeyboardSettings(e.getElement()),this.setActiveTarget(null,!0),e==this.lastActiveTarget&&(this.mostRecentTarget=null)},t.prototype.setActiveTarget=function(e,n){var c,l=this.mostRecentTarget,r=this.activeTarget;if(e==r){r&&(this.currentTarget=r);return}var s=!!l;if(this.currentTarget=this.mostRecentTarget=e,this.predictionContext.setCurrentTarget(e),this.focusAssistant.restoringFocus?this._BlurKeyboardSettings(e.getElement()):e&&this._FocusKeyboardSettings(e.getElement(),!s),this._CommonFocusHelper(e))return!0;var B=e==null?void 0:e.getElement();e instanceof ne&&(B=e.docRoot),B&&B.ownerDocument&&B instanceof B.ownerDocument.defaultView.HTMLElement&&ei(B,(c=this.activeKeyboard)===null||c===void 0?void 0:c.keyboard),e!=r&&this.emit("targetchange",e),n&&this.apiEvents.callEvent("controlfocused",{target:(e==null?void 0:e.getElement())||null,activeControl:l==null?void 0:l.getElement()})},Object.defineProperty(t.prototype,"activeKeyboard",{get:function(){return this._activeKeyboard},enumerable:!1,configurable:!0}),t.prototype.restoreLastActiveTarget=function(){!this.mostRecentTarget||(this.focusAssistant.restoringFocus=!0,this.mostRecentTarget.focus(),this.focusAssistant.restoringFocus=!1)},t.prototype.insertText=function(e,n,c){this.restoreLastActiveTarget();var l=this.activeTarget;return l==null&&this.mostRecentTarget&&(l=this.activeTarget),l!=null?i.prototype.insertText.call(this,e,n,c):!1},t.prototype.currentKeyboardSrcTarget=function(){var e=this.currentTarget||this.mostRecentTarget;return this.isTargetKeyboardIndependent(e)?e:null},t.prototype.isTargetKeyboardIndependent=function(e){var n=e==null?void 0:e.getElement()._kmwAttachment;return!!((n==null?void 0:n.keyboard)||(n==null?void 0:n.keyboard)==="")},t.prototype.activateKeyboardForTarget=function(e,n){var c,l,r=n==null?void 0:n.getElement()._kmwAttachment;if(r?(r.keyboard=(c=e==null?void 0:e.metadata.id)!==null&&c!==void 0?c:"",r.languageCode=(l=e==null?void 0:e.metadata.langId)!==null&&l!==void 0?l:""):this.globalKeyboard=e,this.currentKeyboardSrcTarget()==n){this._activeKeyboard=e;var s=e==null?void 0:e.metadata;this.page.setAttachmentFont(s==null?void 0:s.KFont,this.engineConfig.paths.fonts,this.engineConfig.hostDevice.OS)}},t.prototype.setKeyboardForTarget=function(e,n,c){if(e instanceof ne){console.warn("'keymanweb.setKeyboardForControl' cannot set keyboard on iframes.");return}var l=e.getElement()._kmwAttachment,r=this.currentKeyboardSrcTarget()==e;if(l){if(l.keyboard=n||null,l.languageCode=c||null,r||this.currentKeyboardSrcTarget()==e){var s=this.globalKeyboard.metadata;this.activateKeyboard(l.keyboard||s.id,l.languageCode||s.langId,!0)}}else return},t.prototype.getKeyboardStubForTarget=function(e){if(this.isTargetKeyboardIndependent(e)){var n=e.getElement()._kmwAttachment;return this.keyboardCache.getStub(n.keyboard,n.languageCode)}else return this.globalKeyboard.metadata},t.prototype.getFallbackStubKey=function(){var e={id:"",langId:""};return this.engineConfig.hostDevice.touchable&&this.keyboardCache.defaultStub||e},t.prototype.activateKeyboard=function(e,n,c){var l,r,s,B,o,g;return(0,d.__awaiter)(this,void 0,void 0,function(){var a,F,y,u,Q,C=this;return(0,d.__generator)(this,function(h){switch(h.label){case 0:c||(c=!1),a=this.currentKeyboardSrcTarget(),e||(e=this.getFallbackStubKey().id,n=this.getFallbackStubKey().langId),h.label=1;case 1:return h.trys.push([1,3,,7]),[4,i.prototype.activateKeyboard.call(this,e,n,c)];case 2:return F=h.sent(),(l=this.engineConfig.alertHost)===null||l===void 0||l.wait(),c&&!a&&this.cookieManager.save({current:"".concat(e,":").concat(n)}),a==this.currentKeyboardSrcTarget()&&(ei((r=this.currentTarget)===null||r===void 0?void 0:r.getElement(),this.keyboardCache.getKeyboard(e)),this.page.setAttachmentFont((B=(s=this.activeKeyboard)===null||s===void 0?void 0:s.metadata)===null||B===void 0?void 0:B.KFont,this.engineConfig.paths.fonts,this.engineConfig.hostDevice.OS),this.restoreLastActiveTarget()),[2,F];case 3:return y=h.sent(),u=function(){return(0,d.__awaiter)(C,void 0,void 0,function(){var b;return(0,d.__generator)(this,function(U){switch(U.label){case 0:return b=this.getFallbackStubKey(),b.id==e?[3,2]:[4,this.activateKeyboard(b.id,b.langId,!0).catch(function(){})];case 1:U.sent(),U.label=2;case 2:return[2]}})})},(o=this.engineConfig.alertHost)===null||o===void 0||o.wait(),Q=(y==null?void 0:y.message)||"Sorry, the "+e+" keyboard for "+n+" is not currently available.",y instanceof ze?console.error(y||Q):console.warn(y||Q),this.engineConfig.alertHost?((g=this.engineConfig.alertHost)===null||g===void 0||g.alert(Q,u),[3,6]):[3,4];case 4:return[4,u()];case 5:h.sent(),h.label=6;case 6:throw y;case 7:return[2]}})})},t.prototype._BlurKeyboardSettings=function(e,n,c){var l,r=this.activeKeyboard?this.activeKeyboard.keyboard.id:"",s=(l=this.activeKeyboard)===null||l===void 0?void 0:l.metadata.langId;n!==void 0&&c!==void 0&&(r=n,s=c),e&&e._kmwAttachment.keyboard!=null?(e._kmwAttachment.keyboard=r,e._kmwAttachment.languageCode=s):this.globalKeyboard=this.activeKeyboard},t.prototype._FocusKeyboardSettings=function(e,n){var c,l=e._kmwAttachment,r=this.globalKeyboard;l.keyboard!=null?this.activateKeyboard(l.keyboard,l.languageCode,!0):!n&&(r==null?void 0:r.metadata)!=((c=this._activeKeyboard)===null||c===void 0?void 0:c.metadata)&&this.activateKeyboard(r==null?void 0:r.metadata.id,r==null?void 0:r.metadata.langId,!0)},t.prototype._CommonFocusHelper=function(e){var n,c=this.focusAssistant,l=(n=this.activeKeyboard)===null||n===void 0?void 0:n.keyboard;return c.restoringFocus||(e==null||e.deadkeys().clear(),l==null||l.notify(0,e,1)),!c.restoringFocus&&this.mostRecentTarget!=e&&(c.maintainingFocus=!1),c.restoringFocus=!1,this.resetContext(),!1},t.prototype.doChangeEvent=function(e){if(e.changed){var n=new Event("change",{bubbles:!0,cancelable:!1});e.getElement().dispatchEvent(n)}e.changed=!1},t.prototype.getSavedKeyboardRaw=function(){var e=new se("KeymanWeb_Keyboard"),n=e.load(decodeURIComponent);return typeof n.current!="string"||n.current=="Keyboard_us:eng"?"Keyboard_us:en":n.current},t.prototype.getSavedKeyboard=function(){for(var e=this.getSavedKeyboardRaw(),n=this.keyboardCache.getStubList(),c,l=0;l0?n[0].KI+":"+n[0].KLC:"Keyboard_us:en"},t.prototype.restoreSavedKeyboard=function(e){var n=e,c=n.split(":");c.length<2&&(c[1]="");var l=this.keyboardCache.getStub(c[0],c[1])||this.keyboardCache.defaultStub;l&&this.activateKeyboard(c[0],c[1])},t.prototype.shutdown=function(){this.page.shutdown(),this.domEventTracker.shutdown()},t}(_t),ti=ir;var lr=function(i){(0,d.__extends)(t,i);function t(e){var n=i.call(this)||this;return n.contextManager=e,n}return t.prototype.isCommand=function(e){var n=this.codeForEvent(e);switch(n){case I.keyCodes.K_TAB:case I.keyCodes.K_TABBACK:case I.keyCodes.K_TABFWD:return!0;default:return i.prototype.isCommand.call(this,e)}},t.prototype.applyCommand=function(e,n){var c=this,l=this.codeForEvent(e),r=function(s){var B,o=c.contextManager,g=(B=o.activeTarget)===null||B===void 0?void 0:B.getElement(),a=o.page.findNeighboringInput(g,s);a.focus()};switch(l){case I.keyCodes.K_TAB:r((e.Lmodifiers&I.modifierCodes.SHIFT)!=0);break;case I.keyCodes.K_TABBACK:r(!0);break;case I.keyCodes.K_TABFWD:r(!1);break}i.prototype.applyCommand.call(this,e,n)},t}(Ge),ni=lr;function Sn(i){return i.keyCode?i.keyCode:i.which?i.which:null}function mt(i,t,e){if(i.cancelBubble===!0)return null;var n=Sn(i);if(n==null)return null;var c=t.modStateFlags,l=0,r=!1,s=!1,B=I.keyCodes;switch(n){case B.K_CTRL:case B.K_LCTRL:case B.K_RCTRL:case B.K_CONTROL:case B.K_LCONTROL:case B.K_RCONTROL:r=!0;break;case B.K_LMENU:case B.K_RMENU:case B.K_ALT:case B.K_LALT:case B.K_RALT:s=!0;break}l|=i.getModifierState("Shift")?16:0;var o=I.modifierCodes;i.getModifierState("Control")&&(l|=i.location!=0&&r?i.location==1?o.LCTRL:o.RCTRL:c&3),i.getModifierState("Alt")&&(l|=i.location!=0&&s?i.location==1?o.LALT:o.RALT:c&12);var g=0;g|=i.getModifierState("CapsLock")?o.CAPS:o.NO_CAPS,g|=i.getModifierState("NumLock")?o.NUM_LOCK:o.NO_NUM_LOCK,g|=i.getModifierState("ScrollLock")?o.SCROLL_LOCK:o.NO_SCROLL_LOCK,l|=g;var a=t.modStateFlags!=l;t.modStateFlags=l;var F=o.RALT|o.LCTRL;(c&F)==F&&(l&F)!=F&&(l&=~F),l&o.RALT&&(l&=~o.LCTRL);var y=I.modifierBitmasks,u=t.activeKeyboard,Q;u&&u.isChiral?(Q=l&y.CHIRAL,u.emulatesAltGr&&(Q&y.ALT_GR_SIM)==y.ALT_GR_SIM&&(Q^=y.ALT_GR_SIM,Q|=o.RALT)):Q=l&16|(l&(o.LCTRL|o.RCTRL)?32:0)|(l&(o.LALT|o.RALT)?64:0),Q|=i.metaKey?o.META:0,e.browser==x.Browser.Firefox&&de.browserMap.FF["k"+n]&&(n=de.browserMap.FF["k"+n]);var C=new $({device:e,kName:"",Lcode:n,Lmodifiers:Q,Lstates:g,LmodifierChange:a,isSynthetic:!1});u&&u.isMnemonic&&C.setMnemonicCode(i.getModifierState("Shift"),i.getModifierState("CapsLock"));var h=typeof i.charCode!="undefined"&&i.charCode!=null&&(i.charCode==0||(Q&111)!=0);if(C.LisVirtualKey=h||i.type!="keypress",u&&!u.isMnemonic){var b=de.languageMap[t.baseLayout];b&&b["k"+C.Lcode]&&(C.Lcode=b["k"+C.Lcode]),!u.definesPositionalOrMnemonic&&!(C.Lmodifiers&96)&&(C=new $({Lcode:de._USKeyCodeToCharCode(C),Lmodifiers:0,LisVirtualKey:!1,vkCode:C.Lcode,Lstates:C.Lstates,kName:"",device:e,isSynthetic:!1}))}var U=new $(C);return U.source=i,U}var rr=function(i){(0,d.__extends)(t,i);function t(e,n,c){var l=i.call(this)||this;l.domEventTracker=new Ie,l.swallowKeypress=!1,l._KeyDown=function(B){var o,g=l.contextManager.activeKeyboard,a=be(B);if(!a||g==null)return!0;var F=a.getElement();return((o=F==null?void 0:F.className)===null||o===void 0?void 0:o.indexOf("kmw-disabled"))>=0?!0:l.keyDown(B)},l._KeyPress=function(B){var o=be(B);return!o||l.activeKeyboard==null?!0:l.keyPress(B)},l._KeyUp=function(B){var o=be(B),g=mt(B,l.processor,l.hardDevice);if(g==null)return!0;var a=o.getElement();if(g.Lcode==13){var F=!1;if(N(a,"HTMLTextAreaElement")&&(F=!0),!F){if(a instanceof a.ownerDocument.defaultView.HTMLInputElement)if(a.form&&(a.type=="search"||a.type=="submit"))a.form.submit();else{var y=l.contextManager.page.findNeighboringInput(a,!1);y.focus()}return!0}}return l.keyUp(B)},l.hardDevice=e,l.contextManager=c,l.processor=n;var r=c.page,s=l.domEventTracker;return r.on("enabled",function(B){var o=he(B);if(!(o instanceof ne))s.attachDOMEvent(B,"keypress",l._KeyPress),s.attachDOMEvent(B,"keydown",l._KeyDown),s.attachDOMEvent(B,"keyup",l._KeyUp);else{var g=o.getElement().contentDocument;s.attachDOMEvent(g.body,"keydown",l._KeyDown),s.attachDOMEvent(g.body,"keypress",l._KeyPress),s.attachDOMEvent(g.body,"keyup",l._KeyUp)}}),r.off("disabled",function(B){var o=he(B);if(!(o instanceof ne))s.detachDOMEvent(B,"keypress",l._KeyPress),s.detachDOMEvent(B,"keydown",l._KeyDown),s.detachDOMEvent(B,"keyup",l._KeyUp);else{var g=o.getElement().contentDocument;s.detachDOMEvent(g.body,"keydown",l._KeyDown),s.detachDOMEvent(g.body,"keypress",l._KeyPress),s.detachDOMEvent(g.body,"keyup",l._KeyUp)}}),l}return Object.defineProperty(t.prototype,"activeKeyboard",{get:function(){return this.contextManager.activeKeyboard.keyboard},enumerable:!1,configurable:!0}),t.prototype.keyDown=function(e){var n=this;this.swallowKeypress=!1;var c=mt(e,this.processor,this.hardDevice);if(c==null)return!0;var l={LeventMatched:!1};return this.emit("keyevent",c,function(r,s){l.LeventMatched=r&&!r.triggerKeyDefault,l.LeventMatched?(e&&e.preventDefault&&(e.preventDefault(),e.stopPropagation()),n.swallowKeypress=!!c.Lcode,c.Lcode==8&&(n.swallowKeypress=!1)):n.swallowKeypress=!1}),!l.LeventMatched},t.prototype.keyUp=function(e){var n=mt(e,this.processor,this.hardDevice);if(n==null)return!0;var c=be(e);return this.processor.doModifierPress(n,c,!1)},t.prototype.keyPress=function(e){var n=mt(e,this.processor,this.hardDevice);if(n==null||n.LisVirtualKey)return!0;if(!this.activeKeyboard.isMnemonic)return!this.swallowKeypress||n.Lcode<32||this.hardDevice.browser==x.Browser.Safari&&n.Lcode>63232&&n.Lcode<63744;var c={};return this.swallowKeypress||this.emit("keyevent",n,function(l,r){c.preventDefaultKeystroke=!!l}),this.swallowKeypress||c.preventDefaultKeystroke?(this.swallowKeypress=!1,e&&e.preventDefault&&(e.preventDefault(),e.stopPropagation()),!1):(this.swallowKeypress=!1,!0)},t.prototype.shutdown=function(){this.domEventTracker.shutdown()},t}(Pt),ci=rr;var ii=function(){function i(){this.innerWidth=window.innerWidth,this.innerHeight=window.innerHeight}return i.prototype.equals=function(t){return this.innerWidth==t.innerWidth&&this.innerHeight==t.innerHeight},i}(),li=function(){function i(t){this.idlePermutationCounter=i.IDLE_PERMUTATION_CAP,this.keyman=t}return i.prototype.resolve=function(){var t,e=this.keyman.osk;(t=this.keyman.touchLanguageMenu)===null||t===void 0||t.hide(),this.keyman.touchLanguageMenu=null,e.setNeedsLayout(),this.oskVisible&&e.present(),this.isActive=!1,this.updateTimer&&(window.clearInterval(this.updateTimer),this.rotState=null)},i.prototype.initNewRotation=function(){this.oskVisible=this.keyman.osk.isVisible(),this.keyman.osk.hideNow(),this.isActive=!0},i.prototype.init=function(){var t=this,e=this.keyman.config.hostDevice.OS,n=this.keyman.util;e=="ios"?(n.attachDOMEvent(window,"orientationchange",function(){return t.iOSEventHandler(),!1}),n.attachDOMEvent(window,"resize",function(){return t.iOSEventHandler(),!1})):e=="android"&&("onmozorientationchange"in screen?n.attachDOMEvent(screen,"mozorientationchange",function(){return t.initNewRotation(),!1}):n.attachDOMEvent(window,"orientationchange",function(){return t.initNewRotation(),!1}),n.attachDOMEvent(window,"resize",function(){return t.resolve(),!1}))},i.prototype.iOSEventHandler=function(){this.isActive||(this.initNewRotation(),this.rotState=new ii,this.updateTimer=window.setInterval(this.iOSEventUpdate.bind(this),i.UPDATE_INTERVAL)),this.idlePermutationCounter=0},i.prototype.iOSEventUpdate=function(){var t=new ii;this.rotState.equals(t)?++this.idlePermutationCounter==i.IDLE_PERMUTATION_CAP&&this.resolve():(this.rotState=t,this.idlePermutationCounter=0)},i.IDLE_PERMUTATION_CAP=15,i.UPDATE_INTERVAL=20,i}();var ri=function(){function i(t,e){var n=this;this.domEventTracker=new Ie,this.suppressFocusCheck=function(c){return n.focusAssistant.isTargetForcingScroll()&&(c.stopPropagation(),c.cancelBubble=!0),!0},this.pageFocusHandler=function(){var c;return!n.focusAssistant.maintainingFocus&&((c=n.engine.osk)===null||c===void 0?void 0:c.vkbd)&&(n.engine.contextManager.deactivateCurrentTarget(),n.engine.contextManager.resetContext()),!1},this.touchStartActivationHandler=function(c){var l=n.engine.osk;if(!l)return!1;var r=n.engine.config.hostDevice;if(n.deactivateOnRelease=!0,n.touchY=c.touches[0].screenY,n.deactivateOnScroll=!1,r.OS=="android"&&r.browser=="chrome"){if(typeof l._Box=="undefined"||typeof l._Box.style=="undefined")return!1;var s=c.target.parentElement;if(typeof s!="undefined"&&s!=null&&(s.className.indexOf("kmw-key-")>=0||typeof s.parentElement!="undefined"&&s.parentElement!=null&&(s=s.parentElement,s.className.indexOf("kmw-key-")>=0)))return!1;n.deactivateOnScroll=!0}return!1},this.touchMoveActivationHandler=function(c){n.deactivateOnScroll&&(n.focusAssistant.focusing=!1,n.engine.contextManager.deactivateCurrentTarget());var l=c.touches[0].screenY,r=n.touchY;return(l-r>5||r-l<5)&&(n.deactivateOnRelease=!1),!1},this.touchEndActivationHandler=function(c){return n.deactivateOnRelease&&!n.engine.touchLanguageMenu&&!n.focusAssistant.focusing&&n.engine.contextManager.deactivateCurrentTarget(),n.deactivateOnRelease=!1,!1},this._WindowLoad=function(){document.body.scrollTop=0,typeof document.documentElement!="undefined"&&(document.documentElement.scrollTop=0)},this._WindowUnload=function(){n.engine.shutdown()},this.window=t,this.engine=e,this.attachHandlers(),e.config.hostDevice.touchable&&(this.buildPageTrailer(),this.rotationProcessor=new li(this.engine),this.rotationProcessor.init())}return i.prototype.buildPageTrailer=function(){var t=this.mobilePageTrailer=document.createElement("div"),e=t.style;e.width="100%",e.height=screen.width/2+"px",document.body.appendChild(t)},Object.defineProperty(i.prototype,"focusAssistant",{get:function(){return this.engine.contextManager.focusAssistant},enumerable:!1,configurable:!0}),i.prototype.attachHandlers=function(){var t=this.domEventTracker,e=this.engine.config.hostDevice,n=this.window.document.body;t.attachDOMEvent(this.window,"focus",this.pageFocusHandler,!1),t.attachDOMEvent(this.window,"blur",this.pageFocusHandler,!1),t.attachDOMEvent(n,"focus",this.suppressFocusCheck,!0),t.attachDOMEvent(n,"blur",this.suppressFocusCheck,!0),e.touchable&&(t.attachDOMEvent(n,"touchstart",this.touchStartActivationHandler,!1),t.attachDOMEvent(n,"touchmove",this.touchMoveActivationHandler,!1),t.attachDOMEvent(n,"touchend",this.touchEndActivationHandler,!1)),t.attachDOMEvent(window,"load",this._WindowLoad,!1),t.attachDOMEvent(window,"unload",this._WindowUnload,!1),t.attachDOMEvent(document,"keyup",this.engine.hotkeyManager._Process,!1)},i.prototype.shutdown=function(){var t,e=this.domEventTracker,n=this.engine.config.hostDevice,c=this.window.document.body;e.detachDOMEvent(this.window,"focus",this.pageFocusHandler,!1),e.detachDOMEvent(this.window,"blur",this.pageFocusHandler,!1),e.detachDOMEvent(c,"focus",this.suppressFocusCheck,!0),e.detachDOMEvent(c,"blur",this.suppressFocusCheck,!0),n.touchable&&(e.detachDOMEvent(c,"touchstart",this.touchStartActivationHandler,!1),e.detachDOMEvent(c,"touchmove",this.touchMoveActivationHandler,!1),e.detachDOMEvent(c,"touchend",this.touchEndActivationHandler,!1),(t=this.mobilePageTrailer)===null||t===void 0||t.parentElement.removeChild(this.mobilePageTrailer)),e.detachDOMEvent(window,"load",this._WindowLoad,!1),e.detachDOMEvent(window,"unload",this._WindowUnload,!1),e.detachDOMEvent(document,"keyup",this.engine.hotkeyManager._Process,!1)},i}();function ce(i){var t=document.createElement(i);return t.style.userSelect="none",t.style.MozUserSelect="none",t.style.KhtmlUserSelect="none",t.style.UserSelect="none",t.style.WebkitUserSelect="none",t}function ve(i,t){try{if(i&&typeof window.getComputedStyle!="undefined")return window.getComputedStyle(i,"").getPropertyValue(t)}catch(e){}return""}function Zt(){try{if(this.device.formFactor=="desktop")return 1;var i=document.documentElement.clientWidth;if(screen.width>i)return 1;var t=screen.width;return this.landscapeView()?screen.widthscreen.height&&(t=screen.height),Math.round(100*t/i)/100}catch(e){return 1}}var si=function(){function i(t){this.keyman=t,this.scrolling=!1,this.shim=this.constructShim()}return i.prototype.constructShim=function(){var t=this,e=this,n=ce("div"),c=this.keyman.osk;return n.id="kmw-language-menu-background",n.addEventListener("touchstart",function(l){if(l.preventDefault(),e.hide(),l.touches.length>2){var r=l.touches[1].pageX,s=l.touches[1].pageY,B=c.vkbd.spaceBar;r>B.offsetLeft&&rB.offsetTop&&sr.scrollHeight-r.offsetHeight-1&&(r.scrollTop=r.scrollHeight-r.offsetHeight-1)},!1),this.activeLgNo=this.addLanguages(B,e);var y=B.childNodes.length-1;if(this.lgList.style.visibility="hidden",document.body.appendChild(this.lgList),t.OS=="android"&&"devicePixelRatio"in window&&(this.lgList.style.fontSize=2/window.devicePixelRatio+"em"),t.OS=="android"&&t.formFactor=="tablet"&&"devicePixelRatio"in window){var u=parseInt(ve(c,"width"),10),Q=c.style;isNaN(u)||(Q.width=Q.maxWidth=2*u/window.devicePixelRatio+"px"),u=parseInt(ve(r,"width"),10),Q=r.style,isNaN(u)||(Q.width=Q.maxWidth=2*u/window.devicePixelRatio+"px"),u=parseInt(ve(B,"width"),10),Q=B.style,isNaN(u)||(Q.width=Q.maxWidth=2*u/window.devicePixelRatio+"px")}this.adjust(0);var C=F.childNodes[1].offsetTop-F.childNodes[0].offsetTop,h=Math.floor(c.offsetHeight/26),b=Math.round(100*h/C)/100,U=b>.6?1:2;for(b>1.25&&(b=1.25),g=0;g<26;g++){var V=F.childNodes[g].style;U==2&&g%2==1?V.display="none":(V.fontSize=b*U+"em",V.lineHeight=h*U+"px")}var X=r.offsetWidth;r.scrollHeight>r.offsetHeight+3?X=X+F.offsetWidth:F.style.display="none",c.style.width=X+"px",this.lgList.style.visibility="",this.scrollToIndex(this.activeLgNo,r,B)}},i.prototype.adjust=function(t){var e=this.keyman.osk,n=this.keyman.config.hostDevice,c=this.lgList,l=c.firstChild,r=l.firstChild,s=0,B=c.style,o=c.childNodes[1],g=window.innerHeight-e.vkbd.lgKey.offsetHeight-16,a=r.childNodes.length+t-1,F=r.firstChild.firstChild.offsetHeight,y=a*F;n.OS=="ios"&&(n.formFactor=="phone"?(s=D()?36:0,g=(window.innerHeight-s-16)*Zt()):n.formFactor=="tablet"&&(s=D()?16:0,g=g-s)),B.left=v(e.vkbd.lgKey)+"px",y>g&&(y=g),B.height=y+"px",B.bottom="0px",o.style.height=l.style.height=B.height},i.prototype.scrollToLanguage=function(t,e,n){t.stopImmediatePropagation(),t.stopPropagation(),t.preventDefault();var c=t.touches[0].target;if(c.nodeName=="P"){var l,r,s=c.innerHTML.charCodeAt(0),B=n.childNodes;try{for(l=0;l=s));l++);}catch(o){}this.scrollToIndex(l,e,n)}},i.prototype.scrollToIndex=function(t,e,n){var c,l=.5;try{c=n.firstChild.getBoundingClientRect().height*(t-l)+1,e.scrollTop=c}catch(r){c=0}try{e.scrollTop<0&&(e.scrollTop=0),e.scrollTop>e.scrollHeight-e.offsetHeight-1&&(e.scrollTop=e.scrollHeight-e.offsetHeight-1)}catch(r){}},i.prototype.addLanguages=function(t,e){var n,c=e.length,l=this.keyman.config.hostDevice,r,s,B,o=[];for(s=0;s1)for(F.className="kbd-list",F.innerHTML=o[r]+"...",F.scrolled=!1,F.ontouchend=function(X){X.stopPropagation(),X.target.scrolled?X.target.scrolled=!1:this.parentNode.className=this.parentNode.className=="kbd-list-closed"?"kbd-list-open":"kbd-list-closed",V.adjust(this.parentNode.className=="kbd-list-closed"?0:this.kList.length)},F.addEventListener("touchstart",function(X){X.stopPropagation()},!1),F.addEventListener("touchmove",function(X){X.target.scrolled=!0,X.stopPropagation()},!1),y=0;y=u-1&&(l.y0=Q);else if(C>0)y.scrollTop<2&&(l.y0=Q);else return;return(C<-5||C>5)&&(l.scrolling=!0,this.className=this.className.replace(/\s*selected/,""),l.y0=Q),!0},g=function(F){return typeof F.stopImmediatePropagation!="undefined"?F.stopImmediatePropagation():F.stopPropagation(),l.scrolling?this.className=this.className.replace(/\s*selected/,""):(l.keyman.contextManager.focusAssistant.setFocusTimer(),l.lgList.style.display="none",l.keyman.contextManager.activateKeyboard(this.kn,this.kc,!0),l.keyman.contextManager.restoreLastActiveTarget(),l.hide()),s(),!0},a=function(F){s()};e.onmspointerdown=B,e.addEventListener("touchstart",B,!1),e.onmspointermove=o,e.addEventListener("touchmove",o,!1),e.onmspointerout=g,e.addEventListener("touchend",g,!1),e.addEventListener("touchcancel",a,!1)},i.prototype.hide=function(){var t=this,e=this.keyman.osk;this.lgList&&(e.vkbd.highlightKey(e.vkbd.lgKey,!1),this.lgList.style.visibility="hidden",window.setTimeout(function(){t.shim.parentElement&&(document.body.removeChild(t.shim),document.body.removeChild(t.lgList))},500)),this.keyman.touchLanguageMenu=null},i}();function Bi(i,t,e){var n=this,c=e.focusAssistant;t.on("globekey",function(l,r){r&&t.hostDevice.touchable&&(i.touchLanguageMenu=new si(i),i.touchLanguageMenu.show()),t.vkbd&&t.vkbd.highlightKey(l,!1)}),t.on("hiderequested",function(l){t&&(t.startHide(!0),e.forgetActiveTarget())}),t.addEventListener("hide",function(l){var r;l!=null&&l.HiddenByUser&&((r=e.activeTarget)===null||r===void 0||r.focus())}),t.on("showbuild",function(){var l;(l=i.config.alertHost)===null||l===void 0||l.alert("KeymanWeb Version "+Wt.VERSION+'

Copyright © 2007-2023 SIL International')}),t.on("dragmove",function(l){return(0,d.__awaiter)(n,void 0,void 0,function(){return(0,d.__generator)(this,function(r){switch(r.label){case 0:return c.restoringFocus=!0,[4,l];case 1:return r.sent(),e.restoreLastActiveTarget(),c.restoringFocus=!1,c.setMaintainingFocus(!1),[2]}})})}),t.on("resizemove",function(l){return(0,d.__awaiter)(n,void 0,void 0,function(){return(0,d.__generator)(this,function(r){switch(r.label){case 0:return c.restoringFocus=!0,[4,l];case 1:return r.sent(),e.restoreLastActiveTarget(),c.restoringFocus=!1,c.setMaintainingFocus(!1),[2]}})})}),t.on("pointerinteraction",function(l){return(0,d.__awaiter)(n,void 0,void 0,function(){return(0,d.__generator)(this,function(r){switch(r.label){case 0:return c.setMaintainingFocus(!0),[4,l];case 1:return r.sent(),c.setMaintainingFocus(!1),[2]}})})})}function Br(i){var t=document.createElement(i);return t.style.userSelect="none",t}var oi=function(){function i(t){this.getAbsoluteX=v,this.getAbsoluteY=Z,this._GetAbsoluteX=v,this._GetAbsoluteY=Z,this._GetAbsolute=this.getAbsolute,this.toNzString=this.nzString,this.createElement=Br,this.getStyleValue=ve,this.config=t,this.stylesheetManager=new Fe(document.body,t.applyCacheBusting),this.domEventTracker=new Ie}return i.prototype.isTouchDevice=function(){return this.config.hostDevice.touchable},i.prototype.getAbsolute=function(t){return{x:v(t),y:Z(t)}},i.prototype.getOption=function(t,e){return t in this.config.paths?this.config.paths[t]:t in this.config.options?this.config.options[t]:arguments.length>1?e:""},i.prototype.setOption=function(t,e){switch(t){case"attachType":break;case"ui":break;case"useAlerts":this.config.signalUser=e?new Ne:null;break;case"setActiveOnRegister":this.config.activateFirstKeyboard=!!e;break;case"spacebarText":this.config.spacebarText=e;break;default:throw new Error("Path-related options may not be changed after the engine has initialized.")}},i.prototype.loadCookie=function(t){var e=new se(t);return e.load(decodeURIComponent)},i.prototype.saveCookie=function(t,e){var n=new se(t);n.save(e,encodeURIComponent)},i.prototype.addStyleSheet=function(t){var e=Ve(t);return this.stylesheetManager.linkStylesheet(e),e},i.prototype.removeStyleSheet=function(t){return this.stylesheetManager.unlink(t)},i.prototype.linkStyleSheet=function(t){this.stylesheetManager.linkExternalSheet(t)},i.prototype.getLanguageCodes=function(t){return t.indexOf("-")==-1?[t]:t.split("-")},i.prototype.attachDOMEvent=function(t,e,n,c){this.domEventTracker.attachDOMEvent(t,e,n,c)},i.prototype.detachDOMEvent=function(t,e,n,c){this.domEventTracker.detachDOMEvent(t,e,n,c)},Object.defineProperty(i.prototype,"alertHost",{get:function(){return this.config.alertHost?this.config.alertHost:(this._alertHost||(this._alertHost=new Ne),this._alertHost)},enumerable:!1,configurable:!0}),i.prototype.alert=function(t,e){this.alertHost.alert(t,e)},i.prototype.nzString=function(t,e){var n="";return arguments.length>1&&(n=e),typeof t=="undefined"||t==null||t==0||t==""?n:""+t},i.prototype.toNumber=function(t,e){var n=parseInt(t,10);return isNaN(n)?e:n},i.prototype.toFloat=function(t,e){var n=parseFloat(t);return isNaN(n)?e:n},i.prototype.rgba=function(t,e,n,c,l){var r="transparent";try{r="rgba("+e+","+n+","+c+","+l+")"}catch(s){r="rgb("+e+","+n+","+c+")"}return r},i.prototype.shutdown=function(){var t,e,n;(t=this.stylesheetManager)===null||t===void 0||t.unlinkAll(),(e=this.domEventTracker)===null||e===void 0||e.shutdown(),(n=this._alertHost)===null||n===void 0||n.shutdown()},i}();var or=function(){function i(t,e,n){this.code=t,this.shift=e,this.handler=n}return i.prototype.matches=function(t,e){return this.code==t&&this.shift==e},i}(),ai=function(){function i(){var t=this;this.hotkeys=[],this._Process=function(e){e||(e=window.event);var n=Sn(e);if(n==null)return!1;for(var c=(e.shiftKey?16:0)|(e.ctrlKey?32:0)|(e.altKey?64:0),l=0;l=o&&(g-=window.innerHeight-c.osk._Box.offsetHeight-s.offsetHeight-2,g<0&&(g=0)),g!=0&&window.scrollTo(0,g+o)}}),c}return Object.defineProperty(t.prototype,"util",{get:function(){return this._util},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"views",{get:function(){return pn},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"initialized",{get:function(){return this._initialized},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"ui",{get:function(){return this._ui},set:function(e){this._ui&&this._ui.shutdown(),this._ui=e,this.config.deferForInitialization.hasResolved&&e.initialize()},enumerable:!1,configurable:!0}),t.prototype.init=function(e){return(0,d.__awaiter)(this,void 0,void 0,function(){var n,c,l,r,s=this;return(0,d.__generator)(this,function(B){switch(B.label){case 0:return n=new at,c=n.detect(),l=(0,d.__assign)((0,d.__assign)({},Pc),e),this.config.hostDevice=c,this.config.initialize(l),this._initialized=1,[4,tt()];case 1:return B.sent(),this.config.deferForInitialization.hasFinalized?[2,Promise.resolve()]:[4,i.prototype.init.call(this,l)];case 2:return B.sent(),this.keyboardRequisitioner.cloudQueryEngine.once("unboundregister",function(){var o;!((o=s.contextManager.activeKeyboard)===null||o===void 0)&&o.keyboard||s.setActiveKeyboard("","")}),this.contextManager.initialize(),r=this.contextManager.getSavedKeyboardRaw(),c.touchable?this.osk=new Gn(this):this.osk=new Xn(this),Bi(this,this.osk,this.contextManager),this.pageIntegration=new ri(window,this),String.kmwEnableSupplementaryPlane(!0),this.config.finalizeInit(),this.ui&&(this.ui.initialize(),this.legacyAPIEvents.callEvent("loaduserinterface",{})),this._initialized=2,[4,Promise.resolve()];case 3:return B.sent(),this.contextManager.restoreSavedKeyboard(r),[4,Promise.resolve()];case 4:return B.sent(),[2]}})})},Object.defineProperty(t.prototype,"register",{get:function(){return this.keyboardRequisitioner.cloudQueryEngine.registerFromCloud},enumerable:!1,configurable:!0}),t.prototype.getUIState=function(){return this.contextManager.focusAssistant.getUIState()},t.prototype.activatingUI=function(e){this.contextManager.focusAssistant.setMaintainingFocus(!!e)},t.prototype.setKeyboardForControl=function(e,n,c){if(e instanceof e.ownerDocument.defaultView.HTMLIFrameElement){console.warn("'keymanweb.setKeyboardForControl' cannot set keyboard on iframes.");return}if(!this.isAttached(e)){console.error("KeymanWeb is not attached to element "+e);return}var l=null;if(n&&(l=this.keyboardRequisitioner.cache.getStub(n,c),!l))throw new Error("No keyboard has been registered with id ".concat(n," and language code ").concat(c,"."));this.contextManager.setKeyboardForTarget(e._kmwAttachment.interface,n,c)},t.prototype.getKeyboardForControl=function(e){var n=he(e);return this.contextManager.getKeyboardStubForTarget(n).id},t.prototype.getLanguageForControl=function(e){var n=he(e);return this.contextManager.getKeyboardStubForTarget(n).langId},t.prototype.isAttached=function(e){return this.contextManager.page.isAttached(e)},t.prototype.addKeyboards=function(){for(var e=this,n=[],c=0;c= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n /** @deprecated */\r\n \r\n\r\n /** @deprecated */\r\n \r\n\r\n \r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n \r\n exporter(\"__decorate\", __decorate);\r\n \r\n \r\n \r\n \r\n \r\n \r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n exporter(\"__await\", __await);\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n});\r\n", + "'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n", + "export * from '../../../../node_modules/tslib/tslib.js';\r\n\r\nexport * as tslib from '../../../../node_modules/tslib/tslib.js';", + "import EventEmitter from \"eventemitter3\";\r\n\r\nimport { DeviceSpec, KeyboardProperties, ManagedPromise, OutputTarget, physicalKeyDeviceAlias, RuleBehavior, SpacebarText } from \"@keymanapp/keyboard-processor\";\r\nimport { PathConfiguration, PathOptionDefaults, PathOptionSpec } from \"keyman/engine/paths\";\r\nimport { Device } from \"keyman/engine/device-detect\";\r\nimport { KeyboardStub } from \"keyman/engine/package-cache\";\r\n\r\ninterface EventMap {\r\n 'spacebartext': (mode: SpacebarText) => void;\r\n}\r\n\r\nexport class EngineConfiguration extends EventEmitter {\r\n // The app/webview path replaces this during init, but we expect to have something set for this\r\n // during engine construction, which occurs earlier. So no `readonly`, sadly.\r\n //\r\n // May also be manipulated by Developer's debug-host?\r\n public hostDevice: DeviceSpec;\r\n readonly sourcePath: string;\r\n readonly deferForInitialization: ManagedPromise;\r\n\r\n private _paths: PathConfiguration;\r\n public activateFirstKeyboard: boolean;\r\n private _spacebarText: SpacebarText;\r\n private _stubNamespacer?: (KeyboardStub) => void;\r\n\r\n public applyCacheBusting: boolean = false;\r\n\r\n // sourcePath: see `var sPath =` in kmwbase.ts. It is not obtainable headlessly.\r\n constructor(sourcePath: string, device?: DeviceSpec) {\r\n super();\r\n\r\n if(!device) {\r\n const deviceDetector = new Device();\r\n deviceDetector.detect();\r\n\r\n device = deviceDetector.coreSpec;\r\n }\r\n\r\n this.sourcePath = sourcePath;\r\n this.hostDevice = device;\r\n this.deferForInitialization = new ManagedPromise();\r\n }\r\n\r\n initialize(options: Required) {\r\n if(!this._paths) {\r\n this._paths = new PathConfiguration(options, this.sourcePath);\r\n } else {\r\n this._paths.updateFromOptions(options);\r\n }\r\n\r\n if(typeof options.setActiveOnRegister == 'boolean') {\r\n this.activateFirstKeyboard = options.setActiveOnRegister;\r\n } else {\r\n this.activateFirstKeyboard = true;\r\n }\r\n\r\n this._spacebarText = options.spacebarText;\r\n\r\n // Make sure this is accessible to stubs for use in generating display names!\r\n KeyboardProperties.spacebarTextMode = () => this.spacebarText;\r\n }\r\n\r\n finalizeInit() {\r\n this.deferForInitialization.resolve();\r\n }\r\n\r\n get paths() {\r\n return this._paths;\r\n }\r\n\r\n get spacebarText() {\r\n return this._spacebarText;\r\n }\r\n\r\n set spacebarText(value: SpacebarText) {\r\n if(this._spacebarText != value) {\r\n this._spacebarText = value;\r\n this.emit('spacebartext', value);\r\n }\r\n }\r\n\r\n get softDevice(): DeviceSpec {\r\n return this.hostDevice;\r\n }\r\n\r\n get hardDevice(): DeviceSpec {\r\n return physicalKeyDeviceAlias(this.hostDevice);\r\n }\r\n\r\n get stubNamespacer() {\r\n return this._stubNamespacer;\r\n }\r\n\r\n set stubNamespacer(functor: (stub: KeyboardStub) => void) {\r\n this._stubNamespacer = functor;\r\n }\r\n\r\n debugReport(): Record {\r\n return {\r\n hostDevice: this.hostDevice,\r\n initialized: this.deferForInitialization.hasFinalized\r\n }\r\n }\r\n\r\n /**\r\n * Facilitates implementation of additional functionality for finalized keystroke-event rules\r\n * after postKeystroke takes effect. Any behaviors defined here should be considered 'readonly' in\r\n * terms of context and should instead facilitate integration with the engine's host platform.\r\n * @param ruleBehavior The full effects of keystroke + postkeystroke rules from a processed keystroke.\r\n * @param outputTarget The engine's current source for context\r\n */\r\n onRuleFinalization(ruleBehavior: RuleBehavior, outputTarget: OutputTarget) {};\r\n}\r\n\r\nexport interface InitOptionSpec extends PathOptionSpec {\r\n /**\r\n * If set to true || \"true\" or if left undefined, the engine will automatically select the first available\r\n * keyboard for activation.\r\n *\r\n * Note that keyboards specified locally are synchronously loaded while cloud keyboards are async; as a\r\n * result, a locally-specified keyboard will generally be available \"sooner\", even if added \"later\".\r\n */\r\n setActiveOnRegister?: boolean;\r\n\r\n /**\r\n * Determines the default text shown on the spacebar. If undefined, uses `LANGUAGE_KEYBOARD`\r\n */\r\n spacebarText?: SpacebarText;\r\n}\r\n\r\nexport const InitOptionDefaults: Required = {\r\n setActiveOnRegister: true, // only needed for browser?\r\n spacebarText: SpacebarText.LANGUAGE_KEYBOARD, // useful in both, for OSK config.\r\n ...PathOptionDefaults\r\n}", + "// TODO: Move to separate folder: 'codes'\r\n// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.\r\n// There's an upcoming `/common/web/types` package that 'codes' and 'keyboards' may fit well within.\r\n// In fact, there's a file there (on its branch) that should be merged with this one!\r\n\r\nconst Codes = {\r\n // Define Keyman Developer modifier bit-flags (exposed for use by other modules)\r\n // Compare against /common/include/kmx_file.h. CTRL+F \"#define LCTRLFLAG\" to find the secton.\r\n modifierCodes: {\r\n \"LCTRL\":0x0001, // LCTRLFLAG\r\n \"RCTRL\":0x0002, // RCTRLFLAG\r\n \"LALT\":0x0004, // LALTFLAG\r\n \"RALT\":0x0008, // RALTFLAG\r\n \"SHIFT\":0x0010, // K_SHIFTFLAG\r\n \"CTRL\":0x0020, // K_CTRLFLAG\r\n \"ALT\":0x0040, // K_ALTFLAG\r\n // TENTATIVE: Represents command keys, which some OSes use for shortcuts we don't\r\n // want to block. No rule will ever target a modifier set with this bit set to 1.\r\n \"META\":0x0080, // K_METAFLAG\r\n \"CAPS\":0x0100, // CAPITALFLAG\r\n \"NO_CAPS\":0x0200, // NOTCAPITALFLAG\r\n \"NUM_LOCK\":0x0400, // NUMLOCKFLAG\r\n \"NO_NUM_LOCK\":0x0800, // NOTNUMLOCKFLAG\r\n \"SCROLL_LOCK\":0x1000, // SCROLLFLAG\r\n \"NO_SCROLL_LOCK\":0x2000, // NOTSCROLLFLAG\r\n \"VIRTUAL_KEY\":0x4000, // ISVIRTUALKEY\r\n \"VIRTUAL_CHAR_KEY\":0x8000 // VIRTUALCHARKEY // Unused by KMW, but reserved for use by other Keyman engines.\r\n },\r\n\r\n modifierBitmasks: {\r\n \"ALL\":0x007F,\r\n \"ALT_GR_SIM\": (0x0001 | 0x0004),\r\n \"CHIRAL\":0x001F, // The base bitmask for chiral keyboards. Includes SHIFT, which is non-chiral.\r\n \"IS_CHIRAL\":0x000F, // Used to test if a bitmask uses a chiral modifier.\r\n \"NON_CHIRAL\":0x0070 // The default bitmask, for non-chiral keyboards\r\n },\r\n\r\n stateBitmasks: {\r\n \"ALL\":0x3F00,\r\n \"CAPS\":0x0300,\r\n \"NUM_LOCK\":0x0C00,\r\n \"SCROLL_LOCK\":0x3000\r\n },\r\n\r\n // Define standard keycode numbers (exposed for use by other modules)\r\n keyCodes: {\r\n \"K_BKSP\":8,\"K_TAB\":9,\"K_ENTER\":13,\r\n \"K_SHIFT\":16,\"K_CONTROL\":17,\"K_ALT\":18,\"K_PAUSE\":19,\"K_CAPS\":20,\r\n \"K_ESC\":27,\"K_SPACE\":32,\"K_PGUP\":33,\r\n \"K_PGDN\":34,\"K_END\":35,\"K_HOME\":36,\"K_LEFT\":37,\"K_UP\":38,\r\n \"K_RIGHT\":39,\"K_DOWN\":40,\"K_SEL\":41,\"K_PRINT\":42,\"K_EXEC\":43,\r\n \"K_INS\":45,\"K_DEL\":46,\"K_HELP\":47,\"K_0\":48,\r\n \"K_1\":49,\"K_2\":50,\"K_3\":51,\"K_4\":52,\"K_5\":53,\"K_6\":54,\"K_7\":55,\r\n \"K_8\":56,\"K_9\":57,\"K_A\":65,\"K_B\":66,\"K_C\":67,\"K_D\":68,\"K_E\":69,\r\n \"K_F\":70,\"K_G\":71,\"K_H\":72,\"K_I\":73,\"K_J\":74,\"K_K\":75,\"K_L\":76,\r\n \"K_M\":77,\"K_N\":78,\"K_O\":79,\"K_P\":80,\"K_Q\":81,\"K_R\":82,\"K_S\":83,\r\n \"K_T\":84,\"K_U\":85,\"K_V\":86,\"K_W\":87,\"K_X\":88,\"K_Y\":89,\"K_Z\":90,\r\n \"K_NP0\":96,\"K_NP1\":97,\"K_NP2\":98,\r\n \"K_NP3\":99,\"K_NP4\":100,\"K_NP5\":101,\"K_NP6\":102,\r\n \"K_NP7\":103,\"K_NP8\":104,\"K_NP9\":105,\"K_NPSTAR\":106,\r\n \"K_NPPLUS\":107,\"K_SEPARATOR\":108,\"K_NPMINUS\":109,\"K_NPDOT\":110,\r\n \"K_NPSLASH\":111,\"K_F1\":112,\"K_F2\":113,\"K_F3\":114,\"K_F4\":115,\r\n \"K_F5\":116,\"K_F6\":117,\"K_F7\":118,\"K_F8\":119,\"K_F9\":120,\r\n \"K_F10\":121,\"K_F11\":122,\"K_F12\":123,\"K_NUMLOCK\":144,\"K_SCROLL\":145,\r\n \"K_LSHIFT\":160,\"K_RSHIFT\":161,\"K_LCONTROL\":162,\"K_RCONTROL\":163,\r\n \"K_LALT\":164,\"K_RALT\":165,\r\n \"K_COLON\":186,\"K_EQUAL\":187,\"K_COMMA\":188,\"K_HYPHEN\":189,\r\n \"K_PERIOD\":190,\"K_SLASH\":191,\"K_BKQUOTE\":192,\r\n \"K_LBRKT\":219,\"K_BKSLASH\":220,\"K_RBRKT\":221,\r\n \"K_QUOTE\":222,\"K_oE2\":226,\"K_OE2\":226,\r\n \"K_LOPT\":50001,\"K_ROPT\":50002,\r\n \"K_NUMERALS\":50003,\"K_SYMBOLS\":50004,\"K_CURRENCIES\":50005,\r\n \"K_UPPER\":50006,\"K_LOWER\":50007,\"K_ALPHA\":50008,\r\n \"K_SHIFTED\":50009,\"K_ALTGR\":50010,\r\n \"K_TABBACK\":50011,\"K_TABFWD\":50012\r\n },\r\n\r\n codesUS: [\r\n ['0123456789',';=,-./`', '[\\\\]\\''],\r\n [')!@#$%^&*(',':+<_>?~', '{|}\"']\r\n ],\r\n\r\n isKnownOSKModifierKey(keyID: string): boolean {\r\n switch(keyID) {\r\n case 'K_SHIFT':\r\n case 'K_LOPT':\r\n case 'K_ROPT':\r\n case 'K_NUMLOCK': // Often used for numeric layers.\r\n case 'K_CAPS':\r\n return true;\r\n default:\r\n if(Codes.keyCodes[keyID] >= 50000) { // A few are used by `sil_euro_latin`.\r\n return true; // is a 'K_' key defined for layer shifting or 'control' use.\r\n }\r\n // Refer to text/codes.ts - these are Keyman-custom \"keycodes\" used for\r\n // layer shifting keys. To be safe, we currently let K_TABBACK and\r\n // K_TABFWD through, though we might be able to drop them too.\r\n const code = Codes[keyID];\r\n if(code > 50000 && code < 50011) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n\r\n\r\n /**\r\n * Get modifier key state from layer id\r\n *\r\n * @param {string} layerId layer id (e.g. ctrlshift)\r\n * @return {number} modifier key state (desktop keyboards)\r\n */\r\n getModifierState(layerId: string): number {\r\n var modifier=0;\r\n if(layerId.indexOf('shift') >= 0) {\r\n modifier |= Codes.modifierCodes['SHIFT'];\r\n }\r\n\r\n // The chiral checks must not be directly exclusive due each other to visual OSK feedback.\r\n var ctrlMatched=false;\r\n if(layerId.indexOf('leftctrl') >= 0) {\r\n modifier |= Codes.modifierCodes['LCTRL'];\r\n ctrlMatched=true;\r\n }\r\n if(layerId.indexOf('rightctrl') >= 0) {\r\n modifier |= Codes.modifierCodes['RCTRL'];\r\n ctrlMatched=true;\r\n }\r\n if(layerId.indexOf('ctrl') >= 0 && !ctrlMatched) {\r\n modifier |= Codes.modifierCodes['CTRL'];\r\n }\r\n\r\n var altMatched=false;\r\n if(layerId.indexOf('leftalt') >= 0) {\r\n modifier |= Codes.modifierCodes['LALT'];\r\n altMatched=true;\r\n }\r\n if(layerId.indexOf('rightalt') >= 0) {\r\n modifier |= Codes.modifierCodes['RALT'];\r\n altMatched=true;\r\n }\r\n if(layerId.indexOf('alt') >= 0 && !altMatched) {\r\n modifier |= Codes.modifierCodes['ALT'];\r\n }\r\n\r\n return modifier;\r\n },\r\n\r\n /**\r\n * Get state key state from layer id\r\n *\r\n * @param {string} layerId layer id (e.g. caps)\r\n * @return {number} modifier key state (desktop keyboards)\r\n */\r\n getStateFromLayer(layerId: string): number {\r\n var modifier=0;\r\n\r\n if(layerId.indexOf('caps') >= 0) {\r\n modifier |= Codes.modifierCodes['CAPS'];\r\n } else {\r\n modifier |= Codes.modifierCodes['NO_CAPS'];\r\n }\r\n\r\n return modifier;\r\n }\r\n}\r\n\r\nexport default Codes;", + "// TODO: Move to separate folder: 'codes'\r\n// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.\r\n// There's an upcoming `/common/web/types` package that 'codes' and 'keyboards' may fit well within.\r\n\r\nimport Codes from \"./codes.js\";\r\nimport type KeyEvent from \"./keyEvent.js\";\r\nimport type OutputTarget from \"./outputTarget.js\";\r\n\r\n// The only members referenced are to produce warning and error logs. A little abstraction\r\n// via an optional 'logger' interface can maintain it while facilitating a the split alluded\r\n// to above.\r\n//\r\n// Alternatively, we could just... not take in the parameter at all, which'd also facilitate\r\n// the future modularization effort.\r\nimport RuleBehavior from \"./ruleBehavior.js\";\r\n\r\nexport enum EmulationKeystrokes {\r\n Enter = '\\n',\r\n Backspace = '\\b'\r\n}\r\n\r\n/**\r\n * Defines a collection of static library functions that define KeymanWeb's default (implied) keyboard rule behaviors.\r\n */\r\nexport default class DefaultRules {\r\n public constructor() {\r\n }\r\n\r\n codeForEvent(Lkc: KeyEvent) {\r\n return Codes.keyCodes[Lkc.kName] || Lkc.Lcode;;\r\n }\r\n\r\n /**\r\n * Serves as a default keycode lookup table. This may be referenced safely by mnemonic handling without fear of side-effects.\r\n * Also used by Processor.defaultRuleBehavior to generate output after filtering for special cases.\r\n */\r\n public forAny(Lkc: KeyEvent, isMnemonic: boolean, ruleBehavior?: RuleBehavior) {\r\n var char = '';\r\n\r\n // A pretty simple table of lookups, corresponding VERY closely to the original defaultKeyOutput.\r\n if((char = this.forSpecialEmulation(Lkc)) != null) {\r\n return char;\r\n } else if(!isMnemonic && ((char = this.forNumpadKeys(Lkc)) != null)) {\r\n return char;\r\n } else if((char = this.forUnicodeKeynames(Lkc, ruleBehavior)) != null) {\r\n return char;\r\n } else if((char = this.forBaseKeys(Lkc, ruleBehavior)) != null) {\r\n return char;\r\n } else {\r\n // // For headless and embeddded, we may well allow '\\t'. It's DOM mode that has other uses.\r\n // // Not originally defined for text output within defaultKeyOutput.\r\n // // We can't enable it yet, as it'll cause hardware keystrokes in the DOM to output '\\t' rather\r\n // // than rely on the browser-default handling.\r\n let code = this.codeForEvent(Lkc);\r\n switch(code) {\r\n // case Codes.keyCodes['K_TAB']:\r\n // case Codes.keyCodes['K_TABBACK']:\r\n // case Codes.keyCodes['K_TABFWD']:\r\n // return '\\t';\r\n default:\r\n return null;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * isCommand - returns a boolean indicating if a non-text event should be triggered by the keystroke.\r\n */\r\n public isCommand(Lkc: KeyEvent): boolean {\r\n let code = this.codeForEvent(Lkc);\r\n\r\n switch(code) {\r\n // Should we ever implement them:\r\n // case Codes.keyCodes['K_LEFT']: // would not output text, but would alter the caret's position in the context.\r\n // case Codes.keyCodes['K_RIGHT']:\r\n // return true;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Used when a RuleBehavior represents a non-text \"command\" within the Engine. This will generally\r\n * trigger events that require context reset - often by moving the caret or by moving what OutputTarget\r\n * the caret is in. However, we let those events perform the actual context reset.\r\n *\r\n * Note: is extended by DOM-aware KeymanWeb code.\r\n */\r\n public applyCommand(Lkc: KeyEvent, outputTarget: OutputTarget): void {\r\n // Notes for potential default-handling extensions:\r\n //\r\n // switch(code) {\r\n // // Problem: clusters, and doing them right.\r\n // // The commented-out code below should be a decent starting point, but clusters make it complex.\r\n // // Mostly based on pre-12.0 code, but the general idea should be relatively clear.\r\n //\r\n // case Codes.keyCodes['K_LEFT']:\r\n // if(touchAlias) {\r\n // var caretPos = keymanweb.getTextCaret(Lelem);\r\n // keymanweb.setTextCaret(Lelem, caretPos - 1 >= 0 ? caretPos - 1 : 0);\r\n // }\r\n // break;\r\n // case Codes.keyCodes['K_RIGHT']:\r\n // if(touchAlias) {\r\n // var caretPos = keymanweb.getTextCaret(Lelem);\r\n // keymanweb.setTextCaret(Lelem, caretPos + 1);\r\n // }\r\n // if(code == VisualKeyboard.keyCodes['K_RIGHT']) {\r\n // break;\r\n // }\r\n // }\r\n //\r\n // Note that these would be useful even outside of a DOM context.\r\n }\r\n\r\n /**\r\n * Codes matched here generally have default implementations when in a browser but require emulation\r\n * for 'synthetic' `OutputTarget`s like `Mock`s, which have no default text handling.\r\n */\r\n public forSpecialEmulation(Lkc: KeyEvent): EmulationKeystrokes {\r\n let code = this.codeForEvent(Lkc);\r\n\r\n switch(code) {\r\n case Codes.keyCodes['K_BKSP']:\r\n return EmulationKeystrokes.Backspace;\r\n case Codes.keyCodes['K_ENTER']:\r\n return EmulationKeystrokes.Enter;\r\n // case Codes.keyCodes['K_DEL']:\r\n // return '\\u007f'; // 127, ASCII / Unicode control code for DEL.\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n // Should not be used for mnenomic keyboards. forAny()'s use of this method checks first.\r\n public forNumpadKeys(Lkc: KeyEvent) {\r\n // Translate numpad keystrokes into their non-numpad equivalents\r\n if(Lkc.Lcode >= Codes.keyCodes[\"K_NP0\"] && Lkc.Lcode <= Codes.keyCodes[\"K_NPSLASH\"]) {\r\n // Number pad, numlock on\r\n if(Lkc.Lcode < 106) {\r\n var Lch = Lkc.Lcode-48;\r\n } else {\r\n Lch = Lkc.Lcode-64;\r\n }\r\n let ch = String._kmwFromCharCode(Lch); //I3319\r\n return ch;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n // Test for fall back to U_xxxxxx key id\r\n // For this first test, we ignore the keyCode and use the keyName\r\n public forUnicodeKeynames(Lkc: KeyEvent, ruleBehavior?: RuleBehavior) {\r\n const keyName = Lkc.kName;\r\n\r\n // Test for fall back to U_xxxxxx key id\r\n // For this first test, we ignore the keyCode and use the keyName\r\n if(!keyName || keyName.substr(0,2) != 'U_') {\r\n return null;\r\n }\r\n\r\n let result = '';\r\n const codePoints = keyName.substr(2).split('_');\r\n for(let codePoint of codePoints) {\r\n const codePointValue = parseInt(codePoint, 16);\r\n if (((0x0 <= codePointValue) && (codePointValue <= 0x1F)) || ((0x80 <= codePointValue) && (codePointValue <= 0x9F)) || isNaN(codePointValue)) {\r\n // Code points [U_0000 - U_001F] and [U_0080 - U_009F] refer to Unicode C0 and C1 control codes.\r\n // Check the codePoint number and do not allow output of these codes via U_xxxxxx shortcuts.\r\n // Also handles invalid identifiers (e.g. `U_ghij`) for which parseInt returns NaN\r\n if(ruleBehavior) {\r\n ruleBehavior.errorLog = (\"Suppressing Unicode control code in \" + keyName);\r\n }\r\n // We'll attempt to add valid chars\r\n continue;\r\n } else {\r\n // String.fromCharCode() is inadequate to handle the entire range of Unicode\r\n // Someday after upgrading to ES2015, can use String.fromCodePoint()\r\n result += String.kmwFromCharCode(codePointValue);\r\n }\r\n }\r\n return result ? result : null;\r\n }\r\n\r\n // Test for otherwise unimplemented keys on the the base default & shift layers.\r\n // Those keys must be blocked by keyboard rules if intentionally unimplemented; otherwise, this function will trigger.\r\n public forBaseKeys(Lkc: KeyEvent, ruleBehavior?: RuleBehavior) {\r\n let n = Lkc.Lcode;\r\n let keyShiftState = Lkc.Lmodifiers;\r\n\r\n // check if exact match to SHIFT's code. Only the 'default' and 'shift' layers should have default key outputs.\r\n // TODO: Extend to allow AltGr as well - better mnemonic support.\r\n if(keyShiftState == Codes.modifierCodes['SHIFT']) {\r\n keyShiftState = 1;\r\n } else if(keyShiftState != 0) {\r\n if(ruleBehavior) {\r\n ruleBehavior.warningLog = \"KMW only defines default key output for the 'default' and 'shift' layers!\";\r\n }\r\n return null;\r\n }\r\n\r\n // Now that keyShiftState is either 0 or 1, we can use the following structure to determine the default output.\r\n try {\r\n if(n == Codes.keyCodes['K_SPACE']) {\r\n return ' ';\r\n } else if(n >= Codes.keyCodes['K_0'] && n <= Codes.keyCodes['K_9']) { // The number keys.\r\n return Codes.codesUS[keyShiftState][0][n-Codes.keyCodes['K_0']];\r\n } else if(n >= Codes.keyCodes['K_A'] && n <= Codes.keyCodes['K_Z']) { // The base letter keys\r\n return String.fromCharCode(n+(keyShiftState?0:32)); // 32 is the offset from uppercase to lowercase.\r\n } else if(n >= Codes.keyCodes['K_COLON'] && n <= Codes.keyCodes['K_BKQUOTE']) {\r\n return Codes.codesUS[keyShiftState][1][n-Codes.keyCodes['K_COLON']];\r\n } else if(n >= Codes.keyCodes['K_LBRKT'] && n <= Codes.keyCodes['K_QUOTE']) {\r\n return Codes.codesUS[keyShiftState][2][n-Codes.keyCodes['K_LBRKT']];\r\n } else if(n == Codes.keyCodes['K_oE2']) {\r\n return keyShiftState ? '|' : '\\\\';\r\n }\r\n } catch (e) {\r\n if(ruleBehavior) {\r\n ruleBehavior.errorLog = \"Error detected with default mapping for key: code = \" + n + \", shift state = \" + (keyShiftState == 1 ? 'shift' : 'default');\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n}\r\n", + "// TODO: Move to separate folder: 'codes'\r\n// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.\r\n// There's an upcoming `/common/web/types` package that 'codes' and 'keyboards' may fit well within.\r\n\r\n// KeyEvent may be a _little_ bit of pollution, but this IS what the Web OSK currently generates to signal\r\n// a key event. The most straightforward way to integrate Web OSK events on other platforms is to have\r\n// other platforms recognize and utilize this type.\r\n\r\nimport type Keyboard from \"../keyboards/keyboard.js\";\r\nimport { type DeviceSpec } from \"@keymanapp/web-utils\";\r\n\r\nimport Codes from './codes.js';\r\nimport DefaultRules from './defaultRules.js';\r\n\r\n// Represents a probability distribution over a keyboard's keys.\r\n// Defined here to avoid compilation issues.\r\nexport type KeyDistribution = {keyId: string, p: number}[];\r\n\r\n/**\r\n * A simple instance of the standard 'default rules' for keystroke processing from the\r\n * DefaultRules base class.\r\n */\r\nconst BASE_DEFAULT_RULES = new DefaultRules();\r\n\r\nexport interface KeyEventSpec {\r\n\r\n Lcode: number;\r\n Lstates: number;\r\n LmodifierChange?: boolean;\r\n Lmodifiers: number;\r\n LisVirtualKey?: boolean;\r\n vkCode?: number;\r\n kName: string;\r\n kLayer?: string; // The key's layer property\r\n kbdLayer?: string; // The virtual keyboard's active layer\r\n kNextLayer?: string;\r\n\r\n /**\r\n * Marks the active keyboard at the time that this KeyEvent was generated by the user.\r\n *\r\n * Note: this is NOT equivalent to the active keyboard at the time that the event handler begins\r\n * processing! It should be set via closure (or similar) on the event handler that can 100%\r\n * guarantee that the keyboard instance known to the handler has not changed during JS execution\r\n * since the user's interaction that raised the event.\r\n */\r\n srcKeyboard?: Keyboard;\r\n\r\n // Holds relevant event properties leading to construction of this KeyEvent.\r\n source?: any; // Technically, KeyEvent|MouseEvent|Touch - but those are DOM types that must be kept out of headless mode.\r\n // Holds a generated fat-finger distribution (when appropriate)\r\n keyDistribution?: KeyDistribution;\r\n\r\n /**\r\n * The device model for web-core to follow when processing the keystroke.\r\n */\r\n device: DeviceSpec;\r\n\r\n /**\r\n * `true` if this event was produced by sources other than a DOM-based KeyboardEvent.\r\n */\r\n isSynthetic?: boolean;\r\n}\r\n\r\n/**\r\n * This class is defined within its own file so that it can be loaded by code outside of KMW without\r\n * having to actually load the entirety of KMW.\r\n */\r\nexport default class KeyEvent implements KeyEventSpec {\r\n Lcode: number;\r\n Lstates: number;\r\n LmodifierChange?: boolean;\r\n Lmodifiers: number;\r\n LisVirtualKey?: boolean;\r\n vkCode?: number;\r\n kName: string;\r\n kLayer?: string; // The key's layer property\r\n kbdLayer?: string; // The virtual keyboard's active layer\r\n kNextLayer?: string;\r\n\r\n /**\r\n * Marks the active keyboard at the time that this KeyEvent was generated by the user.\r\n *\r\n * Note: this is NOT equivalent to the active keyboard at the time that the event handler begins\r\n * processing! It should be set via closure (or similar) on the event handler that can 100%\r\n * guarantee that the keyboard instance known to the handler has not changed during JS execution\r\n * since the user's interaction that raised the event.\r\n */\r\n srcKeyboard?: Keyboard;\r\n\r\n // Holds relevant event properties leading to construction of this KeyEvent.\r\n source?: any; // Technically, KeyEvent|MouseEvent|Touch - but those are DOM types that must be kept out of headless mode.\r\n // Holds a generated fat-finger distribution (when appropriate)\r\n keyDistribution?: KeyDistribution;\r\n\r\n /**\r\n * The device model for web-core to follow when processing the keystroke.\r\n */\r\n device: DeviceSpec;\r\n\r\n /**\r\n * `true` if this event was produced by sources other than a DOM-based KeyboardEvent.\r\n */\r\n isSynthetic: boolean = true;\r\n\r\n public constructor(keyEventSpec: KeyEventSpec) {\r\n for(let key in keyEventSpec) {\r\n if(keyEventSpec[key] !== undefined) {\r\n this[key] = keyEventSpec[key];\r\n }\r\n }\r\n }\r\n\r\n public static constructNullKeyEvent(device: DeviceSpec): KeyEvent {\r\n const keyEvent = new KeyEvent({\r\n Lcode: 0,\r\n kName: '',\r\n device: device,\r\n Lstates: undefined,\r\n Lmodifiers: undefined,\r\n vkCode: undefined,\r\n LisVirtualKey: undefined\r\n });\r\n return keyEvent;\r\n }\r\n\r\n get isModifier(): boolean {\r\n switch(this.Lcode) {\r\n case 16: //\"K_SHIFT\":16,\"K_CONTROL\":17,\"K_ALT\":18\r\n case 17:\r\n case 18:\r\n case 20: //\"K_CAPS\":20, \"K_NUMLOCK\":144,\"K_SCROLL\":145\r\n case 144:\r\n case 145:\r\n return true;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n // FIXME: makes some bad assumptions.\r\n setMnemonicCode(shifted: boolean, capsActive: boolean) {\r\n // K_SPACE is not handled by defaultKeyOutput for physical keystrokes unless using touch-aliased elements.\r\n // It's also a \"exception required, March 2013\" for clickKey, so at least they both have this requirement.\r\n if(this.Lcode != Codes.keyCodes['K_SPACE']) {\r\n // So long as the key name isn't prefixed with 'U_', we'll get a default mapping based on the Lcode value.\r\n // We need to determine the mnemonic base character - for example, SHIFT + K_PERIOD needs to map to '>'.\r\n let mappingEvent: KeyEvent = new KeyEvent(this);\r\n for(let key in (this as KeyEvent)) {\r\n mappingEvent[key] = this[key];\r\n }\r\n\r\n // To facilitate storing relevant commands, we should probably reverse-lookup\r\n // the actual keyname instead.\r\n mappingEvent.kName = 'K_xxxx';\r\n mappingEvent.Lmodifiers = (shifted ? 0x10 : 0); // mnemonic lookups only exist for default & shift layers.\r\n var mappedChar: string = BASE_DEFAULT_RULES.forAny(mappingEvent, true);\r\n\r\n /* First, save a backup of the original code. This one won't needlessly trigger keyboard\r\n * rules, but allows us to replicate/emulate commands after rule processing if needed.\r\n * (Like backspaces)\r\n */\r\n this.vkCode = this.Lcode;\r\n if(mappedChar) {\r\n // Will return 96 for 'a', which is a keycode corresponding to Codes.keyCodes('K_NP1') - a numpad key.\r\n // That stated, we're in mnemonic mode - this keyboard's rules are based on the char codes.\r\n this.Lcode = mappedChar.charCodeAt(0);\r\n } else {\r\n // Don't let command-type keys (like K_DEL, which will output '.' otherwise!)\r\n // trigger keyboard rules.\r\n //\r\n // However, DO make sure modifier keys pass through safely.\r\n // (https://github.com/keymanapp/keyman/issues/3744)\r\n if(!this.isModifier) {\r\n delete this.Lcode;\r\n }\r\n }\r\n }\r\n\r\n if(capsActive) {\r\n // TODO: Needs fixing - does not properly mirror physical keystrokes, as Lcode range 96-111 corresponds\r\n // to numpad keys! (Physical keyboard section has its own issues here.)\r\n if((this.Lcode >= 65 && this.Lcode <= 90) /* 'A' - 'Z' */ || (this.Lcode >= 97 && this.Lcode <= 122) /* 'a' - 'z' */) {\r\n this.Lmodifiers ^= 0x10; // Flip the 'shifted' bit, so it'll act as the opposite key.\r\n this.Lcode ^= 0x20; // Flips the 'upper' vs 'lower' bit for the base 'a'-'z' ASCII alphabetics.\r\n }\r\n }\r\n }\r\n};", + "/***\r\n KeymanWeb 11.0\r\n Copyright 2019 SIL International\r\n***/\r\n\r\nimport type KeyEvent from \"./keyEvent.js\";\r\nimport { KeyEventSpec } from \"./keyEvent.js\";\r\n\r\nclass KeyMap {\r\n [keycode: string]: number;\r\n}\r\n\r\nclass BrowserKeyMaps {\r\n FF: KeyMap = new KeyMap();\r\n Safari: KeyMap = new KeyMap();\r\n Opera: KeyMap = new KeyMap();\r\n\r\n constructor() {\r\n // All three have been around since at least May 2014 / FF 29.\r\n // It'd hard to find precise history, but at least that much has been confirmed.\r\n // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode, on Feb 26 2021.\r\n this.FF['k61'] = 187; // = // FF 2.0\r\n this.FF['k59'] = 186; // ;\r\n this.FF['k173'] = 189; // -/_\r\n }\r\n}\r\n\r\nclass LanguageKeyMaps {\r\n [languageCode: string]: KeyMap;\r\n\r\n // // Here are some old legacy definitions that were no longer referenced but are likely related:\r\n // static _BaseLayoutEuro: {[code: string]: string} = {\r\n // 'se': '\\u00a71234567890+´~~~QWERTYUIOP\\u00c5\\u00a8\\'~~~ASDFGHJKL\\u00d6\\u00c4~~~~~ ` ~\r\n this['uk']['k192'] = 222; // ' @ => ' \"\r\n this['uk']['k222'] = 226; // # ~ => K_oE2 // I1504 - UK keyboard mixup #, \\\r\n this['uk']['k220'] = 220; // \\ | => \\ | // I1504 - UK keyboard mixup #, \\\r\n }\r\n}\r\n\r\nexport default class KeyMapping {\r\n static readonly browserMap: BrowserKeyMaps = new BrowserKeyMaps();\r\n static readonly languageMap: LanguageKeyMaps = new LanguageKeyMaps();\r\n\r\n private static _usCharCodes: KeyMap[];\r\n\r\n private constructor() {\r\n // Do not construct this class.\r\n }\r\n\r\n private static _usCodeInit() {\r\n var s0=new KeyMap(),s1=new KeyMap();\r\n\r\n s0['k192'] = 96;\r\n s0['k49'] = 49;\r\n s0['k50'] = 50;\r\n s0['k51'] = 51;\r\n s0['k52'] = 52;\r\n s0['k53'] = 53;\r\n s0['k54'] = 54;\r\n s0['k55'] = 55;\r\n s0['k56'] = 56;\r\n s0['k57'] = 57;\r\n s0['k48'] = 48;\r\n s0['k189'] = 45;\r\n s0['k187'] = 61;\r\n s0['k81'] = 113;\r\n s0['k87'] = 119;\r\n s0['k69'] = 101;\r\n s0['k82'] = 114;\r\n s0['k84'] = 116;\r\n s0['k89'] = 121;\r\n s0['k85'] = 117;\r\n s0['k73'] = 105;\r\n s0['k79'] = 111;\r\n s0['k80'] = 112;\r\n s0['k219'] = 91;\r\n s0['k221'] = 93;\r\n s0['k220'] = 92;\r\n s0['k65'] = 97;\r\n s0['k83'] = 115;\r\n s0['k68'] = 100;\r\n s0['k70'] = 102;\r\n s0['k71'] = 103;\r\n s0['k72'] = 104;\r\n s0['k74'] = 106;\r\n s0['k75'] = 107;\r\n s0['k76'] = 108;\r\n s0['k186'] = 59;\r\n s0['k222'] = 39;\r\n s0['k90'] = 122;\r\n s0['k88'] = 120;\r\n s0['k67'] = 99;\r\n s0['k86'] = 118;\r\n s0['k66'] = 98;\r\n s0['k78'] = 110;\r\n s0['k77'] = 109;\r\n s0['k188'] = 44;\r\n s0['k190'] = 46;\r\n s0['k191'] = 47;\r\n\r\n s1['k192'] = 126;\r\n s1['k49'] = 33;\r\n s1['k50'] = 64;\r\n s1['k51'] = 35;\r\n s1['k52'] = 36;\r\n s1['k53'] = 37;\r\n s1['k54'] = 94;\r\n s1['k55'] = 38;\r\n s1['k56'] = 42;\r\n s1['k57'] = 40;\r\n s1['k48'] = 41;\r\n s1['k189'] = 95;\r\n s1['k187'] = 43;\r\n s1['k81'] = 81;\r\n s1['k87'] = 87;\r\n s1['k69'] = 69;\r\n s1['k82'] = 82;\r\n s1['k84'] = 84;\r\n s1['k89'] = 89;\r\n s1['k85'] = 85;\r\n s1['k73'] = 73;\r\n s1['k79'] = 79;\r\n s1['k80'] = 80;\r\n s1['k219'] = 123;\r\n s1['k221'] = 125;\r\n s1['k220'] = 124;\r\n s1['k65'] = 65;\r\n s1['k83'] = 83;\r\n s1['k68'] = 68;\r\n s1['k70'] = 70;\r\n s1['k71'] = 71;\r\n s1['k72'] = 72;\r\n s1['k74'] = 74;\r\n s1['k75'] = 75;\r\n s1['k76'] = 76;\r\n s1['k186'] = 58;\r\n s1['k222'] = 34;\r\n s1['k90'] = 90;\r\n s1['k88'] = 88;\r\n s1['k67'] = 67;\r\n s1['k86'] = 86;\r\n s1['k66'] = 66;\r\n s1['k78'] = 78;\r\n s1['k77'] = 77;\r\n s1['k188'] = 60;\r\n s1['k190'] = 62;\r\n s1['k191'] = 63;\r\n\r\n KeyMapping._usCharCodes = [s0,s1];\r\n }\r\n\r\n /**\r\n * Function _USKeyCodeToCharCode\r\n * Scope Private\r\n * @param {Event} Levent KMW event object\r\n * @return {number} Character code\r\n * Description Translate keyboard codes to standard US layout codes\r\n */\r\n static _USKeyCodeToCharCode(Levent: KeyEvent | KeyEventSpec) {\r\n return KeyMapping.usCharCodes[Levent.Lmodifiers & 0x10 ? 1 : 0]['k'+Levent.Lcode];\r\n };\r\n\r\n public static get usCharCodes() {\r\n if(!KeyMapping._usCharCodes) {\r\n KeyMapping._usCodeInit();\r\n }\r\n\r\n return KeyMapping._usCharCodes;\r\n }\r\n}", + "import Codes from \"../text/codes.js\";\r\nimport KeyEvent, { KeyEventSpec } from \"../text/keyEvent.js\";\r\nimport KeyMapping from \"../text/keyMapping.js\";\r\nimport type { KeyDistribution } from \"../text/keyEvent.js\";\r\nimport type { LayoutKey, LayoutRow, LayoutLayer, LayoutFormFactor, ButtonClass } from \"./defaultLayouts.js\";\r\nimport type Keyboard from \"./keyboard.js\";\r\n\r\nimport { type DeviceSpec } from \"@keymanapp/web-utils\";\r\n\r\n// TS 3.9 changed behavior of getters to make them\r\n// non-enumerable by default. This broke our 'polyfill'\r\n// functions which depended on enumeration to copy the\r\n// relevant props over.\r\n// https://github.com/microsoft/TypeScript/pull/32264#issuecomment-677718191\r\nfunction Enumerable(\r\n target: unknown,\r\n propertyKey: string,\r\n descriptor: PropertyDescriptor\r\n) {\r\n descriptor.enumerable = true;\r\n};\r\n\r\nexport class ActiveKey implements LayoutKey {\r\n static readonly DEFAULT_PAD=15; // Padding to left of key, in virtual units\r\n static readonly DEFAULT_RIGHT_MARGIN=15; // Padding to right of right-most key, in virtual units\r\n static readonly DEFAULT_KEY_WIDTH=100; // Width of a key, if not specified, in virtual units\r\n\r\n // Defines key defaults\r\n static readonly DEFAULT_KEY = {\r\n text: '',\r\n width: ActiveKey.DEFAULT_KEY_WIDTH,\r\n sp: 0,\r\n pad: ActiveKey.DEFAULT_PAD\r\n };\r\n\r\n /** WARNING - DO NOT USE DIRECTLY outside of @keymanapp/keyboard-processor! */\r\n id?: string;\r\n\r\n // These are fine.\r\n width?: number;\r\n pad?: number;\r\n\r\n layer: string;\r\n displayLayer: string;\r\n nextlayer: string;\r\n sp?: ButtonClass;\r\n\r\n _baseKeyEvent: KeyEvent;\r\n isMnemonic: boolean = false;\r\n\r\n /**\r\n * Only available on subkeys, but we don't distinguish between base keys and subkeys\r\n * at this level yet in KMW.\r\n */\r\n default?: boolean;\r\n\r\n proportionalPad: number;\r\n proportionalX: number;\r\n proportionalWidth: number;\r\n\r\n sk?: ActiveKey[];\r\n\r\n // Keeping things simple here, as this was added LATE in 14.0 beta.\r\n // Could definitely extend in the future to instead return an object\r\n // that denotes the 'nature' of the key.\r\n // - isUnicode\r\n // - isHardwareKey\r\n // - etc.\r\n\r\n // Reference for the terminology in the comments below:\r\n // https://help.keyman.com/developer/current-version/guides/develop/creating-a-touch-keyboard-layout-for-amharic-the-nitty-gritty\r\n\r\n /**\r\n * Matches the key code as set within Keyman Developer for the layout.\r\n * For example, K_R or U_0020. Denotes either physical keys or virtual keys with custom output,\r\n * with no additional metadata like layer or active modifiers.\r\n *\r\n * Is used to determine the keycode for input events, rule-matching, and keystroke processing.\r\n */\r\n @Enumerable\r\n public get baseKeyID(): string {\r\n if(typeof this.id === 'undefined') {\r\n return undefined;\r\n }\r\n\r\n return this.id;\r\n }\r\n\r\n @Enumerable\r\n public get isPadding(): boolean {\r\n // Does not include 9 (class: blank) as that may be an intentional 'catch' for misplaced\r\n // keystrokes.\r\n return this['sp'] == 10; // Button class: hidden.\r\n }\r\n\r\n /**\r\n * A unique identifier based on both the key ID & the 'desktop layer' to be used for the key.\r\n *\r\n * Allows diambiguation of scenarios where the same key ID is used twice within a layer, but\r\n * with different innate modifiers. (Refer to https://github.com/keymanapp/keyman/issues/4617)\r\n * The 'desktop layer' may be omitted if it matches the key's display layer.\r\n *\r\n * Examples, given a 'default' display layer, matching keys to Keyman keyboard language:\r\n *\r\n * ```\r\n * \"K_Q\"\r\n * + [K_Q]\r\n * \"K_Q+shift\"\r\n * + [K_Q SHIFT]\r\n * ```\r\n *\r\n * Useful when the active layer of an input-event is already known.\r\n */\r\n @Enumerable\r\n public get coreID(): string {\r\n if(typeof this.id === 'undefined') {\r\n return undefined;\r\n }\r\n\r\n let baseID = this.id || '';\r\n\r\n if(this.displayLayer != this.layer) {\r\n baseID = baseID + '+' + this.layer;\r\n }\r\n\r\n return baseID;\r\n }\r\n\r\n /**\r\n * A keyboard-unique identifier to be used for any display elements representing this key\r\n * in user interfaces and/or on-screen keyboards.\r\n *\r\n * Distinguishes between otherwise-identical keys on different layers of an OSK.\r\n * Includes identifying information about the key's display layer.\r\n *\r\n * Examples, given a 'default' display layer, matching keys to Keyman keyboard language:\r\n *\r\n * ```\r\n * \"default-K_Q\"\r\n * + [K_Q]\r\n * \"default-K_Q+shift\"\r\n * + [K_Q SHIFT]\r\n * ```\r\n *\r\n * Useful when only the active keyboard is known about an input event.\r\n */\r\n @Enumerable\r\n public get elementID(): string {\r\n if(typeof this.id === 'undefined') {\r\n return undefined;\r\n }\r\n\r\n return this.displayLayer + '-' + this.coreID;\r\n }\r\n\r\n @Enumerable\r\n public get baseKeyEvent(): KeyEvent {\r\n return new KeyEvent(this._baseKeyEvent);\r\n }\r\n\r\n /**\r\n * Converts key IDs of the U_* form to their corresponding UTF-16 text.\r\n * If an ID not matching the pattern is received, returns null.\r\n * @param id\r\n * @returns\r\n */\r\n static unicodeIDToText(id: string, errorCallback?: (codeAsString: string) => void) {\r\n if(!id || id.substring(0,2) != 'U_') {\r\n return null;\r\n }\r\n\r\n let result = '';\r\n const codePoints = id.substring(2).split('_');\r\n for(let codePoint of codePoints) {\r\n const codePointValue = parseInt(codePoint, 16);\r\n if (((0x0 <= codePointValue) && (codePointValue <= 0x1F)) ||\r\n ((0x80 <= codePointValue) && (codePointValue <= 0x9F)) ||\r\n isNaN(codePointValue)) {\r\n if(errorCallback) {\r\n errorCallback(codePoint);\r\n }\r\n continue;\r\n } else {\r\n // String.fromCharCode() is inadequate to handle the entire range of Unicode\r\n // Someday after upgrading to ES2015, can use String.fromCodePoint()\r\n result += String.kmwFromCharCode(codePointValue);\r\n }\r\n }\r\n return result ? result : null;\r\n }\r\n\r\n static sanitize(rawKey: LayoutKey) {\r\n if(typeof rawKey.width == 'string') {\r\n rawKey.width = parseInt(rawKey.width, 10);\r\n }\r\n // Handles NaN cases as well as 'set to 0' cases; both are intentional here.\r\n rawKey.width ||= ActiveKey.DEFAULT_KEY_WIDTH;\r\n\r\n if(typeof rawKey.pad == 'string') {\r\n rawKey.pad = parseInt(rawKey.pad, 10);\r\n }\r\n rawKey.pad ||= ActiveKey.DEFAULT_PAD;\r\n\r\n if(typeof rawKey.sp == 'string') {\r\n rawKey.sp = Number.parseInt(rawKey.sp, 10) as ButtonClass;\r\n }\r\n rawKey.sp ||= 0; // The default button class.\r\n }\r\n\r\n static polyfill(key: LayoutKey, keyboard: Keyboard, layout: ActiveLayout, displayLayer: string) {\r\n // Add class functions to the existing layout object, allowing it to act as an ActiveLayout.\r\n let dummy = new ActiveKey();\r\n let proto = Object.getPrototypeOf(dummy);\r\n\r\n for(let prop in dummy) {\r\n if(!key.hasOwnProperty(prop)) {\r\n let descriptor = Object.getOwnPropertyDescriptor(proto, prop);\r\n if(descriptor) {\r\n // It's a computed property! Copy the descriptor onto the key's object.\r\n Object.defineProperty(key, prop, descriptor);\r\n } else {\r\n key[prop] = dummy[prop];\r\n }\r\n }\r\n }\r\n\r\n // Ensure subkeys are also properly extended.\r\n if(key.sk) {\r\n for(let subkey of key.sk) {\r\n ActiveKey.polyfill(subkey, keyboard, layout, displayLayer);\r\n }\r\n }\r\n\r\n let aKey = key as ActiveKey;\r\n aKey.displayLayer = displayLayer;\r\n aKey.layer = aKey.layer || displayLayer;\r\n\r\n // Compute the key's base KeyEvent properties for use in future event generation\r\n aKey.constructBaseKeyEvent(keyboard, layout, displayLayer);\r\n }\r\n\r\n private constructBaseKeyEvent(keyboard: Keyboard, layout: ActiveLayout, displayLayer: string) {\r\n // Get key name and keyboard shift state (needed only for default layouts and physical keyboard handling)\r\n // Note - virtual keys should be treated case-insensitive, so we force uppercasing here.\r\n let layer = this.layer || displayLayer || '';\r\n let keyName= this.id ? this.id.toUpperCase() : null;\r\n\r\n // Start: mirrors _GetKeyEventProperties\r\n\r\n // First check the virtual key, and process shift, control, alt or function keys\r\n let props: KeyEventSpec = {\r\n // Override key shift state if specified for key in layout (corrected for popup keys KMEW-93)\r\n Lmodifiers: Codes.getModifierState(layer),\r\n Lstates: Codes.getStateFromLayer(layer),\r\n Lcode: keyName ? Codes.keyCodes[keyName] : 0,\r\n LisVirtualKey: true,\r\n vkCode: 0,\r\n kName: keyName,\r\n kLayer: layer,\r\n kbdLayer: displayLayer,\r\n kNextLayer: this.nextlayer,\r\n device: null,\r\n isSynthetic: true\r\n };\r\n\r\n let Lkc: KeyEvent = new KeyEvent(props);\r\n\r\n if(layout.keyboard) {\r\n let keyboard = layout.keyboard;\r\n\r\n // Include *limited* support for mnemonic keyboards (Sept 2012)\r\n // If a touch layout has been defined for a mnemonic keyout, do not perform mnemonic mapping for rules on touch devices.\r\n if(keyboard.isMnemonic && !(layout.isDefault && layout.formFactor != 'desktop')) {\r\n if(Lkc.Lcode != Codes.keyCodes['K_SPACE']) { // exception required, March 2013\r\n // Jan 2019 - interesting that 'K_SPACE' also affects the caps-state check...\r\n Lkc.vkCode = Lkc.Lcode;\r\n this.isMnemonic = true;\r\n }\r\n } else {\r\n Lkc.vkCode=Lkc.Lcode;\r\n }\r\n\r\n // Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic\r\n if(!keyboard.definesPositionalOrMnemonic) {\r\n // Not the best pattern, but currently safe - we don't look up any properties of any of the\r\n // arguments in this use case, and the object's scope is extremely limited.\r\n Lkc.Lcode = KeyMapping._USKeyCodeToCharCode(keyboard.constructKeyEvent(null, null, {\r\n K_CAPS: false,\r\n K_NUMLOCK: false,\r\n K_SCROLL: false\r\n }));\r\n Lkc.LisVirtualKey=false;\r\n }\r\n }\r\n\r\n this._baseKeyEvent = Lkc;\r\n }\r\n\r\n public getSubkey(coreID: string): ActiveKey {\r\n if(this.sk) {\r\n for(let key of this.sk) {\r\n if(key.coreID == coreID) {\r\n return key;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n}\r\n\r\nexport class ActiveRow implements LayoutRow {\r\n // Identify key labels (e.g. *Shift*) that require the special OSK font\r\n static readonly SPECIAL_LABEL=/\\*\\w+\\*/;\r\n\r\n id: number;\r\n key: ActiveKey[];\r\n\r\n /**\r\n * Used for calculating fat-fingering offsets.\r\n */\r\n proportionalY: number;\r\n\r\n private constructor() {\r\n\r\n }\r\n\r\n static sanitize(rawRow: LayoutRow) {\r\n for(const key of rawRow.key) {\r\n // Test for a trailing comma included in spec, added as null object by IE\r\n // It has only ever appeared at the end of a row's spec.\r\n if(key == null) {\r\n rawRow.key.length = rawRow.key.length-1;\r\n } else {\r\n ActiveKey.sanitize(key);\r\n }\r\n }\r\n\r\n if(typeof rawRow.id == 'string') {\r\n rawRow.id = Number.parseInt(rawRow.id, 10);\r\n }\r\n }\r\n\r\n static polyfill(row: LayoutRow, keyboard: Keyboard, layout: ActiveLayout, displayLayer: string, totalWidth: number, proportionalY: number) {\r\n // Apply defaults, setting the width and other undefined properties for each key\r\n let keys=row['key'];\r\n for(let j=0; j 0) {\r\n const finalKey = keys[keys.length-1] as ActiveKey;\r\n\r\n // If a single key, and padding is negative, add padding to right align the key\r\n if(keys.length == 1 && finalKey.pad < 0) {\r\n const keyPercent = finalKey.width/totalWidth;\r\n const padPercent = 1-(totalPercent + keyPercent + rightMargin);\r\n\r\n // compute center's default x-coord (used in headless modes)\r\n setProportions(finalKey, padPercent, keyPercent, totalPercent);\r\n } else {\r\n const padPercent = finalKey.pad/totalWidth;\r\n const keyPercent = 1-(totalPercent + padPercent + rightMargin);\r\n\r\n // compute center's default x-coord (used in headless modes)\r\n setProportions(finalKey, padPercent, keyPercent, totalPercent);\r\n }\r\n }\r\n\r\n // Add class functions to the existing layout object, allowing it to act as an ActiveLayout.\r\n let dummy = new ActiveRow();\r\n for(let key in dummy) {\r\n if(!row.hasOwnProperty(key)) {\r\n row[key] = dummy[key];\r\n }\r\n }\r\n\r\n let aRow = row as ActiveRow;\r\n aRow.proportionalY = proportionalY;\r\n }\r\n\r\n populateKeyMap(map: {[keyId: string]: ActiveKey}) {\r\n this.key.forEach(function(key: ActiveKey) {\r\n if(key.coreID) {\r\n map[key.coreID] = key;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport class ActiveLayer implements LayoutLayer {\r\n row: ActiveRow[];\r\n id: string;\r\n\r\n // These already exist on the objects, pre-polyfill...\r\n // but they still need to be proactively declared on this type.\r\n capsKey?: ActiveKey;\r\n numKey?: ActiveKey;\r\n scrollKey?: ActiveKey;\r\n\r\n totalWidth: number;\r\n\r\n defaultKeyProportionalWidth: number;\r\n rowProportionalHeight: number;\r\n\r\n /**\r\n * Facilitates mapping key id strings to their specification objects.\r\n */\r\n keyMap: {[keyId: string]: ActiveKey};\r\n\r\n constructor() {\r\n\r\n }\r\n\r\n static sanitize(rawLayer: LayoutLayer) {\r\n for(const row of rawLayer.row) {\r\n ActiveRow.sanitize(row);\r\n }\r\n }\r\n\r\n static polyfill(layer: LayoutLayer, keyboard: Keyboard, layout: ActiveLayout) {\r\n layer.aligned=false;\r\n\r\n // Create a DIV for each row of the group\r\n let rows=layer['row'];\r\n\r\n // Calculate the maximum row width (in layout units)\r\n let totalWidth=0;\r\n for(const row of rows) {\r\n let width=0;\r\n const keys=row['key'];\r\n\r\n for(const key of keys) {\r\n // So long as `sanitize` is called first, these coercions are safe.\r\n width += (key.width as number) + (key.pad as number);\r\n }\r\n\r\n if(width > totalWidth) {\r\n totalWidth = width;\r\n }\r\n }\r\n\r\n // Add default right margin\r\n if(layout.formFactor == 'desktop') {\r\n totalWidth += 5; // TODO: resolve difference between touch and desktop; why don't we use ActiveKey.DEFAULT_RIGHT_MARGIN?\r\n } else {\r\n totalWidth += ActiveKey.DEFAULT_RIGHT_MARGIN;\r\n }\r\n\r\n let rowCount = layer.row.length;\r\n for(let i=0; i probability, use a function parameter in place\r\n // of the formula in the loop below.\r\n for(let key in keyDists) {\r\n totalMass += keyProbs[key] = 1 / (Math.pow(keyDists[key], 2) + 1e-6); // Prevent div-by-0 errors.\r\n }\r\n\r\n for(let key in keyProbs) {\r\n keyProbs[key] /= totalMass;\r\n }\r\n\r\n return keyProbs;\r\n }\r\n\r\n /**\r\n * Computes a squared 'pseudo-distance' for the touch from each key. (Not a proper metric.)\r\n * Intended for use in generating a probability distribution over the keys based on the touch input.\r\n * @param touchCoords A proportional (x, y) coordinate of the touch within the keyboard's geometry.\r\n * Should be within [0, 0] to [1, 1].\r\n * @param kbdScaleRatio The ratio of the keyboard's horizontal scale to its vertical scale.\r\n * For a 400 x 200 keyboard, should be 2.\r\n */\r\n private keyTouchDistances(touchCoords: {x: number, y: number}, kbdScaleRatio: number): {[keyId: string]: number} {\r\n let layer = this;\r\n\r\n let keyDists: {[keyId: string]: number} = {};\r\n\r\n // This double-nested loop computes a pseudo-distance for the touch from each key. Quite useful for\r\n // generating a probability distribution.\r\n this.row.forEach(function(row: ActiveRow): void {\r\n row.key.forEach(function(key: ActiveKey): void {\r\n // If the key lacks an ID, just skip it. Sometimes used for padding.\r\n if(!key.baseKeyID) {\r\n return;\r\n } else {\r\n // Attempt to filter out known non-output keys.\r\n // Results in a more optimized distribution.\r\n if(Codes.isKnownOSKModifierKey(key.baseKeyID)) {\r\n return;\r\n } else if(key.isPadding) { // to the user, blank / padding keys do not exist.\r\n return;\r\n }\r\n }\r\n // These represent the within-key distance of the touch from the key's center.\r\n // Both should be on the interval [0, 0.5].\r\n let dx = Math.abs(touchCoords.x - key.proportionalX);\r\n let dy = Math.abs(touchCoords.y - row.proportionalY);\r\n\r\n // If the touch isn't within the key, these store the out-of-key distance\r\n // from the closest point on the key being checked.\r\n let distX: number, distY: number;\r\n\r\n if(dx > 0.5 * key.proportionalWidth) {\r\n distX = (dx - 0.5 * key.proportionalWidth);\r\n dx = 0.5;\r\n } else {\r\n distX = 0;\r\n dx /= key.proportionalWidth;\r\n }\r\n\r\n if(dy > 0.5 * layer.rowProportionalHeight) {\r\n distY = (dy - 0.5 * layer.rowProportionalHeight);\r\n dy = 0.5;\r\n } else {\r\n distY = 0;\r\n dy /= layer.rowProportionalHeight;\r\n }\r\n\r\n // Now that the differentials are computed, it's time to do distance scaling.\r\n //\r\n // For out-of-key distance, we scale the X component by the keyboard's aspect ratio\r\n // to get the actual out-of-key distance rather than proportional.\r\n distX *= kbdScaleRatio;\r\n\r\n // While the keys are rarely perfect squares, we map all within-key distance\r\n // to a square shape. (ALT/CMD should seem as close to SPACE as a 'B'.)\r\n //\r\n // For that square, we take the rowHeight as its edge lengths.\r\n distX += dx * layer.rowProportionalHeight;\r\n distY += dy * layer.rowProportionalHeight;\r\n\r\n let distance = distX * distX + distY * distY;\r\n keyDists[key.coreID] = distance;\r\n });\r\n });\r\n\r\n return keyDists;\r\n }\r\n\r\n getKey(keyId: string) {\r\n // Keys usually are specified in a \"long form\" prefixed with their layer's ID.\r\n if(keyId.indexOf(this.id + '-') == 0) {\r\n keyId = keyId.replace(this.id + '-', '');\r\n }\r\n\r\n let idComponents = keyId.split('::');\r\n if(idComponents.length > 1) {\r\n let baseKey = this.keyMap[idComponents[0]];\r\n return baseKey.getSubkey(idComponents[1]);\r\n } else {\r\n return this.keyMap[keyId];\r\n }\r\n }\r\n}\r\n\r\nexport class ActiveLayout implements LayoutFormFactor{\r\n layer: ActiveLayer[];\r\n font: string;\r\n keyLabels: boolean;\r\n isDefault?: boolean;\r\n keyboard: Keyboard;\r\n formFactor: DeviceSpec.FormFactor;\r\n\r\n /**\r\n * Facilitates mapping layer id strings to their specification objects.\r\n */\r\n layerMap: {[layerId: string]: ActiveLayer};\r\n\r\n private constructor() {\r\n\r\n }\r\n\r\n getLayer(layerId: string): ActiveLayer {\r\n return this.layerMap[layerId];\r\n }\r\n\r\n /**\r\n * Refer to https://github.com/keymanapp/keyman/issues/254, which mentions\r\n * KD-11 from a prior issue-tracking system from the closed-source days that\r\n * resulted in an unintended extra empty row.\r\n *\r\n * It'll be pretty rare to see a keyboard affected by the bug, but we don't\r\n * 100% control all keyboards out there, so it's best we make sure the edge\r\n * case is covered.\r\n *\r\n * @param layers The layer group to be loaded for the form factor. Will be\r\n * mutated by this operation.\r\n */\r\n static correctLayerEmptyRowBug(layers: LayoutLayer[]) {\r\n for(let n=0; n=0; i--) {\r\n if(!Array.isArray(rows[i]['key']) || rows[i]['key'].length == 0) {\r\n rows.splice(i, 1)\r\n }\r\n }\r\n }\r\n }\r\n\r\n static sanitize(rawLayout: LayoutFormFactor) {\r\n ActiveLayout.correctLayerEmptyRowBug(rawLayout.layer);\r\n\r\n for(const layer of rawLayout.layer) {\r\n ActiveLayer.sanitize(layer);\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @param layout\r\n * @param formFactor\r\n */\r\n static polyfill(layout: LayoutFormFactor, keyboard: Keyboard, formFactor: DeviceSpec.FormFactor): ActiveLayout {\r\n if(layout == null) {\r\n throw new Error(\"Cannot build an ActiveLayout for a null specification.\");\r\n }\r\n\r\n /* Standardize the layout object's data types.\r\n *\r\n * In older versions of KMW, some numeric properties were long represented as strings instead,\r\n * and that lives on within a _lot_ of keyboards. The data should be sanitized before it\r\n * is processed by this method.\r\n */\r\n this.sanitize(layout);\r\n\r\n // Create a separate OSK div for each OSK layer, only one of which will ever be visible\r\n var n: number;\r\n let layerMap: {[layerId: string]: ActiveLayer} = {};\r\n\r\n let layers=layout.layer;\r\n\r\n // Add class functions to the existing layout object, allowing it to act as an ActiveLayout.\r\n let dummy = new ActiveLayout();\r\n for(let key in dummy) {\r\n if(!layout.hasOwnProperty(key)) {\r\n layout[key] = dummy[key];\r\n }\r\n }\r\n\r\n let aLayout = layout as ActiveLayout;\r\n aLayout.keyboard = keyboard;\r\n aLayout.formFactor = formFactor;\r\n\r\n for(n=0; n(p:T, c0?): T {\r\n var c = c0 || {};\r\n for (var i in p) {\r\n if(typeof p[i] === 'object' && p[i] != null) {\r\n c[i] = (p[i].constructor === Array ) ? [] : {};\r\n deepCopy(p[i],c[i]);\r\n }\r\n else {\r\n c[i] = p[i];\r\n }\r\n }\r\n\r\n return c;\r\n}", + "/**\r\n * This class provides an abstract version of com.keyman.Device that is core-friendly,\r\n * containing only the information needed by web-core for text processing use, devoid\r\n * of any direct references to the DOM.\r\n */\r\nexport class DeviceSpec {\r\n readonly browser: DeviceSpec.Browser;\r\n readonly formFactor: DeviceSpec.FormFactor;\r\n readonly OS: DeviceSpec.OperatingSystem;\r\n readonly touchable: boolean;\r\n\r\n constructor(browser: string, formFactor: string, OS: string, touchable: boolean) {\r\n switch(browser.toLowerCase() as DeviceSpec.Browser) {\r\n case DeviceSpec.Browser.Chrome:\r\n case DeviceSpec.Browser.Edge:\r\n case DeviceSpec.Browser.Firefox:\r\n case DeviceSpec.Browser.Native:\r\n case DeviceSpec.Browser.Opera:\r\n case DeviceSpec.Browser.Safari:\r\n this.browser = browser.toLowerCase() as DeviceSpec.Browser;\r\n break;\r\n default:\r\n this.browser = DeviceSpec.Browser.Other;\r\n }\r\n\r\n switch(formFactor.toLowerCase() as DeviceSpec.FormFactor) {\r\n case DeviceSpec.FormFactor.Desktop:\r\n case DeviceSpec.FormFactor.Phone:\r\n case DeviceSpec.FormFactor.Tablet:\r\n this.formFactor = formFactor.toLowerCase() as DeviceSpec.FormFactor;\r\n break;\r\n default:\r\n throw (\"Invalid form factor specified for device: \" + formFactor);\r\n }\r\n\r\n switch(OS.toLowerCase() as DeviceSpec.OperatingSystem) {\r\n case DeviceSpec.OperatingSystem.Windows.toLowerCase():\r\n case DeviceSpec.OperatingSystem.macOS.toLowerCase():\r\n case DeviceSpec.OperatingSystem.Linux.toLowerCase():\r\n case DeviceSpec.OperatingSystem.Android.toLowerCase():\r\n case DeviceSpec.OperatingSystem.iOS.toLowerCase():\r\n this.OS = OS.toLowerCase() as DeviceSpec.OperatingSystem;\r\n break;\r\n default:\r\n this.OS = DeviceSpec.OperatingSystem.Other;\r\n }\r\n\r\n this.touchable = touchable;\r\n }\r\n}\r\n\r\n// Namespaces these under DeviceSpec, as each is primarily used with it.\r\nexport namespace DeviceSpec {\r\n export enum Browser {\r\n Chrome = 'chrome',\r\n Edge = 'edge',\r\n Firefox = 'firefox',\r\n Native = 'native', // Used by embedded mode\r\n Opera = 'opera',\r\n Safari = 'safari',\r\n Other = 'other'\r\n }\r\n\r\n export enum OperatingSystem {\r\n Windows = 'windows',\r\n macOS = 'macosx',\r\n Linux = 'linux',\r\n Android = 'android',\r\n iOS = 'ios',\r\n Other = 'other'\r\n }\r\n\r\n export enum FormFactor {\r\n Desktop = 'desktop',\r\n Phone = 'phone',\r\n Tablet = 'tablet'\r\n }\r\n}\r\n\r\nexport function physicalKeyDeviceAlias(device: DeviceSpec) {\r\n return new DeviceSpec(device.browser, DeviceSpec.FormFactor.Desktop, device.OS, false);\r\n}\r\n\r\nexport default DeviceSpec;", + "\n// Generated by common/web/keyman-version/build.sh\n//\n// Note: does not use the 'default' keyword so that the export name is\n// correct when converted to a CommonJS module with `esbuild`.\nexport class KEYMAN_VERSION {\n static readonly VERSION = \"17.0.203\";\n static readonly VERSION_RELEASE =\"17.0\";\n static readonly VERSION_MAJOR = \"17\";\n static readonly VERSION_MINOR = \"0\";\n static readonly VERSION_PATCH = \"203\";\n static readonly TIER =\"alpha\";\n static readonly VERSION_TAG = \"-alpha\";\n static readonly VERSION_WITH_TAG = \"17.0.203-alpha\";\n static readonly VERSION_ENVIRONMENT = \"alpha\";\n static readonly VERSION_GIT_TAG = \"release@17.0.203-alpha\";\n}\n\n// Also provides it as a 'default' export.\nexport default KEYMAN_VERSION;\n \n", + "import KEYMAN_VERSION from \"@keymanapp/keyman-version\";\r\n\r\n// Dotted-decimal version\r\nexport default class Version {\r\n public static readonly CURRENT = new Version(KEYMAN_VERSION.VERSION_RELEASE);\r\n\r\n // Represents a default version value for keyboards compiled before this was compiled into keyboards.\r\n // The exact version is unknown at this point, but the value is \"good enough\" for what we need.\r\n public static readonly DEVELOPER_VERSION_FALLBACK = new Version([9, 0, 0]);\r\n\r\n // For 12.0, the old default behavior of adding missing keycaps to the default layers was removed,\r\n // as it results in unexpected, bug-like behavior for keyboard designers when it is unwanted.\r\n public static readonly NO_DEFAULT_KEYCAPS = new Version([12, 0]);\r\n\r\n public static readonly MAC_POSSIBLE_IPAD_ALIAS = new Version([10, 15]);\r\n\r\n private readonly components: number[]\r\n\r\n /**\r\n * Parses version information, preparing it for use in comparisons.\r\n * @param text Either a string representing a version number (ex: \"9.0.0\") or an array representing\r\n * its components (ex: [9, 0, 0]).\r\n */\r\n constructor(text: String | number[]) {\r\n // If a keyboard doesn't specify a version, use the DEVELOPER_VERSION_FALLBACK values.\r\n if(text === undefined || text === null) {\r\n this.components = [].concat(Version.DEVELOPER_VERSION_FALLBACK.components);\r\n return;\r\n }\r\n\r\n if(Array.isArray(text)) {\r\n let components = text as number[];\r\n if(components.length < 2) {\r\n throw new Error(\"Version string must have at least a major and minor component!\");\r\n } else {\r\n this.components = [].concat(components);\r\n return;\r\n }\r\n }\r\n\r\n // else, standard constructor path.\r\n let parts = text.split('.');\r\n let componentArray: number[] = [];\r\n\r\n if(parts.length < 2) {\r\n throw new Error(\"Version string must have at least a major and minor component!\");\r\n }\r\n\r\n for(let i=0; i < parts.length; i++) {\r\n let value = parseInt(parts[i], 10);\r\n if(isNaN(value)) {\r\n throw new Error(\"Version string components must be numerical!\");\r\n }\r\n\r\n componentArray.push(value);\r\n }\r\n\r\n this.components = componentArray;\r\n }\r\n\r\n get major(): number {\r\n return this.components[0];\r\n }\r\n\r\n get minor(): number {\r\n return this.components[1];\r\n }\r\n\r\n toString(): string {\r\n return this.components.join('.');\r\n }\r\n\r\n toJSON(): string {\r\n return this.toString();\r\n }\r\n\r\n equals(other: Version): boolean {\r\n return this.compareTo(other) == 0;\r\n }\r\n\r\n precedes(other: Version): boolean {\r\n return this.compareTo(other) < 0;\r\n }\r\n\r\n compareTo(other: Version): number {\r\n // If the version info depth differs, we need a flag to indicate which instance is shorter.\r\n var isShorter: boolean = this.components.length < other.components.length;\r\n var maxDepth: number = (this.components.length < other.components.length) ? this.components.length : other.components.length;\r\n\r\n var i: number;\r\n for(i = 0; i < maxDepth; i++) {\r\n let delta = this.components[i] - other.components[i];\r\n if(delta != 0) {\r\n return delta;\r\n }\r\n }\r\n\r\n var longList = isShorter ? other.components : this.components;\r\n do {\r\n if(longList[i] > 0) {\r\n return isShorter ? -1 : 1;\r\n }\r\n i++;\r\n } while (i < longList.length);\r\n\r\n // Equal.\r\n return 0;\r\n }\r\n}", + "/**\r\n * Returns the base global object available to the current JS platform.\r\n * - In browsers, returns `window`.\r\n * - In WebWorkers, returns `self`.\r\n * - In Node, returns `global`.\r\n */\r\nexport default function getGlobalObject(): typeof globalThis {\r\n // Evergreen browsers have started defining 'globalThis'.\r\n // Refer to https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#type-checking-for-globalthis\r\n // and its referenced polyfill. Said polyfill is very complex, so we opt for this far leaner variant.\r\n if(typeof globalThis != 'undefined') {\r\n return globalThis; // Not available in IE or older Edge versions\r\n // @ts-ignore (TS will throw errors for whatever platform we're not compiling for.)\r\n } else if(typeof window != 'undefined') {\r\n // @ts-ignore\r\n return window; // The browser-based classic\r\n // @ts-ignore\r\n } else if(typeof self != 'undefined') {\r\n // @ts-ignore\r\n return self; // WebWorker global\r\n } else {\r\n // Assumption - if neither of the above exist, we're in Node, for unit-testing.\r\n // Node doesn't have as many methods and properties as the other two, but what\r\n // matters for us is that it's the base global.\r\n //\r\n // Some other headless JS solutions use 'this' instead, but Node's enough for our needs.\r\n // @ts-ignore\r\n return (global as any) as typeof globalThis;\r\n }\r\n}", + "/***\r\n KeymanWeb 14.0\r\n Copyright 2020 SIL International\r\n***/\r\n\r\n\r\n/*\r\n * TODO: Remove this file as part of addressing https://github.com/keymanapp/keyman/issues/2492.\r\n */\r\n\r\ndeclare global {\r\n interface StringConstructor {\r\n kmwFromCharCode(cp0: number): string,\r\n _kmwFromCharCode(cp0: number): string,\r\n kmwEnableSupplementaryPlane(bEnable: boolean)\r\n }\r\n\r\n interface String {\r\n kmwCharCodeAt(codePointIndex: number): number,\r\n kmwCharAt(codePointIndex: number) : string,\r\n kmwIndexOf(searchValue: string, fromIndex?: number) : number,\r\n kmwLastIndexOf(searchValue: string, fromIndex?: number) : number,\r\n kmwSlice(beginSlice: number, endSlice: number) : string,\r\n kmwSubstring(start: number, length: number) : string,\r\n kmwSubstr(start: number, length?: number) : string,\r\n kmwBMPSubstr(start: number, length?: number) : string,\r\n kmwLength(): number,\r\n kmwBMPLength(): number,\r\n kmwNextChar(codeUnitIndex: number): number,\r\n kmwBMPNextChar(codeUnitIndex: number): number,\r\n kmwPrevChar(codeUnitIndex: number): number,\r\n kmwBMPPrevChar(codeUnitIndex: number): number,\r\n kmwCodePointToCodeUnit(codePointIndex: number) : number,\r\n kmwBMPCodePointToCodeUnit(codePointIndex: number) : number,\r\n kmwCodeUnitToCodePoint(codeUnitIndex: number) : number,\r\n kmwBMPCodeUnitToCodePoint(codeUnitIndex: number) : number,\r\n _kmwCharCodeAt(codePointIndex: number): number,\r\n _kmwCharAt(codePointIndex: number) : string,\r\n _kmwIndexOf(searchValue: string, fromIndex?: number) : number,\r\n _kmwLastIndexOf(searchValue: string, fromIndex?: number) : number,\r\n _kmwSlice(beginSlice: number, endSlice: number) : string,\r\n _kmwSubstring(start: number, length?: number) : string,\r\n _kmwSubstr(start: number, length?: number) : string,\r\n _kmwLength(): number,\r\n _kmwNextChar(codeUnitIndex: number): number,\r\n _kmwPrevChar(codeUnitIndex: number): number,\r\n _kmwCodePointToCodeUnit(codePointIndex: number) : number,\r\n _kmwCodeUnitToCodePoint(codeUnitIndex: number) : number\r\n }\r\n}\r\n\r\nexport default function extendString() {\r\n /**\r\n * Constructs a string from one or more Unicode character codepoint values\r\n * passed as integer parameters.\r\n *\r\n * @param {number} cp0,... 1 or more Unicode codepoints, e.g. 0x0065, 0x10000\r\n * @return {string|null} The new String object.\r\n */\r\n String.kmwFromCharCode = function(cp0) {\r\n var chars = [], i;\r\n for (i = 0; i < arguments.length; i++) {\r\n var c = Number(arguments[i]);\r\n if (!isFinite(c) || c < 0 || c > 0x10FFFF || Math.floor(c) !== c) {\r\n throw new RangeError(\"Invalid code point \" + c);\r\n }\r\n if (c < 0x10000) {\r\n chars.push(c);\r\n } else {\r\n c -= 0x10000;\r\n chars.push((c >> 10) + 0xD800);\r\n chars.push((c % 0x400) + 0xDC00);\r\n }\r\n }\r\n return String.fromCharCode.apply(undefined, chars);\r\n }\r\n\r\n /**\r\n * Returns a number indicating the Unicode value of the character at the given\r\n * code point index, with support for supplementary plane characters.\r\n *\r\n * @param {number} codePointIndex The code point index into the string (not\r\n the code unit index) to return\r\n * @return {number} The Unicode character value\r\n */\r\n String.prototype.kmwCharCodeAt = function(codePointIndex) {\r\n var str = String(this);\r\n var codeUnitIndex = 0;\r\n\r\n if (codePointIndex < 0 || codePointIndex >= str.length) {\r\n return NaN;\r\n }\r\n\r\n for(var i = 0; i < codePointIndex; i++) {\r\n codeUnitIndex = str.kmwNextChar(codeUnitIndex);\r\n if(codeUnitIndex === null) return NaN;\r\n }\r\n\r\n var first = str.charCodeAt(codeUnitIndex);\r\n if (first >= 0xD800 && first <= 0xDBFF && str.length > codeUnitIndex + 1) {\r\n var second = str.charCodeAt(codeUnitIndex + 1);\r\n if (second >= 0xDC00 && second <= 0xDFFF) {\r\n return ((first - 0xD800) << 10) + (second - 0xDC00) + 0x10000;\r\n }\r\n }\r\n return first;\r\n }\r\n\r\n /**\r\n * Returns the code point index within the calling String object of the first occurrence\r\n * of the specified value, or -1 if not found.\r\n *\r\n * @param {string} searchValue The value to search for\r\n * @param {number} [fromIndex] Optional code point index to start searching from\r\n * @return {number} The code point index of the specified search value\r\n */\r\n String.prototype.kmwIndexOf = function(searchValue, fromIndex) {\r\n var str = String(this);\r\n var codeUnitIndex = str.indexOf(searchValue, fromIndex);\r\n\r\n if(codeUnitIndex < 0) {\r\n return codeUnitIndex;\r\n }\r\n\r\n var codePointIndex = 0;\r\n for(var i = 0; i !== null && i < codeUnitIndex; i = str.kmwNextChar(i)) codePointIndex++;\r\n return codePointIndex;\r\n }\r\n\r\n /**\r\n * Returns the code point index within the calling String object of the last occurrence\r\n * of the specified value, or -1 if not found.\r\n *\r\n * @param {string} searchValue The value to search for\r\n * @param {number} fromIndex Optional code point index to start searching from\r\n * @return {number} The code point index of the specified search value\r\n */\r\n String.prototype.kmwLastIndexOf = function(searchValue, fromIndex)\r\n {\r\n var str = String(this);\r\n var codeUnitIndex = str.lastIndexOf(searchValue, fromIndex);\r\n\r\n if(codeUnitIndex < 0) {\r\n return codeUnitIndex;\r\n }\r\n\r\n var codePointIndex = 0;\r\n for(var i = 0; i !== null && i < codeUnitIndex; i = str.kmwNextChar(i)) codePointIndex++;\r\n return codePointIndex;\r\n }\r\n\r\n /**\r\n * Returns the length of the string in code points, as opposed to code units.\r\n *\r\n * @return {number} The length of the string in code points\r\n */\r\n String.prototype.kmwLength = function() {\r\n var str = String(this);\r\n\r\n if(str.length == 0) return 0;\r\n\r\n for(var i = 0, codeUnitIndex = 0; codeUnitIndex !== null; i++)\r\n codeUnitIndex = str.kmwNextChar(codeUnitIndex);\r\n return i;\r\n }\r\n\r\n /**\r\n * Extracts a section of a string and returns a new string.\r\n *\r\n * @param {number} beginSlice The start code point index in the string to\r\n * extract from\r\n * @param {number} endSlice Optional end code point index in the string\r\n * to extract to\r\n * @return {string} The substring as selected by beginSlice and\r\n * endSlice\r\n */\r\n String.prototype.kmwSlice = function(beginSlice, endSlice) {\r\n var str = String(this);\r\n var beginSliceCodeUnit = str.kmwCodePointToCodeUnit(beginSlice);\r\n var endSliceCodeUnit = str.kmwCodePointToCodeUnit(endSlice);\r\n if(beginSliceCodeUnit === null || endSliceCodeUnit === null)\r\n return '';\r\n else\r\n return str.slice(beginSliceCodeUnit, endSliceCodeUnit);\r\n }\r\n\r\n /**\r\n * Returns the characters in a string beginning at the specified location through\r\n * the specified number of characters.\r\n *\r\n * @param {number} start The start code point index in the string to\r\n * extract from\r\n * @param {number=} length Optional length to extract\r\n * @return {string} The substring as selected by start and length\r\n */\r\n String.prototype.kmwSubstr = function(start, length?)\r\n {\r\n var str = String(this);\r\n if(start < 0)\r\n {\r\n start = str.kmwLength() + start;\r\n }\r\n if(start < 0) start = 0;\r\n var startCodeUnit = str.kmwCodePointToCodeUnit(start);\r\n var endCodeUnit = startCodeUnit;\r\n\r\n if(startCodeUnit === null) return '';\r\n\r\n if(arguments.length < 2) {\r\n endCodeUnit = str.length;\r\n } else {\r\n for(var i = 0; i < length; i++) endCodeUnit = str.kmwNextChar(endCodeUnit);\r\n }\r\n if(endCodeUnit === null)\r\n return str.substring(startCodeUnit);\r\n else\r\n return str.substring(startCodeUnit, endCodeUnit);\r\n }\r\n\r\n /**\r\n * Returns the characters in a string between two indexes into the string.\r\n *\r\n * @param {number} indexA The start code point index in the string to\r\n * extract from\r\n * @param {number} indexB The end code point index in the string to\r\n * extract to\r\n * @return {string} The substring as selected by indexA and indexB\r\n */\r\n String.prototype.kmwSubstring = function(indexA, indexB)\r\n {\r\n var str = String(this),indexACodeUnit,indexBCodeUnit;\r\n\r\n if(typeof(indexB) == 'undefined')\r\n {\r\n indexACodeUnit = str.kmwCodePointToCodeUnit(indexA);\r\n indexBCodeUnit = str.length;\r\n }\r\n else\r\n {\r\n if(indexA > indexB) { var c = indexA; indexA = indexB; indexB = c; }\r\n\r\n indexACodeUnit = str.kmwCodePointToCodeUnit(indexA);\r\n indexBCodeUnit = str.kmwCodePointToCodeUnit(indexB);\r\n }\r\n if(isNaN(indexACodeUnit) || indexACodeUnit === null) indexACodeUnit = 0;\r\n if(isNaN(indexBCodeUnit) || indexBCodeUnit === null) indexBCodeUnit = str.length;\r\n\r\n return str.substring(indexACodeUnit, indexBCodeUnit);\r\n }\r\n\r\n /*\r\n Helper functions\r\n */\r\n\r\n /**\r\n * Returns the code unit index for the next code point in the string, accounting for\r\n * supplementary pairs\r\n *\r\n * @param {number|null} codeUnitIndex The code unit position to increment\r\n * @return {number|null} The index of the next code point in the string,\r\n * in code units\r\n */\r\n String.prototype.kmwNextChar = function(codeUnitIndex) {\r\n var str = String(this);\r\n\r\n if(codeUnitIndex === null || codeUnitIndex < 0 || codeUnitIndex >= str.length - 1) {\r\n return null;\r\n }\r\n\r\n var first = str.charCodeAt(codeUnitIndex);\r\n if (first >= 0xD800 && first <= 0xDBFF && str.length > codeUnitIndex + 1) {\r\n var second = str.charCodeAt(codeUnitIndex + 1);\r\n if (second >= 0xDC00 && second <= 0xDFFF) {\r\n if(codeUnitIndex == str.length - 2) {\r\n return null;\r\n }\r\n return codeUnitIndex + 2;\r\n }\r\n }\r\n return codeUnitIndex + 1;\r\n }\r\n\r\n /**\r\n * Returns the code unit index for the previous code point in the string, accounting\r\n * for supplementary pairs\r\n *\r\n * @param {number|null} codeUnitIndex The code unit position to decrement\r\n * @return {number|null} The index of the previous code point in the\r\n * string, in code units\r\n */\r\n String.prototype.kmwPrevChar = function(codeUnitIndex) {\r\n var str = String(this);\r\n\r\n if(codeUnitIndex == null || codeUnitIndex <= 0 || codeUnitIndex > str.length) {\r\n return null;\r\n }\r\n\r\n var second = str.charCodeAt(codeUnitIndex - 1);\r\n if (second >= 0xDC00 && second <= 0xDFFF && codeUnitIndex > 1) {\r\n var first = str.charCodeAt(codeUnitIndex - 2);\r\n if(first >= 0xD800 && first <= 0xDBFF) {\r\n return codeUnitIndex - 2;\r\n }\r\n }\r\n return codeUnitIndex - 1;\r\n }\r\n\r\n /**\r\n * Returns the corresponding code unit index to the code point index passed\r\n *\r\n * @param {number|null} codePointIndex A code point index in the string\r\n * @return {number|null} The corresponding code unit index\r\n */\r\n String.prototype.kmwCodePointToCodeUnit = function(codePointIndex) {\r\n\r\n if(codePointIndex === null) return null;\r\n\r\n var str = String(this);\r\n var codeUnitIndex = 0;\r\n\r\n if(codePointIndex < 0) {\r\n codeUnitIndex = str.length;\r\n for(var i = 0; i > codePointIndex; i--)\r\n codeUnitIndex = str.kmwPrevChar(codeUnitIndex);\r\n return codeUnitIndex;\r\n }\r\n\r\n if(codePointIndex == str.kmwLength()) return str.length;\r\n\r\n for(var i = 0; i < codePointIndex; i++)\r\n codeUnitIndex = str.kmwNextChar(codeUnitIndex);\r\n return codeUnitIndex;\r\n }\r\n\r\n /**\r\n * Returns the corresponding code point index to the code unit index passed\r\n *\r\n * @param {number|null} codeUnitIndex A code unit index in the string\r\n * @return {number|null} The corresponding code point index\r\n */\r\n String.prototype.kmwCodeUnitToCodePoint = function(codeUnitIndex) {\r\n var str = String(this);\r\n\r\n if(codeUnitIndex === null)\r\n return null;\r\n else if(codeUnitIndex == 0)\r\n return 0;\r\n else if(codeUnitIndex < 0)\r\n return str.substr(codeUnitIndex).kmwLength();\r\n else\r\n return str.substr(0,codeUnitIndex).kmwLength();\r\n }\r\n\r\n /**\r\n * Returns the character at a the code point index passed\r\n *\r\n * @param {number} codePointIndex A code point index in the string\r\n * @return {string} The corresponding character\r\n */\r\n String.prototype.kmwCharAt = function(codePointIndex) {\r\n var str = String(this);\r\n\r\n if(codePointIndex >= 0) return str.kmwSubstr(codePointIndex,1); else return '';\r\n }\r\n\r\n /**\r\n * String prototype library extensions for basic plane characters,\r\n * to simplify enabling or disabling supplementary plane functionality (I3319)\r\n */\r\n\r\n /**\r\n * Returns the code unit index for the next code point in the string\r\n *\r\n * @param {number} codeUnitIndex A code point index in the string\r\n * @return {number|null} The corresponding character\r\n */\r\n String.prototype.kmwBMPNextChar = function(codeUnitIndex)\r\n {\r\n var str = String(this);\r\n if(codeUnitIndex < 0 || codeUnitIndex >= str.length - 1) {\r\n return null;\r\n }\r\n return codeUnitIndex + 1;\r\n }\r\n\r\n /**\r\n * Returns the code unit index for the previous code point in the string\r\n *\r\n * @param {number} codeUnitIndex A code unit index in the string\r\n * @return {number|null} The corresponding character\r\n */\r\n String.prototype.kmwBMPPrevChar = function(codeUnitIndex)\r\n {\r\n var str = String(this);\r\n\r\n if(codeUnitIndex <= 0 || codeUnitIndex > str.length) {\r\n return null;\r\n }\r\n return codeUnitIndex - 1;\r\n }\r\n\r\n /**\r\n * Returns the code unit index for a code point index\r\n *\r\n * @param {number} codePointIndex A code point index in the string\r\n * @return {number} The corresponding character\r\n */\r\n String.prototype.kmwBMPCodePointToCodeUnit = function(codePointIndex)\r\n {\r\n return codePointIndex;\r\n }\r\n\r\n /**\r\n * Returns the code point index for a code unit index\r\n *\r\n * @param {number} codeUnitIndex A code point index in the string\r\n * @return {number} The corresponding character\r\n */\r\n String.prototype.kmwBMPCodeUnitToCodePoint = function(codeUnitIndex)\r\n {\r\n return codeUnitIndex;\r\n }\r\n\r\n /**\r\n * Returns the length of a BMP string\r\n *\r\n * @return {number} The length in code points\r\n */\r\n String.prototype.kmwBMPLength = function()\r\n {\r\n var str = String(this);\r\n return str.length;\r\n }\r\n\r\n /**\r\n * Returns a substring\r\n *\r\n * @param {number} n\r\n * @param {number=} ln\r\n * @return {string}\r\n */\r\n String.prototype.kmwBMPSubstr = function(n,ln?)\r\n {\r\n var str=String(this);\r\n if(n > -1)\r\n return str.substr(n,ln);\r\n else\r\n return str.substr(str.length+n,-n);\r\n }\r\n\r\n /**\r\n * Enable or disable supplementary plane string handling\r\n *\r\n * @param {boolean} bEnable\r\n */\r\n String.kmwEnableSupplementaryPlane = function(bEnable)\r\n {\r\n var p=String.prototype;\r\n String._kmwFromCharCode = bEnable ? String.kmwFromCharCode : String.fromCharCode;\r\n p._kmwCharAt = bEnable ? p.kmwCharAt : p.charAt;\r\n p._kmwCharCodeAt = bEnable ? p.kmwCharCodeAt : p.charCodeAt;\r\n p._kmwIndexOf = bEnable ? p.kmwIndexOf :p.indexOf;\r\n p._kmwLastIndexOf = bEnable ? p.kmwLastIndexOf : p.lastIndexOf ;\r\n p._kmwSlice = bEnable ? p.kmwSlice : p.slice;\r\n p._kmwSubstring = bEnable ? p.kmwSubstring : p.substring;\r\n p._kmwSubstr = bEnable ? p.kmwSubstr : p.kmwBMPSubstr;\r\n p._kmwLength = bEnable ? p.kmwLength : p.kmwBMPLength;\r\n p._kmwNextChar = bEnable ? p.kmwNextChar : p.kmwBMPNextChar;\r\n p._kmwPrevChar = bEnable ? p.kmwPrevChar : p.kmwBMPPrevChar;\r\n p._kmwCodePointToCodeUnit = bEnable ? p.kmwCodePointToCodeUnit : p.kmwBMPCodePointToCodeUnit;\r\n p._kmwCodeUnitToCodePoint = bEnable ? p.kmwCodeUnitToCodePoint : p.kmwBMPCodeUnitToCodePoint;\r\n }\r\n\r\n // Ensure that _all_ String extensions are established, even if disabled by default.\r\n if(!String._kmwFromCharCode) {\r\n String.kmwEnableSupplementaryPlane(false);\r\n }\r\n}\r\n\r\n// For side-effect imports:\r\nextendString();", + "type ResolveSignature = (value: Type | PromiseLike) => void;\r\ntype RejectSignature = (reason?: any) => void;\r\n\r\nexport default class ManagedPromise {\r\n public resolve: ResolveSignature;\r\n public reject: RejectSignature;\r\n\r\n private _hasResolved: boolean = false;\r\n private _hasRejected: boolean = false;\r\n\r\n public get hasResolved(): boolean {\r\n return this._hasResolved;\r\n }\r\n\r\n public get hasRejected(): boolean {\r\n return this._hasRejected;\r\n }\r\n\r\n public get hasFinalized(): boolean {\r\n return this.hasResolved || this.hasRejected;\r\n }\r\n\r\n private _promise: Promise;\r\n\r\n constructor();\r\n constructor(executor: (resolve: ResolveSignature, reject: RejectSignature) => Type);\r\n constructor(executor?: (resolve: ResolveSignature, reject: RejectSignature) => Type) {\r\n this._promise = new Promise((resolve, reject) => {\r\n this.resolve = (value) => {\r\n this._hasResolved = true;\r\n resolve(value);\r\n };\r\n\r\n this.reject = (reason) => {\r\n this._hasRejected = true;\r\n reject(reason);\r\n };\r\n\r\n if(executor) {\r\n executor(this.resolve, this.reject);\r\n }\r\n });\r\n }\r\n\r\n // Cannot actually extend the Promise class in ES5; attempt to use it will throw errors.\r\n // So, we just implement a Promise-like interface.\r\n\r\n then(onfulfilled?: ((value: Type) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise {\r\n return this._promise.then(onfulfilled, onrejected);\r\n }\r\n\r\n catch(onrejected?: (reason: any) => PromiseLike): Promise {\r\n return this._promise.catch(onrejected);\r\n }\r\n\r\n finally(onfinally?: () => void): Promise {\r\n return this._promise.finally(onfinally);\r\n }\r\n\r\n // And for things that actually need to provide something typed to Promise... well...\r\n get corePromise(): Promise {\r\n return this._promise;\r\n }\r\n}", + "/***\r\n KeymanWeb 10.0\r\n Copyright 2017 SIL International\r\n***/\r\n\r\nimport Codes from \"../text/codes.js\";\r\nimport type Keyboard from \"./keyboard.js\";\r\nimport { Version, deepCopy } from \"@keymanapp/web-utils\";\r\n\r\nexport type KLS = {[layerName: string]: string[]};\r\n\r\n// The following types provide type definitions for the full JSON format we use for visual keyboard definitions.\r\nexport type ButtonClass = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;\r\nexport type ButtonClassString = \"0\"|\"1\"|\"2\"|\"3\"|\"4\"|\"5\"|\"6\"|\"7\"|\"8\"|\"9\"|\"10\";\r\n\r\nexport type LayoutKey = {\r\n \"id\"?: string,\r\n \"text\"?: string,\r\n \"sp\"?: ButtonClass | ButtonClassString,\r\n \"width\"?: string | number,\r\n \"layer\"?: string, // Key derives any modifiers from the value set here if specified, not the actual display layer.\r\n \"nextlayer\"?: string,\r\n \"pad\"?: string | number,\r\n \"sk\"?: LayoutKey[]\r\n \"default\"?: boolean\r\n}\r\n\r\nexport type LayoutRow = {\r\n \"id\": string | number,\r\n \"key\": LayoutKey[]\r\n};\r\n\r\nexport type LayoutLayer = {\r\n \"id\": string,\r\n \"row\": LayoutRow[],\r\n\r\n // Post-processing elements.\r\n shiftKey?: LayoutKey,\r\n capsKey?: LayoutKey,\r\n numKey?: LayoutKey,\r\n scrollKey?: LayoutKey,\r\n aligned?: boolean\r\n}\r\n\r\nexport type LayoutFormFactor = {\r\n \"displayUnderlying\"?: boolean,\r\n \"font\": string,\r\n \"layer\": LayoutLayer[],\r\n isDefault?: boolean\r\n}\r\n\r\nexport type LayoutSpec = {\r\n \"desktop\"?: LayoutFormFactor,\r\n \"phone\"?: LayoutFormFactor,\r\n \"tablet\"?: LayoutFormFactor\r\n}\r\n\r\n// This class manages default layout construction for consumption by OSKs without a specified layout.\r\nexport class Layouts {\r\n static dfltCodes=[\r\n \"K_BKQUOTE\",\"K_1\",\"K_2\",\"K_3\",\"K_4\",\"K_5\",\"K_6\",\"K_7\",\"K_8\",\"K_9\",\"K_0\",\r\n \"K_HYPHEN\",\"K_EQUAL\",\"K_*\",\"K_*\",\"K_*\",\"K_Q\",\"K_W\",\"K_E\",\"K_R\",\"K_T\",\r\n \"K_Y\",\"K_U\",\"K_I\",\"K_O\",\"K_P\",\"K_LBRKT\",\"K_RBRKT\",\"K_BKSLASH\",\"K_*\",\r\n \"K_*\",\"K_*\",\"K_A\",\"K_S\",\"K_D\",\"K_F\",\"K_G\",\"K_H\",\"K_J\",\"K_K\",\"K_L\",\r\n \"K_COLON\",\"K_QUOTE\",\"K_*\",\"K_*\",\"K_*\",\"K_*\",\"K_*\",\"K_oE2\",\r\n \"K_Z\",\"K_X\",\"K_C\",\"K_V\",\"K_B\",\"K_N\",\"K_M\",\"K_COMMA\",\"K_PERIOD\",\r\n \"K_SLASH\",\"K_*\",\"K_*\",\"K_*\",\"K_*\",\"K_*\",\"K_SPACE\"\r\n ];\r\n\r\n static dfltText='`1234567890-=\\xA7~~qwertyuiop[]\\\\~~~asdfghjkl;\\'~~~~~?zxcvbnm,./~~~~~ '\r\n +'~!@#$%^&*()_+\\xA7~~QWERTYUIOP{}\\\\~~~ASDFGHJKL:\"~~~~~?ZXCVBNM<>?~~~~~ ';\r\n\r\n static readonly DEFAULT_RAW_SPEC = {'F':'Tahoma', 'BK': Layouts.dfltText};\r\n\r\n // Cross-reference with the ids in osk.setButtonClass.\r\n static buttonClasses: {[name: string]: ButtonClass} = {\r\n 'DEFAULT':0,\r\n 'SHIFT':1,\r\n 'SHIFT-ON':2,\r\n 'SPECIAL':3,\r\n 'SPECIAL-ON':4,\r\n 'DEADKEY':8,\r\n 'BLANK':9,\r\n 'HIDDEN':10\r\n };\r\n\r\n static modifierSpecials = {\r\n 'leftalt': '*LAlt*',\r\n 'rightalt': '*RAlt*',\r\n 'alt': '*Alt*',\r\n 'leftctrl': '*LCtrl*',\r\n 'rightctrl': '*RCtrl*',\r\n 'ctrl': '*Ctrl*',\r\n 'ctrl-alt': '*AltGr*',\r\n 'leftctrl-leftalt': '*LAltCtrl*',\r\n 'rightctrl-rightalt': '*RAltCtrl*',\r\n 'leftctrl-leftalt-shift': '*LAltCtrlShift*',\r\n 'rightctrl-rightalt-shift': '*RAltCtrlShift*',\r\n 'shift': '*Shift*',\r\n 'shift-alt': '*AltShift*',\r\n 'shift-ctrl': '*CtrlShift*',\r\n 'shift-ctrl-alt': '*AltCtrlShift*',\r\n 'leftalt-shift': '*LAltShift*',\r\n 'rightalt-shift': '*RAltShift*',\r\n 'leftctrl-shift': '*LCtrlShift*',\r\n 'rightctrl-shift': '*RCtrlShift*'\r\n };\r\n\r\n /**\r\n * Build a default layout for keyboards with no explicit layout\r\n *\r\n * @param {Object} PVK raw specifications\r\n * @param {Keyboard} keyboard keyboard object (as loaded)\r\n * @param {string} formFactor (really utils.FormFactor)\r\n * @return {LayoutFormFactor}\r\n */\r\n static buildDefaultLayout(PVK, keyboard: Keyboard, formFactor: string): LayoutFormFactor {\r\n // Build a layout using the default for the device\r\n var layoutType=formFactor;\r\n\r\n if(typeof Layouts.dfltLayout[layoutType] != 'object') {\r\n layoutType = 'desktop';\r\n }\r\n\r\n let kbdBitmask = Codes.modifierBitmasks['NON_CHIRAL'];\r\n // An unfortunate dependency there. Should probably also set a version within web-core for use.\r\n let kbdDevVersion = Version.CURRENT;\r\n if(keyboard) {\r\n kbdBitmask = keyboard.modifierBitmask;\r\n kbdDevVersion = keyboard.compilerVersion;\r\n }\r\n\r\n if(!PVK) {\r\n PVK = this.DEFAULT_RAW_SPEC;\r\n }\r\n\r\n // Clone the default layout object for this device\r\n var layout: LayoutFormFactor = deepCopy(Layouts.dfltLayout[layoutType]);\r\n\r\n var n,layers=layout['layer'], keyLabels: KLS=PVK['KLS'], key102=PVK['K102'];\r\n var i, j, k, m, row, rows: LayoutRow[], key: LayoutKey, keys: LayoutKey[];\r\n var chiral: boolean = (kbdBitmask & Codes.modifierBitmasks.IS_CHIRAL) != 0;\r\n\r\n if(PVK['F']) {\r\n // The KeymanWeb compiler generates a string of the format `[italic ][bold ] 1em \"\"`\r\n // We will ignore the bold, italic and font size spec\r\n let legacyFontSpec = /^(?:(?:italic|bold) )* *[0-9.eE-]+(?:[a-z]+) \"(.+)\"$/.exec(PVK['F']);\r\n if(legacyFontSpec) {\r\n layout.font = legacyFontSpec[1];\r\n }\r\n }\r\n\r\n var kmw10Plus = !(typeof keyLabels == 'undefined' || !keyLabels);\r\n if(!kmw10Plus) {\r\n // Save the processed key label information to the keyboard's general data.\r\n // Makes things more efficient elsewhere and for reloading after keyboard swaps.\r\n keyLabels = PVK['KLS'] = Layouts.processLegacyDefinitions(PVK['BK']);\r\n }\r\n\r\n // Identify key labels (e.g. *Shift*) that require the special OSK font\r\n var specialLabel=/\\*\\w+\\*/;\r\n\r\n // *** Step 1: instantiate the layer objects. ***\r\n\r\n // Get the list of valid layers, enforcing that the 'default' layer must be the first one processed.\r\n var validIdList = Object.getOwnPropertyNames(keyLabels), invalidIdList = [];\r\n validIdList.splice(validIdList.indexOf('default'), 1);\r\n validIdList = [ 'default' ].concat(validIdList);\r\n\r\n // Automatic AltGr emulation if the 'leftctrl-leftalt' layer is otherwise undefined.\r\n if(keyboard && keyboard.emulatesAltGr) {\r\n // We insert only the layers that need to be emulated.\r\n if((validIdList.indexOf('leftctrl-leftalt') == -1) && validIdList.indexOf('rightalt') != -1) {\r\n validIdList.push('leftctrl-leftalt');\r\n keyLabels['leftctrl-leftalt'] = keyLabels['rightalt'];\r\n }\r\n\r\n if((validIdList.indexOf('leftctrl-leftalt-shift') == -1) && validIdList.indexOf('rightalt-shift') != -1) {\r\n validIdList.push('leftctrl-leftalt-shift');\r\n keyLabels['leftctrl-leftalt-shift'] = keyLabels['rightalt-shift'];\r\n }\r\n }\r\n\r\n // If there is no predefined layout, even touch layouts will follow the desktop's\r\n // setting for the displayUnderlying flag. As the desktop layout uses a different\r\n // format for its layout spec, that's found at the field referenced below.\r\n layout[\"displayUnderlying\"] = keyboard ? !!keyboard.scriptObject['KDU'] : false;\r\n\r\n // For desktop devices, we must create all layers, even if invalid.\r\n if(formFactor == 'desktop') {\r\n invalidIdList = Layouts.generateLayerIds(chiral);\r\n\r\n // Filter out all ids considered valid. (We also don't want duplicates in the following list...)\r\n for(n=0; n 0) {\r\n layers[n]=deepCopy(layers[0]);\r\n }\r\n layers[n]['id']=idList[n];\r\n layers[n]['nextlayer']=idList[n]; // This would only be different for a dynamic keyboard\r\n\r\n // Extraced into a helper method to improve readability.\r\n Layouts.formatDefaultLayer(layers[n], chiral, formFactor, !!key102);\r\n }\r\n\r\n // *** Step 2: Layer objects now exist; time to fill them with the appropriate key labels and key styles ***\r\n for(n=0; n= 0 && kx < layerSpec.length) key['text']=layerSpec[kx];\r\n }\r\n\r\n // Legacy (pre 12.0) behavior: fall back to US English keycap text as default for the base two layers\r\n // if a key cap is not otherwise defined. (Any intentional 'ghost' keys must be explicitly defined.)\r\n if(isDefault && kbdDevVersion.precedes(Version.NO_DEFAULT_KEYCAPS)) {\r\n if(key['id'] != 'K_SPACE' && kx+65 * isShift < Layouts.dfltText.length && key['text'] !== null) {\r\n key['text'] = key['text'] || Layouts.dfltText[kx+65*isShift];\r\n }\r\n }\r\n }\r\n\r\n // Leave any unmarked key caps as null strings\r\n if(key['text'] !== null) {\r\n key['text'] = key['text'] || '';\r\n }\r\n\r\n // Detect important tracking keys.\r\n switch(key['id']) {\r\n case \"K_SHIFT\":\r\n shiftKey=key;\r\n break;\r\n case \"K_TAB\":\r\n nextKey=key;\r\n break;\r\n case \"K_CAPS\":\r\n capsKey=key;\r\n break;\r\n case \"K_NUMLOCK\":\r\n numKey=key;\r\n break;\r\n case \"K_SCROLL\":\r\n scrollKey=key;\r\n break;\r\n }\r\n\r\n // Remove pop-up shift keys referencing invalid layers (Build 349)\r\n if(key['sk'] != null) {\r\n for(k=0; k 0 && shiftKey != null) {\r\n shiftKey['sp']=Layouts.buttonClasses['SHIFT-ON'];\r\n shiftKey['sk']=null;\r\n shiftKey['text'] = Layouts.modifierSpecials[layers[n].id] ? Layouts.modifierSpecials[layers[n].id] : \"*Shift*\";\r\n }\r\n }\r\n }\r\n\r\n return layout;\r\n }\r\n\r\n /**\r\n * Function getLayerId\r\n * Scope Private\r\n * @param {number} m shift modifier code\r\n * @return {string} layer string from shift modifier code (desktop keyboards)\r\n * Description Get name of layer from code, where the modifer order is determined by ascending bit-flag value.\r\n */\r\n static getLayerId(m: number): string {\r\n let modifierCodes = Codes.modifierCodes;\r\n\r\n var s='';\r\n if(m == 0) {\r\n return 'default';\r\n } else {\r\n if(m & modifierCodes['LCTRL']) {\r\n s = (s.length > 0 ? s + '-' : '') + 'leftctrl';\r\n }\r\n if(m & modifierCodes['RCTRL']) {\r\n s = (s.length > 0 ? s + '-' : '') + 'rightctrl';\r\n }\r\n if(m & modifierCodes['LALT']) {\r\n s = (s.length > 0 ? s + '-' : '') + 'leftalt';\r\n }\r\n if(m & modifierCodes['RALT']) {\r\n s = (s.length > 0 ? s + '-' : '') + 'rightalt';\r\n }\r\n if(m & modifierCodes['SHIFT']) {\r\n s = (s.length > 0 ? s + '-' : '') + 'shift';\r\n }\r\n if(m & modifierCodes['CTRL']) {\r\n s = (s.length > 0 ? s + '-' : '') + 'ctrl';\r\n }\r\n if(m & modifierCodes['ALT']) {\r\n s = (s.length > 0 ? s + '-' : '') + 'alt';\r\n }\r\n return s;\r\n }\r\n }\r\n\r\n /**\r\n * Generates a list of potential layer ids for the specified chirality mode.\r\n *\r\n * @param {boolean} chiral // Does the keyboard use chiral modifiers or not?\r\n */\r\n static generateLayerIds(chiral: boolean): string[] {\r\n var layerCnt, offset;\r\n\r\n if(chiral) {\r\n layerCnt=32;\r\n offset=0x01;\r\n } else {\r\n layerCnt=8;\r\n offset=0x10;\r\n }\r\n\r\n var layerIds = [];\r\n\r\n for(var i=0; i < layerCnt; i++) {\r\n layerIds.push(Layouts.getLayerId(i * offset));\r\n }\r\n\r\n return layerIds;\r\n }\r\n\r\n /**\r\n * Sets a formatting property for the modifier keys when constructing a default layout for a keyboard.\r\n *\r\n * @param {Object} layer // One layer specification\r\n * @param {boolean} chiral // Whether or not the keyboard uses chiral modifier information.\r\n * @param {string} formFactor // The form factor of the device the layout is being constructed for.\r\n * @param {boolean} key102 // Whether or not the extended key 102 should be hidden.\r\n */\r\n static formatDefaultLayer(layer: LayoutLayer, chiral: boolean, formFactor: string, key102: boolean) {\r\n var layerId = layer['id'];\r\n let buttonClasses = Layouts.buttonClasses;\r\n\r\n // Correct appearance of state-dependent modifier keys according to group\r\n for(var i=0; i sil_euro_latin_js.txt)\r\n *\r\n * Reference: https://help.keyman.com/developer/language/reference/kmw_embedjs\r\n */\r\n embedScript(e: any) {\r\n // e: Expects the OSKManager's _Box element. We don't add type info here b/c it would\r\n // reference the DOM.\r\n this.scriptObject['KHF'](e);\r\n }\r\n\r\n get oskStyling(): string {\r\n return this.scriptObject['KCSS'];\r\n }\r\n\r\n /**\r\n * true if this keyboard uses a (legacy) pick list (Chinese, Japanese, Korean, etc.)\r\n *\r\n * TODO: Make a property on keyboards (say, `isPickList` / `KPL`) to signal this when we\r\n * get around to better, generalized picker-list support.\r\n */\r\n get isCJK(): boolean { // I3363 (Build 301)\r\n var lg: string;\r\n if(typeof(this.scriptObject['KLC']) != 'undefined') {\r\n lg = this.scriptObject['KLC'];\r\n } else if(typeof(this.scriptObject['LanguageCode']) != 'undefined') {\r\n lg = this.scriptObject['LanguageCode'];\r\n }\r\n\r\n // While some of these aren't proper BCP-47 language codes, the CJK keyboards predate our use of BCP-47.\r\n // So, we preserve the old ISO 639-3 codes, as that's what the keyboards are matching against.\r\n return ((lg == 'cmn') || (lg == 'jpn') || (lg == 'kor'));\r\n }\r\n\r\n get isRTL(): boolean {\r\n return !!this.scriptObject['KRTL'];\r\n }\r\n\r\n /**\r\n * Obtains the currently-active modifier bitmask for the active keyboard.\r\n */\r\n get modifierBitmask(): number {\r\n // NON_CHIRAL is the default bitmask if KMBM is not defined.\r\n // We always need a bitmask to compare against, as seen in `isChiral`.\r\n return this.scriptObject['KMBM'] || Codes.modifierBitmasks['NON_CHIRAL'];\r\n }\r\n\r\n get isChiral(): boolean {\r\n return !!(this.modifierBitmask & Codes.modifierBitmasks['IS_CHIRAL']);\r\n }\r\n\r\n get desktopFont(): string {\r\n if(this.scriptObject['KV']) {\r\n return this.scriptObject['KV']['F'];\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n private get cacheTag(): CacheTag {\r\n let tag = this.scriptObject['_kmw'];\r\n\r\n if(!tag) {\r\n tag = new CacheTag();\r\n this.scriptObject['_kmw'] = tag;\r\n }\r\n\r\n return tag;\r\n }\r\n\r\n get explodedStores(): {[storeName: string]: ComplexKeyboardStore} {\r\n return this.cacheTag.stores;\r\n }\r\n\r\n /**\r\n * Signifies whether or not a layout or OSK should include AltGr / Right-alt emulation for this keyboard.\r\n * @param {Object=} keyLabels\r\n * @return {boolean}\r\n */\r\n get emulatesAltGr(): boolean {\r\n let modifierCodes = Codes.modifierCodes;\r\n\r\n // If we're not chiral, we're not emulating.\r\n if(!this.isChiral) {\r\n return false;\r\n }\r\n\r\n if(this._legacyLayoutSpec == null) {\r\n return false;\r\n }\r\n\r\n // Only exists in KMW 10.0+, but before that Web had no chirality support, so... return false.\r\n let layers = this._legacyLayoutSpec['KLS'];\r\n if(!layers) {\r\n return false;\r\n }\r\n\r\n var emulationMask = modifierCodes['LCTRL'] | modifierCodes['LALT'];\r\n var unshiftedEmulationLayer = layers[Layouts.getLayerId(emulationMask)];\r\n var shiftedEmulationLayer = layers[Layouts.getLayerId(modifierCodes['SHIFT'] | emulationMask)];\r\n\r\n // buildDefaultLayout ensures that these are aliased to the original modifier set being emulated.\r\n // As a result, we can directly test for reference equality.\r\n //\r\n // This allows us to still return `true` after creating the layers for emulation; during keyboard\r\n // construction, the two layers should be null for AltGr emulation to succeed.\r\n if(unshiftedEmulationLayer != null &&\r\n unshiftedEmulationLayer != layers[Layouts.getLayerId(modifierCodes['RALT'])]) {\r\n return false;\r\n }\r\n\r\n if(shiftedEmulationLayer != null &&\r\n shiftedEmulationLayer != layers[Layouts.getLayerId(modifierCodes['RALT'] | modifierCodes['SHIFT'])]) {\r\n return false;\r\n }\r\n\r\n // It's technically possible for the OSK to not specify anything while allowing chiral input. A last-ditch catch:\r\n var bitmask = this.modifierBitmask;\r\n if((bitmask & emulationMask) != emulationMask) {\r\n // At least one of the emulation modifiers is never used by the keyboard! We can confirm everything's safe.\r\n return true;\r\n }\r\n\r\n if(unshiftedEmulationLayer == null && shiftedEmulationLayer == null) {\r\n // We've run out of things to go on; we can't detect if chiral AltGr emulation is intended or not.\r\n // TODO: handle this again!\r\n // if(!osk.altGrWarning) {\r\n // console.warn(\"Could not detect if AltGr emulation is safe, but defaulting to active emulation!\")\r\n // // Avoid spamming the console with warnings on every call of the method.\r\n // osk.altGrWarning = true;\r\n // }\r\n return true;\r\n }\r\n return true;\r\n }\r\n\r\n get usesSupplementaryPlaneChars(): boolean {\r\n let kbd = this.scriptObject;\r\n // I3319 - SMP extension, I3363 (Build 301)\r\n return kbd && ((kbd['KS'] && kbd['KS'] == 1) || kbd['KN'] == 'Hieroglyphic');\r\n }\r\n\r\n get version(): string {\r\n return this.scriptObject['KBVER'] || '';\r\n }\r\n\r\n usesDesktopLayoutOnDevice(device: DeviceSpec) {\r\n if(this.scriptObject['KVKL']) {\r\n // A custom mobile layout is defined... but are we using it?\r\n return device.formFactor == DeviceSpec.FormFactor.Desktop;\r\n } else {\r\n return true;\r\n }\r\n }\r\n\r\n /**\r\n * @param {number} _PCommand event code (16,17,18) or 0\r\n * @param {Object} _PTarget target element\r\n * @param {number} _PData 1 or 0\r\n * Notifies keyboard of keystroke or other event\r\n */\r\n notify(_PCommand: number, _PTarget: OutputTarget, _PData: number) { // I2187\r\n // Good example use case - the Japanese CJK-picker keyboard\r\n if(typeof(this.scriptObject['KNS']) == 'function') {\r\n this.scriptObject['KNS'](_PCommand, _PTarget, _PData);\r\n }\r\n }\r\n\r\n private findOrConstructLayout(formFactor: DeviceSpec.FormFactor): LayoutFormFactor {\r\n if(this._layouts) {\r\n // Search for viable layouts. `null` is allowed for desktop form factors when help text is available,\r\n // so we check explicitly against `undefined`.\r\n if(this._layouts[formFactor] !== undefined) {\r\n return this._layouts[formFactor];\r\n } else if(formFactor == DeviceSpec.FormFactor.Phone && this._layouts[DeviceSpec.FormFactor.Tablet]) {\r\n return this._layouts[DeviceSpec.FormFactor.Phone] = this._layouts[DeviceSpec.FormFactor.Tablet];\r\n } else if(formFactor == DeviceSpec.FormFactor.Tablet && this._layouts[DeviceSpec.FormFactor.Phone]) {\r\n return this._layouts[DeviceSpec.FormFactor.Tablet] = this._layouts[DeviceSpec.FormFactor.Phone];\r\n }\r\n }\r\n\r\n // No pre-built layout available; time to start constructing it via defaults.\r\n // First, if we have non-default keys specified by the ['BK'] array, we've got\r\n // enough to work with to build a default layout.\r\n let rawSpecifications: any = null; // TODO: better typing, same type as this._legacyLayoutSpec.\r\n if(this._legacyLayoutSpec != null && this._legacyLayoutSpec['KLS']) { // KLS is only specified whenever there are non-default keys.\r\n rawSpecifications = this._legacyLayoutSpec;\r\n } else if(this._legacyLayoutSpec != null && this._legacyLayoutSpec['BK'] != null) {\r\n var keyCaps=this._legacyLayoutSpec['BK'];\r\n for(var i=0; i 0) {\r\n rawSpecifications = this._legacyLayoutSpec;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // If we don't have key definitions to use for a layout but also lack help text or are a touch-based layout,\r\n // we make a default layout anyway. We have to show display something usable.\r\n if(!rawSpecifications && (this.helpText == '' || formFactor != DeviceSpec.FormFactor.Desktop)) {\r\n rawSpecifications = {'F':'Tahoma', 'BK': Layouts.dfltText};\r\n }\r\n\r\n // Regardless of success, we'll want to initialize the field that backs the property;\r\n // may as well cache the default layout we just built, or a 'null' if it shouldn't exist..\r\n if(!this._layouts) {\r\n this._layouts = {};\r\n }\r\n\r\n // Final check - do we construct a layout, or is this a case where helpText / insertHelpHTML should take over?\r\n if(rawSpecifications) {\r\n // Now to generate a layout from our raw specifications.\r\n let layout = this._layouts[formFactor] = Layouts.buildDefaultLayout(rawSpecifications, this, formFactor);\r\n layout.isDefault = true;\r\n return layout;\r\n } else {\r\n // The fact that it doesn't exist will indicate that help text/HTML should be inserted instead.\r\n this._layouts[formFactor] = null; // provides a cached value for the check at the top of this method.\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Returns an ActiveLayout object representing the keyboard's layout for this form factor. May return null if a custom desktop \"help\" OSK is defined, as with sil_euro_latin.\r\n *\r\n * In such cases, please use either `helpText` or `insertHelpHTML` instead.\r\n * @param formFactor {string} The desired form factor for the layout.\r\n */\r\n public layout(formFactor: DeviceSpec.FormFactor): ActiveLayout {\r\n let rawLayout = this.findOrConstructLayout(formFactor);\r\n\r\n if(rawLayout) {\r\n // Prevents accidentally reprocessing layouts; it's a simple enough check.\r\n if(this.layoutStates[formFactor] == LayoutState.NOT_LOADED) {\r\n rawLayout = ActiveLayout.polyfill(rawLayout, this, formFactor);\r\n this.layoutStates[formFactor] = LayoutState.POLYFILLED;\r\n }\r\n\r\n return rawLayout as ActiveLayout;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n public refreshLayouts() {\r\n let formFactors = [ DeviceSpec.FormFactor.Desktop, DeviceSpec.FormFactor.Phone, DeviceSpec.FormFactor.Tablet ];\r\n\r\n let _this = this;\r\n\r\n formFactors.forEach(function(form) {\r\n // Currently doesn't work if we reset it to POLYFILLED, likely due to how 'calibration'\r\n // currently works.\r\n _this.layoutStates[form] = LayoutState.NOT_LOADED;\r\n });\r\n }\r\n\r\n public markLayoutCalibrated(formFactor: DeviceSpec.FormFactor) {\r\n if(this.layoutStates[formFactor] != LayoutState.NOT_LOADED) {\r\n this.layoutStates[formFactor] = LayoutState.CALIBRATED;\r\n }\r\n }\r\n\r\n public getLayoutState(formFactor: DeviceSpec.FormFactor) {\r\n return this.layoutStates[formFactor];\r\n }\r\n\r\n\r\n constructNullKeyEvent(device: DeviceSpec, stateKeys?: StateKeyMap): KeyEvent {\r\n stateKeys = stateKeys || {\r\n K_CAPS: false,\r\n K_NUMLOCK: false,\r\n K_SCROLL: false\r\n }\r\n\r\n const keyEvent = KeyEvent.constructNullKeyEvent(device);\r\n this.setSyntheticEventDefaults(keyEvent, stateKeys);\r\n return keyEvent;\r\n }\r\n\r\n constructKeyEvent(key: ActiveKey, device: DeviceSpec, stateKeys: StateKeyMap): KeyEvent {\r\n // Make a deep copy of our preconstructed key event, filling it out from there.\r\n const Lkc = key.baseKeyEvent;\r\n Lkc.device = device;\r\n\r\n if(this.isMnemonic) {\r\n Lkc.setMnemonicCode(key.layer.indexOf('shift') != -1, stateKeys['K_CAPS']);\r\n }\r\n\r\n // Performs common pre-analysis for both 'native' and 'embedded' OSK key & subkey input events.\r\n // This part depends on the keyboard processor's active state.\r\n this.setSyntheticEventDefaults(Lkc, stateKeys);\r\n\r\n // If it's a state key modifier, trigger its effects as part of the\r\n // keystroke.\r\n const bitmap = {\r\n 'K_CAPS': Codes.stateBitmasks.CAPS,\r\n 'K_NUMLOCK': Codes.stateBitmasks.NUM_LOCK,\r\n 'K_SCROLL': Codes.stateBitmasks.SCROLL_LOCK\r\n };\r\n const bitmask = bitmap[Lkc.kName];\r\n\r\n if(bitmask) {\r\n Lkc.Lstates ^= bitmask;\r\n Lkc.LmodifierChange = true;\r\n }\r\n\r\n return Lkc;\r\n }\r\n\r\n setSyntheticEventDefaults(Lkc: KeyEvent, stateKeys: StateKeyMap) {\r\n // Set the flags for the state keys - for desktop devices. For touch\r\n // devices, the only state key in use currently is Caps Lock, which is set\r\n // when the 'caps' layer is active in ActiveKey::constructBaseKeyEvent.\r\n if(!Lkc.device.touchable) {\r\n /*\r\n * For desktop-style keyboards, start from a blank slate. They have a 'default'\r\n * (implicit 'NO_CAPS') layer but not a 'caps' layer. With caps set, it just\r\n * highlights the key on the 'default' layer instead.\r\n *\r\n * We should never set both `CAPS` and `NO_CAPS` at the same time, and\r\n * same for the other modifiers.\r\n */\r\n Lkc.Lstates = 0;\r\n Lkc.Lstates |= stateKeys['K_CAPS'] ? Codes.modifierCodes['CAPS'] : Codes.modifierCodes['NO_CAPS'];\r\n Lkc.Lstates |= stateKeys['K_NUMLOCK'] ? Codes.modifierCodes['NUM_LOCK'] : Codes.modifierCodes['NO_NUM_LOCK'];\r\n Lkc.Lstates |= stateKeys['K_SCROLL'] ? Codes.modifierCodes['SCROLL_LOCK'] : Codes.modifierCodes['NO_SCROLL_LOCK'];\r\n }\r\n\r\n // Set LisVirtualKey to false to ensure that nomatch rule does fire for U_xxxx keys\r\n if(Lkc.kName && Lkc.kName.substr(0,2) == 'U_') {\r\n Lkc.LisVirtualKey=false;\r\n }\r\n\r\n // Get code for non-physical keys (T_KOKAI, U_05AB etc)\r\n if(typeof Lkc.Lcode == 'undefined') {\r\n Lkc.Lcode = this.getVKDictionaryCode(Lkc.kName);// Updated for Build 347\r\n if(!Lkc.Lcode) {\r\n // Special case for U_xxxx keys. This vk code will never be used\r\n // in a keyboard, so we use this to ensure that keystroke processing\r\n // occurs for the key.\r\n Lkc.Lcode = 1;\r\n }\r\n }\r\n\r\n // Handles modifier states when the OSK is emulating rightalt through the leftctrl-leftalt layer.\r\n if((Lkc.Lmodifiers & Codes.modifierBitmasks['ALT_GR_SIM']) == Codes.modifierBitmasks['ALT_GR_SIM'] && this.emulatesAltGr) {\r\n Lkc.Lmodifiers &= ~Codes.modifierBitmasks['ALT_GR_SIM'];\r\n Lkc.Lmodifiers |= Codes.modifierCodes['RALT'];\r\n }\r\n }\r\n\r\n /**\r\n * @summary Look up a custom virtual key code in the virtual key code dictionary KVKD.\r\n * On first run, will build the dictionary.\r\n *\r\n * `VKDictionary` is constructed from the keyboard's `KVKD` member. This list is constructed\r\n * at compile-time and is a list of 'additional' virtual key codes, starting at 256 (i.e.\r\n * outside the range of standard virtual key codes). These additional codes are both\r\n * `[T_xxx]` and `[U_xxxx]` custom key codes from the Keyman keyboard language. However,\r\n * `[U_xxxx]` keys only generate an entry in `KVKD` if there is a corresponding rule that\r\n * is associated with them in the keyboard rules. If the `[U_xxxx]` key code is only\r\n * referenced as the id of a key in the touch layout, then it does not get an entry in\r\n * the `KVKD` property.\r\n *\r\n * @private\r\n * @param {string} keyName custom virtual key code to lookup in the dictionary\r\n * @return {number} key code > 255 on success, or 0 if not found\r\n */\r\n getVKDictionaryCode(keyName: string) {\r\n if(!this.scriptObject['VKDictionary']) {\r\n const a=[];\r\n if(typeof this.scriptObject['KVKD'] == 'string') {\r\n // Build the VK dictionary\r\n // TODO: Move the dictionary build into the compiler -- so compiler generates code such as following.\r\n // Makes the VKDictionary member unnecessary.\r\n // this.KVKD={\"K_ABC\":256,\"K_DEF\":257,...};\r\n const s=this.scriptObject['KVKD'].split(' ');\r\n for(var i=0; i {\r\n this.harness.install();\r\n const promise = this.loadKeyboardInternal(uri, new UriBasedErrorBuilder(uri));\r\n\r\n return promise;\r\n }\r\n\r\n public loadKeyboardFromStub(stub: KeyboardStub) {\r\n this.harness.install();\r\n let promise = this.loadKeyboardInternal(stub.filename, new StubBasedErrorBuilder(stub), stub.id);\r\n\r\n return promise;\r\n }\r\n\r\n protected abstract loadKeyboardInternal(\r\n uri: string,\r\n errorBuilder: KeyboardLoadErrorBuilder,\r\n id?: string\r\n ): Promise;\r\n}", + "// Compiles completely out if `const enum`, making it unavailable in JS-based unit tests.\r\nenum SpacebarText {\r\n KEYBOARD = 'keyboard',\r\n LANGUAGE = 'language',\r\n LANGUAGE_KEYBOARD = 'languageKeyboard',\r\n BLANK = 'blank'\r\n};\r\n\r\nexport default SpacebarText;", + "import SpacebarText from './spacebarText.js';\r\n\r\nexport interface InternalKeyboardFont {\r\n family: string;\r\n filename?: never;\r\n files: string | string[]; // internal\r\n source?: never;\r\n path: string;\r\n}\r\n\r\ninterface CloudKeyboardFont1 {\r\n family: string;\r\n filename: string | string[];\r\n files?: never;\r\n source?: never;\r\n}\r\n\r\ninterface CloudKeyboardFont2 {\r\n family: string;\r\n filename?: never;\r\n files?: never;\r\n source: string | string[];\r\n}\r\n\r\nexport type CloudKeyboardFont = CloudKeyboardFont1 | CloudKeyboardFont2;\r\n\r\n/**\r\n * Converts one of three public-facing font-specification formats into a consistent structure\r\n * used generally among the Keyman JS/TS modules.\r\n * @param fontObj\r\n * @param fontPath\r\n * @returns\r\n */\r\nexport function internalizeFont(fontObj: CloudKeyboardFont, fontPath: string): InternalKeyboardFont {\r\n if(!fontObj) {\r\n return undefined;\r\n } else {\r\n return {\r\n family: fontObj.family,\r\n path: fontPath,\r\n files: fontObj.filename || fontObj.source\r\n }\r\n }\r\n}\r\n\r\nexport type KeyboardFont = CloudKeyboardFont | InternalKeyboardFont;\r\n\r\n// Filename properties are deliberately omitted here; we can add that at higher-levels where it matters\r\n// via 'mix-in'.\r\n//\r\n// For example, the OSK module doesn't care about the filename of a loaded keyboard. It doesn't do\r\n// keyboard loading on its own whatsoever.\r\n\r\n// Corresponds to Keyman Engine for Web's internal \"keyboard stub\" format.\r\n// Also referred to by KMW 2.0-era loaders: https://help.keyman.com/developer/8.0/docs/reference_kmw20_example\r\nexport interface KeyboardInternalPropertySpec {\r\n KI: string,\r\n KFont: InternalKeyboardFont,\r\n KOskFont: InternalKeyboardFont,\r\n displayName?: string,\r\n KN?: string,\r\n KL?: string,\r\n KLC?: string\r\n};\r\n\r\nexport type LanguageAPIPropertySpec = {\r\n id: string,\r\n name: string,\r\n font: CloudKeyboardFont,\r\n oskFont: CloudKeyboardFont,\r\n region?: number|string\r\n}\r\n\r\n/**\r\n * Corresponds to the documented API for the Web engine's `addKeyboards` function\r\n * when a single language object is specified - not an array.\r\n *\r\n * See https://help.keyman.com/DEVELOPER/ENGINE/WEB/15.0/reference/core/addKeyboards,\r\n * \"Using an `object`\".\r\n */\r\nexport type KeyboardAPIPropertySpec = {\r\n id: string,\r\n name: string,\r\n\r\n /**\r\n * @deprecated Replaced with `languages`.\r\n */\r\n language?: LanguageAPIPropertySpec;\r\n languages: LanguageAPIPropertySpec;\r\n}\r\n\r\n/**\r\n * Corresponds to the documented API for the Web engine's `addKeyboards` function\r\n * when a language array is specified for the object.\r\n *\r\n * See https://help.keyman.com/DEVELOPER/ENGINE/WEB/15.0/reference/core/addKeyboards,\r\n * \"Using an `object`\".\r\n */\r\nexport type KeyboardAPIPropertyMultilangSpec = {\r\n id: string,\r\n name: string,\r\n\r\n /**\r\n * @deprecated Replaced with `languages`.\r\n */\r\n language?: LanguageAPIPropertySpec[];\r\n languages: LanguageAPIPropertySpec[];\r\n}\r\n\r\nexport type MetadataObj = KeyboardInternalPropertySpec | KeyboardAPIPropertySpec | KeyboardAPIPropertyMultilangSpec;\r\n\r\nexport default class KeyboardProperties implements KeyboardInternalPropertySpec {\r\n KI: string;\r\n KN: string;\r\n KL: string;\r\n KLC: string;\r\n KFont: InternalKeyboardFont;\r\n KOskFont: InternalKeyboardFont;\r\n _displayName?: string;\r\n\r\n private static spacebarTextModeSrc: SpacebarText | (() => SpacebarText) = SpacebarText.KEYBOARD;\r\n\r\n public static get spacebarTextMode(): SpacebarText {\r\n if(typeof this.spacebarTextModeSrc == 'string') {\r\n return this.spacebarTextModeSrc;\r\n } else {\r\n return this.spacebarTextModeSrc();\r\n }\r\n }\r\n\r\n public static set spacebarTextMode(source: typeof KeyboardProperties.spacebarTextModeSrc) {\r\n this.spacebarTextModeSrc = source;\r\n }\r\n\r\n public constructor(metadataObj: MetadataObj, fontPath?: string);\r\n public constructor(keyboardId: string, languageCode: string);\r\n public constructor(arg1: MetadataObj | string, arg2?: string) {\r\n if(!(typeof arg1 == 'string')) {\r\n if(arg1['KI'] || arg1['KL'] || arg1['KLC'] || arg1['KFont'] || arg1['KOskFont']) {\r\n const other = arg1 as KeyboardInternalPropertySpec;\r\n this.KI = other.KI;\r\n this.KN = other.KN;\r\n this.KL = other.KL;\r\n this.KLC = other.KLC;\r\n // Do NOT apply fontPath here; the mobile apps will have font issues if you do!\r\n this.KFont = other.KFont;\r\n this.KOskFont = other.KOskFont;\r\n this._displayName = (other instanceof KeyboardProperties) ? other._displayName : other.displayName;\r\n } else {\r\n let apiStub = arg1 as KeyboardAPIPropertySpec; // TODO: could be an array, as currently specified. :(\r\n\r\n apiStub.languages ||= apiStub.language;\r\n\r\n this.KI = apiStub.id,\r\n this.KN = apiStub.name,\r\n this.KL = apiStub.languages.name,\r\n this.KLC = apiStub.languages.id,\r\n this.KFont = internalizeFont(apiStub.languages.font, arg2),\r\n this.KOskFont = internalizeFont(apiStub.languages.oskFont, arg2)\r\n }\r\n } else {\r\n this.KI = arg1;\r\n this.KLC = arg2;\r\n }\r\n }\r\n\r\n public static fromMultilanguageAPIStub(apiStub: KeyboardAPIPropertyMultilangSpec): KeyboardProperties[] {\r\n let stubs: KeyboardProperties[] = [];\r\n\r\n apiStub.languages ||= apiStub.language;\r\n\r\n for(let langSpec of apiStub.languages) {\r\n let stub: KeyboardAPIPropertySpec = {\r\n id: apiStub.id,\r\n name: apiStub.name,\r\n languages: langSpec\r\n };\r\n\r\n stubs.push(new KeyboardProperties(stub));\r\n }\r\n\r\n return stubs;\r\n }\r\n\r\n public get id(): string {\r\n return this.KI;\r\n }\r\n\r\n public get name(): string {\r\n return this.KN;\r\n }\r\n\r\n public get langId(): string {\r\n return this.KLC;\r\n }\r\n\r\n public get langName(): string {\r\n return this.KL;\r\n }\r\n\r\n public get displayName(): string {\r\n if(this._displayName) {\r\n return this._displayName;\r\n }\r\n\r\n // else, construct it.\r\n const kbdName = this.KN;\r\n const lgName = this.KL;\r\n\r\n switch (KeyboardProperties.spacebarTextMode) {\r\n case SpacebarText.KEYBOARD:\r\n return kbdName;\r\n case SpacebarText.LANGUAGE:\r\n return lgName;\r\n case SpacebarText.LANGUAGE_KEYBOARD:\r\n return (kbdName == lgName) ? lgName : lgName + ' - ' + kbdName;\r\n case SpacebarText.BLANK:\r\n return '';\r\n default:\r\n return kbdName;\r\n }\r\n }\r\n\r\n public set displayName(name: string) {\r\n this._displayName = name;\r\n }\r\n\r\n public get textFont() {\r\n return this.KFont;\r\n }\r\n\r\n public get oskFont() {\r\n return this.KOskFont;\r\n }\r\n\r\n /**\r\n * Generates an error for objects with specification levels insufficient for use in the on-screen-keyboard\r\n * module, complete with a message about one or more details in need of correction.\r\n * @returns A preconstructed `Error` instance that may be thrown by the caller.\r\n */\r\n public validateForOSK(): Error {\r\n if(!this.KLC) {\r\n if(this.KI || this.KN) {\r\n return new Error(`No language code was specified for use with the ${this.KI || this.KN} keyboard`);\r\n } else {\r\n return new Error(\"No language code was specified for use with the corresponding keyboard\")\r\n }\r\n }\r\n\r\n if(this.displayName === undefined || (KeyboardProperties.spacebarTextMode != SpacebarText.BLANK && !this.displayName)) {\r\n return new Error(\"A display name is missing for this keyboard and cannot be generated under current settings.\")\r\n }\r\n\r\n return null;\r\n }\r\n\r\n public validateForCustomKeyboard(): Error {\r\n if(!this.KI || !this.KN || !this.KL || !this.KLC) {\r\n return new Error(\"To use a custom keyboard, you must specify keyboard id, keyboard name, language and language code.\");\r\n } else {\r\n return null;\r\n }\r\n }\r\n}", + "// Defines the base Deadkey-tracking object.\r\nexport class Deadkey {\r\n p: number; // Position of deadkey\r\n d: number; // Numerical id of the deadkey\r\n o: number; // Ordinal value of the deadkey (resolves same-place conflicts)\r\n matched: number;\r\n\r\n static ordinalSeed: number = 0;\r\n\r\n constructor(pos: number, id: number) {\r\n this.p = pos;\r\n this.d = id;\r\n this.o = Deadkey.ordinalSeed++;\r\n }\r\n\r\n match(p: number, d: number): boolean {\r\n var result:boolean = (this.p == p && this.d == d);\r\n\r\n return result;\r\n }\r\n\r\n set(): void {\r\n this.matched = 1;\r\n }\r\n\r\n reset(): void {\r\n this.matched = 0;\r\n }\r\n\r\n before(other: Deadkey): boolean {\r\n return this.o < other.o;\r\n }\r\n\r\n clone(): Deadkey {\r\n let dk = new Deadkey(this.p, this.d);\r\n dk.o = this.o;\r\n\r\n return dk;\r\n }\r\n\r\n /**\r\n * Sorts the deadkeys in reverse order.\r\n */\r\n static sortFunc = function(a: Deadkey, b: Deadkey) {\r\n // We want descending order, so we want 'later' deadkeys first.\r\n if(a.p != b.p) {\r\n return b.p - a.p;\r\n } else {\r\n return b.o - a.o;\r\n }\r\n };\r\n}\r\n\r\n// Object-orients deadkey management.\r\nexport class DeadkeyTracker {\r\n dks: Deadkey[] = [];\r\n\r\n toSortedArray(): Deadkey[] {\r\n this.dks = this.dks.sort(Deadkey.sortFunc);\r\n return [].concat(this.dks);\r\n }\r\n\r\n clone(): DeadkeyTracker {\r\n let dkt = new DeadkeyTracker();\r\n let dks = this.toSortedArray();\r\n\r\n // Make sure to clone the deadkeys themselves - the Deadkey object is mutable.\r\n dkt.dks = [];\r\n dks.forEach(function(value: Deadkey) {\r\n dkt.dks.push(value.clone());\r\n });\r\n\r\n return dkt;\r\n }\r\n\r\n /**\r\n * Function isMatch\r\n * Scope Public\r\n * @param {number} caretPos current cursor position\r\n * @param {number} n expected offset of deadkey from cursor\r\n * @param {number} d deadkey\r\n * @return {boolean} True if deadkey found selected context matches val\r\n * Description Match deadkey at current cursor position\r\n */\r\n isMatch(caretPos: number, n: number, d: number): boolean {\r\n if(this.dks.length == 0) {\r\n return false; // I3318\r\n }\r\n\r\n var sp=caretPos;\r\n n = sp - n;\r\n for(var i = 0; i < this.dks.length; i++) {\r\n // Don't re-match an already-matched deadkey. It's possible to have two identical\r\n // entries, and they should be kept separately.\r\n if(this.dks[i].match(n, d) && !this.dks[i].matched) {\r\n this.dks[i].set();\r\n // Assumption: since we match the first possible entry in the array, we\r\n // match the entry with the lower ordinal - the 'first' deadkey in the position.\r\n return true; // I3318\r\n }\r\n }\r\n\r\n this.resetMatched(); // I3318\r\n\r\n return false;\r\n }\r\n\r\n add(dk: Deadkey) {\r\n this.dks = this.dks.concat(dk);\r\n }\r\n\r\n remove(dk: Deadkey) {\r\n var index = this.dks.indexOf(dk);\r\n this.dks.splice(index, 1);\r\n }\r\n\r\n clear() {\r\n this.dks = [];\r\n }\r\n\r\n resetMatched() {\r\n for(let dk of this.dks) {\r\n dk.reset();\r\n }\r\n }\r\n\r\n deleteMatched(): void {\r\n for(var Li = 0; Li < this.dks.length; Li++) {\r\n if(this.dks[Li].matched) {\r\n this.dks.splice(Li--, 1); // Don't forget to decrement!\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Function adjustPositions (formerly _DeadkeyAdjustPos)\r\n * Scope Private\r\n * @param {number} Lstart start position in context\r\n * @param {number} Ldelta characters to adjust by\r\n * Description Adjust saved positions of deadkeys in context\r\n */\r\n adjustPositions(Lstart: number, Ldelta: number): void {\r\n if(Ldelta == 0) {\r\n return;\r\n }\r\n\r\n for(let dk of this.dks) {\r\n if(dk.p > Lstart) {\r\n dk.p += Ldelta;\r\n }\r\n }\r\n }\r\n\r\n count(): number {\r\n return this.dks.length;\r\n }\r\n}", + "import type KeyboardInterface from \"./kbdInterface.js\";\r\nimport { SystemStoreIDs } from \"./kbdInterface.js\";\r\n\r\n/**\r\n * Defines common behaviors associated with system stores.\r\n */\r\nexport abstract class SystemStore {\r\n public readonly id: number;\r\n\r\n constructor(id: number) {\r\n this.id = id;\r\n }\r\n\r\n abstract matches(value: string): boolean;\r\n\r\n set(value: string): void {\r\n throw new Error(\"System store with ID \" + this.id + \" may not be directly set.\");\r\n }\r\n}\r\n\r\n/**\r\n * A handler designed to receive feedback whenever a system store's value is changed.\r\n * @param source The system store being mutated, before the value change occurs.\r\n * @param newValue The new value being set\r\n * @returns `false` / `undefined` to allow the change, `true` to block the change.\r\n */\r\nexport type SystemStoreMutationHandler = (source: MutableSystemStore, newValue: string) => boolean;\r\n\r\nexport class MutableSystemStore extends SystemStore {\r\n private _value: string;\r\n handler?: SystemStoreMutationHandler = null;\r\n\r\n constructor(id: number, defaultValue: string) {\r\n super(id);\r\n this._value = defaultValue;\r\n }\r\n\r\n get value() {\r\n return this._value;\r\n }\r\n\r\n matches(value: string) {\r\n return this._value == value;\r\n }\r\n\r\n set(value: string) {\r\n // Even if things stay the same, we should still signal this.\r\n // It's important for tracking if a rule directly set the layer\r\n // versus if it passively remained.\r\n if(this.handler) {\r\n if(this.handler(this, value)) {\r\n return;\r\n }\r\n }\r\n\r\n this._value = value;\r\n }\r\n}\r\n\r\n/**\r\n * Handles checks against the current platform.\r\n */\r\nexport class PlatformSystemStore extends SystemStore {\r\n private readonly kbdInterface: KeyboardInterface;\r\n\r\n constructor(keyboardInterface: KeyboardInterface) {\r\n super(SystemStoreIDs.TSS_PLATFORM);\r\n\r\n this.kbdInterface = keyboardInterface;\r\n }\r\n\r\n matches(value: string) {\r\n var i,constraint,constraints=value.split(' ');\r\n let device = this.kbdInterface.activeDevice;\r\n\r\n for(i=0; i\r\n\r\nimport { extendString } from \"@keymanapp/web-utils\";\r\n\r\nextendString();\r\n\r\n// Defines deadkey management in a manner attachable to each element interface.\r\nimport type KeyEvent from \"./keyEvent.js\";\r\nimport { Deadkey, DeadkeyTracker } from \"./deadkeys.js\";\r\n\r\n// Also relies on string-extensions provided by the web-utils package.\r\n\r\nexport function isEmptyTransform(transform: Transform) {\r\n if(!transform) {\r\n return false;\r\n }\r\n return transform.insert === '' && transform.deleteLeft === 0 && (transform.deleteRight ?? 0) === 0;\r\n}\r\n\r\nexport class TextTransform implements Transform {\r\n readonly insert: string;\r\n readonly deleteLeft: number;\r\n readonly deleteRight?: number;\r\n\r\n constructor(insert: string, deleteLeft: number, deleteRight?: number) {\r\n this.insert = insert;\r\n this.deleteLeft = deleteLeft;\r\n this.deleteRight = deleteRight || 0;\r\n }\r\n\r\n public static readonly nil = new TextTransform('', 0, 0);\r\n}\r\n\r\nexport class Transcription {\r\n readonly token: number;\r\n readonly keystroke: KeyEvent;\r\n readonly transform: Transform;\r\n alternates: Alternate[]; // constructed after the rest of the transcription.\r\n readonly preInput: Mock;\r\n\r\n private static tokenSeed: number = 0;\r\n\r\n constructor(keystroke: KeyEvent, transform: Transform, preInput: Mock, alternates?: Alternate[]/*, removedDks: Deadkey[], insertedDks: Deadkey[]*/) {\r\n let token = this.token = Transcription.tokenSeed++;\r\n\r\n this.keystroke = keystroke;\r\n this.transform = transform;\r\n this.alternates = alternates;\r\n this.preInput = preInput;\r\n\r\n this.transform.id = this.token;\r\n\r\n // Assign the ID to each alternate, as well.\r\n if(alternates) {\r\n alternates.forEach(function(alt) {\r\n alt.sample.id = token;\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport type Alternate = ProbabilityMass;\r\n\r\nexport default abstract class OutputTarget {\r\n private _dks: DeadkeyTracker;\r\n\r\n constructor() {\r\n this._dks = new DeadkeyTracker();\r\n }\r\n\r\n /**\r\n * Signifies that this OutputTarget has no default key processing behaviors. This should be false\r\n * for OutputTargets backed by web elements like HTMLInputElement or HTMLTextAreaElement.\r\n */\r\n get isSynthetic(): boolean {\r\n return true;\r\n }\r\n\r\n resetContext(): void {\r\n this.deadkeys().clear();\r\n }\r\n\r\n deadkeys(): DeadkeyTracker {\r\n return this._dks;\r\n }\r\n\r\n hasDeadkeyMatch(n: number, d: number): boolean {\r\n return this.deadkeys().isMatch(this.getDeadkeyCaret(), n, d);\r\n }\r\n\r\n insertDeadkeyBeforeCaret(d: number) {\r\n var dk: Deadkey = new Deadkey(this.getDeadkeyCaret(), d);\r\n this.deadkeys().add(dk);\r\n }\r\n\r\n /**\r\n * Should be called by each output target immediately before text mutation operations occur.\r\n *\r\n * Maintains solutions to old issues: I3318,I3319\r\n * @param {number} delta Use negative values if characters were deleted, positive if characters were added.\r\n */\r\n protected adjustDeadkeys(delta: number) {\r\n this.deadkeys().adjustPositions(this.getDeadkeyCaret(), delta);\r\n }\r\n\r\n /**\r\n * Needed to properly clone deadkeys for use with Mock element interfaces toward predictive text purposes.\r\n * @param {object} dks An existing set of deadkeys to deep-copy for use by this element interface.\r\n */\r\n protected setDeadkeys(dks: DeadkeyTracker) {\r\n this._dks = dks.clone();\r\n }\r\n\r\n /**\r\n * Determines the basic operations needed to reconstruct the current OutputTarget's text from the prior state specified\r\n * by another OutputTarget based on their text and caret positions.\r\n *\r\n * This is designed for use as a \"before and after\" comparison to determine the effect of a single keyboard rule at a time.\r\n * As such, it assumes that the caret is immediately after any inserted text.\r\n * @param from An output target (preferably a Mock) representing the prior state of the input/output system.\r\n */\r\n buildTransformFrom(original: OutputTarget): Transform {\r\n let to = this.getText();\r\n let from = original.getText();\r\n\r\n let fromCaret = original.getDeadkeyCaret();\r\n let toCaret = this.getDeadkeyCaret();\r\n\r\n // Step 1: Determine the number of left-deletions.\r\n let maxSMPLeftMatch = fromCaret < toCaret ? fromCaret : toCaret;\r\n\r\n // We need the corresponding non-SMP caret location in order to binary-search efficiently.\r\n // (Examining code units is much more computationally efficient.)\r\n let maxLeftMatch = to._kmwCodePointToCodeUnit(maxSMPLeftMatch);\r\n\r\n // 1.1: use a non-SMP-aware binary search to determine the divergence point.\r\n let start = 0;\r\n let end = maxLeftMatch; // the index AFTER the last possible matching char.\r\n\r\n // This search is O(maxLeftMatch). 1/2 + 1/4 + 1/8 + ... converges to = 1.\r\n while(start < end) {\r\n let mid = Math.floor((end+start+1) / 2); // round up (compare more)\r\n let fromLeft = from.substr(start, mid-start);\r\n let toLeft = to.substr(start, mid-start);\r\n\r\n if(fromLeft == toLeft) {\r\n start = mid;\r\n } else {\r\n end = mid - 1;\r\n }\r\n }\r\n\r\n // At the loop's end: `end` now holds the non-SMP-aware divergence point.\r\n // The 'caret' is after the last matching code unit.\r\n\r\n // 1.2: detect a possible surrogate-pair split scenario, correcting for it\r\n // (by moving the split before the high-surrogate) if detected.\r\n\r\n // If the split location is precisely on either end of the context, we can't\r\n // have split a surrogate pair.\r\n if(end > 0 && end < maxLeftMatch) {\r\n let potentialHigh = from.charCodeAt(end-1);\r\n let potentialFromLow = from.charCodeAt(end);\r\n let potentialToLow = to.charCodeAt(end);\r\n\r\n // if potentialHigh is a possible high surrogate...\r\n if(potentialHigh >= 0xD800 && potentialHigh <= 0xDBFF) {\r\n // and at least one potential 'low' is a possible low surrogate...\r\n let flag = potentialFromLow >= 0xDC00 && potentialFromLow <= 0xDFFF;\r\n flag = flag || (potentialToLow >= 0XDC00 && potentialToLow <= 0xDFFF);\r\n\r\n // Correct the split location, moving it 'before' the high surrogate.\r\n if(flag) {\r\n end = end - 1;\r\n }\r\n }\r\n }\r\n\r\n // 1.3: take substring from start to the split point; determine SMP-aware length.\r\n // This yields the SMP-aware divergence index, which gives the number of left-deletes.\r\n let newCaret = from._kmwCodeUnitToCodePoint(end);\r\n let deletedLeft = fromCaret - newCaret;\r\n\r\n // Step 2: Determine the other properties.\r\n // Since the 'after' OutputTarget's caret indicates the end of any inserted text, we\r\n // can easily calculate the rest.\r\n let insertedLength = toCaret - newCaret;\r\n let delta = to._kmwSubstr(newCaret, insertedLength);\r\n\r\n let undeletedRight = to._kmwLength() - toCaret;\r\n let originalRight = from._kmwLength() - fromCaret;\r\n let deletedRight = originalRight - undeletedRight;\r\n\r\n // May occur when reverting a suggestion that had been applied mid-word.\r\n if(deletedRight < 0) {\r\n // Restores deleteRight characters.\r\n delta = delta + to._kmwSubstr(toCaret, -deletedRight);\r\n deletedRight = 0;\r\n }\r\n\r\n return new TextTransform(delta, deletedLeft, deletedRight);\r\n }\r\n\r\n buildTranscriptionFrom(original: OutputTarget, keyEvent: KeyEvent, readonly: boolean, alternates?: Alternate[]): Transcription {\r\n let transform = this.buildTransformFrom(original);\r\n\r\n // If we ever decide to re-add deadkey tracking, this is the place for it.\r\n\r\n return new Transcription(keyEvent, transform, Mock.from(original, readonly), alternates);\r\n }\r\n\r\n /**\r\n * Restores the `OutputTarget` to the indicated state. Designed for use with `Transcription.preInput`.\r\n * @param original An `OutputTarget` (usually a `Mock`).\r\n */\r\n restoreTo(original: OutputTarget) {\r\n //\r\n this.setTextBeforeCaret(original.getTextBeforeCaret());\r\n this.setTextAfterCaret(original.getTextAfterCaret());\r\n\r\n // Also, restore the deadkeys!\r\n this._dks = original._dks.clone();\r\n }\r\n\r\n apply(transform: Transform) {\r\n if(transform.deleteRight) {\r\n this.setTextAfterCaret(this.getTextAfterCaret()._kmwSubstr(transform.deleteRight));\r\n }\r\n\r\n if(transform.deleteLeft) {\r\n this.deleteCharsBeforeCaret(transform.deleteLeft);\r\n }\r\n\r\n if(transform.insert) {\r\n this.insertTextBeforeCaret(transform.insert);\r\n }\r\n\r\n // We assume that all deadkeys are invalidated after applying a Transform, since\r\n // prediction implies we'll be completing a word, post-deadkeys.\r\n this._dks.clear();\r\n }\r\n\r\n /**\r\n * Helper to `restoreTo` - allows directly setting the 'before' context to that of another\r\n * `OutputTarget`.\r\n * @param s\r\n */\r\n protected setTextBeforeCaret(s: string): void {\r\n // This one's easy enough to provide a default implementation for.\r\n this.deleteCharsBeforeCaret(this.getTextBeforeCaret()._kmwLength());\r\n this.insertTextBeforeCaret(s);\r\n }\r\n\r\n /**\r\n * Helper to `restoreTo` - allows directly setting the 'after' context to that of another\r\n * `OutputTarget`.\r\n * @param s\r\n */\r\n protected abstract setTextAfterCaret(s: string): void;\r\n\r\n /**\r\n * Clears any selected text within the wrapper's element(s).\r\n * Silently does nothing if no such text exists.\r\n */\r\n abstract clearSelection(): void;\r\n\r\n /**\r\n * Clears any cached selection-related state values.\r\n */\r\n abstract invalidateSelection(): void;\r\n\r\n /**\r\n * Indicates whether or not the underlying element has its own selection (input, textarea)\r\n * or is part of (or possesses) the DOM's active selection. Don't confuse with isSelectionEmpty().\r\n *\r\n * TODO: rename to supportsOwnSelection\r\n */\r\n abstract hasSelection(): boolean;\r\n\r\n /**\r\n * Returns true if there is no current selection -- that is, the selection range is empty\r\n */\r\n abstract isSelectionEmpty(): boolean;\r\n\r\n /**\r\n * Returns an index corresponding to the caret's position for use with deadkeys.\r\n */\r\n abstract getDeadkeyCaret(): number;\r\n\r\n /**\r\n * Relative to the caret, gets the current context within the wrapper's element.\r\n */\r\n abstract getTextBeforeCaret(): string;\r\n\r\n /**\r\n * Gets the element's-currently selected text.\r\n */\r\n abstract getSelectedText(): string;\r\n\r\n /**\r\n * Relative to the caret (and/or active selection), gets the element's text after the caret,\r\n * excluding any actively selected text that would be immediately replaced upon text entry.\r\n */\r\n abstract getTextAfterCaret(): string;\r\n\r\n /**\r\n * Gets the element's full text, including any text that is actively selected.\r\n */\r\n abstract getText(): string;\r\n\r\n /**\r\n * Performs context deletions (from the left of the caret) as needed by the KeymanWeb engine and\r\n * corrects the location of any affected deadkeys.\r\n *\r\n * Does not delete deadkeys (b/c KMW 1 & 2 behavior maintenance).\r\n * @param dn The number of characters to delete. If negative, context will be left unchanged.\r\n */\r\n abstract deleteCharsBeforeCaret(dn: number): void;\r\n\r\n /**\r\n * Inserts text immediately before the caret's current position, moving the caret after the\r\n * newly inserted text in the process along with any affected deadkeys.\r\n *\r\n * @param s Text to insert before the caret's current position.\r\n */\r\n abstract insertTextBeforeCaret(s: string): void;\r\n\r\n /**\r\n * Allows element-specific handling for ENTER key inputs. Conceptually, this should usually\r\n * correspond to `insertTextBeforeCaret('\\n'), but actual implementation will vary greatly among\r\n * elements.\r\n */\r\n abstract handleNewlineAtCaret(): void;\r\n\r\n /**\r\n * Saves element-specific state properties prone to mutation, enabling restoration after\r\n * text-output operations.\r\n */\r\n saveProperties() {\r\n // Most element interfaces won't need anything here.\r\n }\r\n\r\n /**\r\n * Restores previously-saved element-specific state properties. Designed for use after text-output\r\n * ops to facilitate more-seamless web-dev and user interactions.\r\n */\r\n restoreProperties(){\r\n // Most element interfaces won't need anything here.\r\n }\r\n\r\n /**\r\n * Generates a synthetic event on the underlying element, signalling that its value has changed.\r\n */\r\n abstract doInputEvent(): void;\r\n}\r\n\r\n// Due to some interesting requirements on compile ordering in TS,\r\n// this needs to be in the same file as OutputTarget now.\r\nexport class Mock extends OutputTarget {\r\n text: string;\r\n\r\n selStart: number;\r\n selEnd: number;\r\n selForward: boolean = true;\r\n\r\n constructor(text?: string, caretPos?: number);\r\n constructor(text?: string, selStart?: number, selEnd?: number);\r\n constructor(text?: string, selStart?: number, selEnd?: number) {\r\n super();\r\n\r\n this.text = text ? text : \"\";\r\n var defaultLength = this.text._kmwLength();\r\n\r\n // Ensures that `caretPos == 0` is handled correctly.\r\n this.selStart = typeof selStart == \"number\" ? selStart : defaultLength;\r\n\r\n // If no selection-end is set, selection length is implied to be 0.\r\n this.selEnd = typeof selEnd == \"number\" ? selEnd : this.selStart;\r\n\r\n this.selForward = this.selEnd >= this.selStart;\r\n }\r\n\r\n // Clones the state of an existing EditableElement, creating a Mock version of its state.\r\n static from(outputTarget: OutputTarget, readonly?: boolean) {\r\n let clone: Mock;\r\n\r\n if(outputTarget instanceof Mock) {\r\n // Avoids the need to run expensive kmwstring.ts / `_kmwLength()`\r\n // calculations when deep-copying Mock instances.\r\n let priorMock = outputTarget as Mock;\r\n clone = new Mock(priorMock.text, priorMock.selStart, priorMock.selEnd);\r\n } else {\r\n const text = outputTarget.getText();\r\n const textLen = text._kmwLength();\r\n\r\n // If !hasSelection()\r\n let selectionStart: number = textLen;\r\n let selectionEnd: number = 0;\r\n\r\n if(outputTarget.hasSelection()) {\r\n let beforeText = outputTarget.getTextBeforeCaret();\r\n let afterText = outputTarget.getTextAfterCaret();\r\n selectionStart = beforeText._kmwLength();\r\n selectionEnd = textLen - afterText._kmwLength();\r\n }\r\n\r\n // readonly group or not, the returned Mock remains the same.\r\n // New-context events should act as if the caret were at the earlier-in-context\r\n // side of the selection, same as standard keyboard rules.\r\n clone = new Mock(text, selectionStart, selectionEnd);\r\n }\r\n\r\n // Also duplicate deadkey state! (Needed for fat-finger ops.)\r\n clone.setDeadkeys(outputTarget.deadkeys());\r\n\r\n return clone;\r\n }\r\n\r\n clearSelection(): void {\r\n this.text = this.getTextBeforeCaret() + this.getTextAfterCaret();\r\n this.selEnd = this.selStart;\r\n this.selForward = true;\r\n }\r\n\r\n invalidateSelection(): void {\r\n return;\r\n }\r\n\r\n isSelectionEmpty(): boolean {\r\n return this.selStart == this.selEnd;\r\n }\r\n\r\n hasSelection(): boolean {\r\n return true;\r\n }\r\n\r\n getDeadkeyCaret(): number {\r\n return this.selStart;\r\n }\r\n\r\n setSelection(start: number, end?: number) {\r\n this.selStart = start;\r\n this.selEnd = typeof end == 'number' ? end : start;\r\n\r\n this.selForward = end >= start;\r\n if(!this.selForward) {\r\n let temp = this.selStart;\r\n this.selStart = this.selEnd;\r\n this.selEnd = temp;\r\n }\r\n }\r\n\r\n getTextBeforeCaret(): string {\r\n return this.text.kmwSubstr(0, this.selStart);\r\n }\r\n\r\n getSelectedText(): string {\r\n return this.text.kmwSubstr(this.selStart, this.selEnd - this.selStart);\r\n }\r\n\r\n getTextAfterCaret(): string {\r\n return this.text.kmwSubstr(this.selEnd);\r\n }\r\n\r\n getText(): string {\r\n return this.text;\r\n }\r\n\r\n deleteCharsBeforeCaret(dn: number): void {\r\n if(dn >= 0) {\r\n if(dn > this.selStart) {\r\n dn = this.selStart;\r\n }\r\n this.adjustDeadkeys(-dn);\r\n this.text = this.text.kmwSubstr(0, this.selStart - dn) + this.text.kmwSubstr(this.selStart);\r\n this.selStart -= dn;\r\n this.selEnd -= dn;\r\n }\r\n }\r\n\r\n insertTextBeforeCaret(s: string): void {\r\n this.adjustDeadkeys(s._kmwLength());\r\n this.text = this.getTextBeforeCaret() + s + this.text.kmwSubstr(this.selStart);\r\n this.selStart += s.kmwLength();\r\n this.selEnd += s.kmwLength();\r\n }\r\n\r\n handleNewlineAtCaret(): void {\r\n this.insertTextBeforeCaret('\\n');\r\n }\r\n\r\n protected setTextAfterCaret(s: string): void {\r\n this.text = this.getTextBeforeCaret() + s;\r\n }\r\n\r\n doInputEvent() {\r\n // Mock isn't backed by an element, so it won't have any event listeners.\r\n }\r\n}", + "///\r\n\r\nimport KeyboardProcessor from \"./keyboardProcessor.js\";\r\nimport OutputTarget, { Mock, type Transcription } from \"./outputTarget.js\";\r\nimport { VariableStoreDictionary } from \"../keyboards/keyboard.js\";\r\nimport type { VariableStore } from \"./kbdInterface.js\";\r\n\r\n/**\r\n * Represents the commands and state changes that result from a matched keyboard rule.\r\n */\r\nexport default class RuleBehavior {\r\n /**\r\n * The before-and-after Transform from matching a keyboard rule. May be `null`\r\n * if no keyboard rules were matched for the keystroke.\r\n */\r\n transcription: Transcription = null;\r\n\r\n /**\r\n * Indicates whether or not a BEEP command was issued by the matched keyboard rule.\r\n */\r\n beep?: boolean;\r\n\r\n /**\r\n * A set of changed store values triggered by the matched keyboard rule.\r\n */\r\n setStore: {[id: number]: string} = {};\r\n\r\n /**\r\n * A set of variable stores with save requests triggered by the matched keyboard rule\r\n */\r\n saveStore: {[name: string]: VariableStore} = {};\r\n\r\n /**\r\n * A set of variable stores with possible changes to be applied during finalization.\r\n */\r\n variableStores: VariableStoreDictionary = {};\r\n\r\n /**\r\n * Denotes a non-output default behavior; this should be evaluated later, against the true keystroke.\r\n */\r\n triggersDefaultCommand: boolean = false;\r\n\r\n /**\r\n * Denotes error log messages generated when attempting to generate this behavior.\r\n */\r\n errorLog?: string;\r\n\r\n /**\r\n * Denotes warning log messages generated when attempting to generate this behavior.\r\n */\r\n warningLog?: string;\r\n\r\n /**\r\n * If predictive text is active, contains a Promise returning predictive Suggestions.\r\n */\r\n predictionPromise?: Promise;\r\n\r\n /**\r\n * In reference to https://github.com/keymanapp/keyman/pull/4350#issuecomment-768753852:\r\n *\r\n * If the final group processed is a context and keystroke group (using keys),\r\n * and there is no nomatch rule, and the keystroke is not matched in the group,\r\n * the keystroke's default behavior should trigger, regardless of whether or not any\r\n * rules in prior groups matched.\r\n */\r\n triggerKeyDefault?: boolean;\r\n\r\n finalize(processor: KeyboardProcessor, outputTarget: OutputTarget, readonly: boolean) {\r\n if(!this.transcription) {\r\n throw \"Cannot finalize a RuleBehavior with no transcription.\";\r\n }\r\n\r\n if(processor.beepHandler && this.beep) {\r\n processor.beepHandler(outputTarget);\r\n }\r\n\r\n for(let storeID in this.setStore) {\r\n let sysStore = processor.keyboardInterface.systemStores[storeID];\r\n if(sysStore) {\r\n try {\r\n sysStore.set(this.setStore[storeID]);\r\n } catch (error) {\r\n if(processor.errorLogger) {\r\n processor.errorLogger(\"Rule attempted to perform illegal operation - 'platform' may not be changed.\");\r\n }\r\n }\r\n } else if(processor.warningLogger) {\r\n processor.warningLogger(\"Unknown store affected by keyboard rule: \" + storeID);\r\n }\r\n }\r\n\r\n processor.keyboardInterface.applyVariableStores(this.variableStores);\r\n\r\n if(processor.keyboardInterface.variableStoreSerializer) {\r\n for(let storeID in this.saveStore) {\r\n processor.keyboardInterface.variableStoreSerializer.saveStore(processor.activeKeyboard.id, storeID, this.saveStore[storeID]);\r\n }\r\n }\r\n\r\n if(this.triggersDefaultCommand) {\r\n let keyEvent = this.transcription.keystroke;\r\n processor.defaultRules.applyCommand(keyEvent, outputTarget);\r\n }\r\n\r\n if(processor.warningLogger && this.warningLog) {\r\n processor.warningLogger(this.warningLog);\r\n } else if(processor.errorLogger && this.errorLog) {\r\n processor.errorLogger(this.errorLog);\r\n }\r\n }\r\n\r\n /**\r\n * Merges default-related behaviors from another RuleBehavior into this one. Assumes that the current instance\r\n * \"came first\" chronologically. Both RuleBehaviors must be sourced from the same keystroke.\r\n *\r\n * Intended use: merging rule-based behavior with default key behavior during scenarios like those described\r\n * at https://github.com/keymanapp/keyman/pull/4350#issuecomment-768753852.\r\n *\r\n * This function does not attempt a \"complete\" merge for two fully-constructed RuleBehaviors! Things\r\n * WILL break for unintended uses.\r\n * @param other\r\n */\r\n mergeInDefaults(other: RuleBehavior) {\r\n let keystroke = this.transcription.keystroke;\r\n let keyFromOther = other.transcription.keystroke;\r\n if(keystroke.Lcode != keyFromOther.Lcode || keystroke.Lmodifiers != keyFromOther.Lmodifiers) {\r\n throw \"RuleBehavior default-merge not supported unless keystrokes are identical!\";\r\n }\r\n\r\n this.triggersDefaultCommand = this.triggersDefaultCommand || other.triggersDefaultCommand;\r\n\r\n let mergingMock = Mock.from(this.transcription.preInput, false);\r\n mergingMock.apply(this.transcription.transform);\r\n mergingMock.apply(other.transcription.transform);\r\n\r\n this.transcription = mergingMock.buildTranscriptionFrom(this.transcription.preInput, keystroke, false, this.transcription.alternates);\r\n }\r\n}", + "/***\r\n KeymanWeb 11.0\r\n Copyright 2019 SIL International\r\n***/\r\n\r\n//#region Imports\r\n\r\nimport { type DeviceSpec } from \"@keymanapp/web-utils\";\r\n\r\nimport Codes from \"./codes.js\";\r\nimport type KeyEvent from \"./keyEvent.js\";\r\nimport type { Deadkey } from \"./deadkeys.js\";\r\nimport KeyMapping from \"./keyMapping.js\";\r\nimport { SystemStore, MutableSystemStore, PlatformSystemStore } from \"./systemStores.js\";\r\nimport type { VariableStoreSerializer } from \"./keyboardProcessor.js\";\r\nimport type OutputTarget from \"./outputTarget.js\";\r\nimport { Mock } from \"./outputTarget.js\";\r\nimport RuleBehavior from \"./ruleBehavior.js\";\r\nimport Keyboard, { VariableStoreDictionary } from \"../keyboards/keyboard.js\";\r\nimport { KeyboardHarness, KeyboardKeymanGlobal } from \"../keyboards/keyboardHarness.js\";\r\n\r\n//#endregion\r\n\r\n//#region Helper type definitions\r\n\r\nexport class KeyInformation {\r\n vk: boolean;\r\n code: number;\r\n modifiers: number;\r\n}\r\n\r\n/*\r\n* Type alias definitions to reflect the parameters of the fullContextMatch() callback (KMW 10+).\r\n* No constructors or methods since keyboards will not utilize the same backing prototype, and\r\n* property names are shorthanded to promote minification.\r\n*/\r\ntype PlainKeyboardStore = string;\r\n\r\nexport type KeyboardStoreElement = (string|StoreNonCharEntry);\r\nexport type ComplexKeyboardStore = KeyboardStoreElement[];\r\n\r\ntype KeyboardStore = PlainKeyboardStore | ComplexKeyboardStore;\r\n\r\nexport type VariableStore = {[name: string]: string};\r\n\r\ntype RuleChar = string;\r\n\r\nclass RuleDeadkey {\r\n /** Discriminant field - 'd' for Deadkey.\r\n */\r\n ['t']: 'd';\r\n\r\n /**\r\n * Value: the deadkey's ID.\r\n */\r\n ['d']: number; // For 'd'eadkey; also reflects the Deadkey class's 'd' property.\r\n}\r\n\r\nclass ContextAny {\r\n /** Discriminant field - 'a' for `any()`.\r\n */\r\n ['t']: 'a';\r\n\r\n /**\r\n * Value: the store to search.\r\n */\r\n ['a']: KeyboardStore; // For 'a'ny statement.\r\n\r\n /**\r\n * If set to true, negates the 'any'.\r\n */\r\n ['n']: boolean|0|1;\r\n}\r\n\r\nclass RuleIndex {\r\n /** Discriminant field - 'i' for `index()`.\r\n */\r\n ['t']: 'i';\r\n\r\n /**\r\n * Value: the Store from which to output\r\n */\r\n ['i']: KeyboardStore;\r\n\r\n /**\r\n * Offset: the offset in context for the corresponding `any()`.\r\n */\r\n ['o']: number;\r\n}\r\n\r\nclass ContextEx {\r\n /** Discriminant field - 'c' for `context()`.\r\n */\r\n ['t']: 'c';\r\n\r\n /**\r\n * Value: The offset into the current rule's context to be matched.\r\n */\r\n ['c']: number; // For 'c'ontext statement.\r\n}\r\n\r\nclass ContextNul {\r\n /** Discriminant field - 'n' for `nul`\r\n */\r\n ['t']: 'n';\r\n}\r\n\r\nclass StoreBeep {\r\n /** Discriminant field - 'b' for `beep`\r\n */\r\n ['t']: 'b';\r\n}\r\n\r\ntype ContextNonCharEntry = RuleDeadkey | ContextAny | RuleIndex | ContextEx | ContextNul;\r\ntype ContextEntry = RuleChar | ContextNonCharEntry;\r\n\r\ntype StoreNonCharEntry = RuleDeadkey | StoreBeep;\r\n\r\n/**\r\n * Cache of context storing and retrieving return values from KC\r\n * Must be reset prior to each keystroke and after any text changes\r\n * MCD 3/1/14\r\n **/\r\nclass CachedContext {\r\n _cache: string[][];\r\n\r\n reset(): void {\r\n this._cache = [];\r\n }\r\n\r\n get(n: number, ln: number): string {\r\n // return null; // uncomment this line to disable context caching\r\n if(typeof this._cache[n] == 'undefined') {\r\n return null;\r\n } else if(typeof this._cache[n][ln] == 'undefined') {\r\n return null;\r\n }\r\n return this._cache[n][ln];\r\n }\r\n\r\n set(n: number, ln: number, val: string): void {\r\n if(typeof this._cache[n] == 'undefined') {\r\n this._cache[n] = [];\r\n }\r\n this._cache[n][ln] = val;\r\n }\r\n};\r\n\r\ntype CachedExEntry = {valContext: (string|number)[], deadContext: Deadkey[]};\r\n/**\r\n * An extended version of cached context storing designed to work with\r\n * `fullContextMatch` and its helper functions.\r\n */\r\nclass CachedContextEx {\r\n _cache: CachedExEntry[][];\r\n\r\n reset(): void {\r\n this._cache = [];\r\n }\r\n\r\n get(n: number, ln: number): CachedExEntry {\r\n // return null; // uncomment this line to disable context caching\r\n if(typeof this._cache[n] == 'undefined') {\r\n return null;\r\n } else if(typeof this._cache[n][ln] == 'undefined') {\r\n return null;\r\n }\r\n return this._cache[n][ln];\r\n }\r\n\r\n set(n: number, ln: number, val: CachedExEntry): void {\r\n if(typeof this._cache[n] == 'undefined') {\r\n this._cache[n] = [];\r\n }\r\n this._cache[n][ln] = val;\r\n }\r\n\r\n clone(): CachedContextEx {\r\n let r = new CachedContextEx();\r\n r._cache = this._cache;\r\n return r;\r\n }\r\n};\r\n\r\nexport enum SystemStoreIDs {\r\n TSS_LAYER = 33,\r\n TSS_PLATFORM = 31,\r\n TSS_NEWLAYER = 42,\r\n TSS_OLDLAYER = 43\r\n}\r\n\r\n//#endregion\r\n\r\nexport default class KeyboardInterface extends KeyboardHarness {\r\n static readonly GLOBAL_NAME = 'KeymanWeb';\r\n\r\n cachedContext: CachedContext = new CachedContext();\r\n cachedContextEx: CachedContextEx = new CachedContextEx();\r\n ruleContextEx: CachedContextEx;\r\n\r\n activeTargetOutput: OutputTarget;\r\n ruleBehavior: RuleBehavior;\r\n\r\n systemStores: {[storeID: number]: SystemStore};\r\n\r\n _AnyIndices: number[] = []; // AnyIndex - array of any/index match indices\r\n\r\n // Must be accessible to some of the keyboard API methods.\r\n activeKeyboard: Keyboard;\r\n activeDevice: DeviceSpec;\r\n\r\n variableStoreSerializer?: VariableStoreSerializer;\r\n\r\n // A 'reference point' that debug keyboards may use to access KMW's code constants.\r\n public get Codes(): typeof Codes {\r\n return Codes;\r\n }\r\n\r\n constructor(_jsGlobal: any, keymanGlobal: KeyboardKeymanGlobal, variableStoreSerializer: VariableStoreSerializer = null) {\r\n super(_jsGlobal, keymanGlobal);\r\n\r\n this.systemStores = {};\r\n\r\n this.systemStores[SystemStoreIDs.TSS_PLATFORM] = new PlatformSystemStore(this);\r\n this.systemStores[SystemStoreIDs.TSS_LAYER] = new MutableSystemStore(SystemStoreIDs.TSS_LAYER, 'default');\r\n this.systemStores[SystemStoreIDs.TSS_NEWLAYER] = new MutableSystemStore(SystemStoreIDs.TSS_NEWLAYER, '');\r\n this.systemStores[SystemStoreIDs.TSS_OLDLAYER] = new MutableSystemStore(SystemStoreIDs.TSS_OLDLAYER, '');\r\n\r\n this.variableStoreSerializer = variableStoreSerializer;\r\n }\r\n\r\n /**\r\n * Function KSF\r\n * Scope Public\r\n *\r\n * Saves the document's current focus settings on behalf of the keyboard. Often paired with insertText.\r\n */\r\n saveFocus(): void { }\r\n\r\n /**\r\n * A text-insertion method used by custom OSKs for helpHTML interaction, like with sil_euro_latin.\r\n *\r\n * This function currently bypasses web-core's standard text handling control path and all predictive text processing.\r\n * It also has DOM-dependencies that help ensure KMW's active OutputTarget retains focus during use.\r\n */\r\n insertText?: (Ptext: string, PdeadKey: number) => void;\r\n\r\n /**\r\n * Function registerKeyboard KR\r\n * Scope Public\r\n * @param {Object} Pk Keyboard object\r\n * Description Registers a keyboard with KeymanWeb once its script has fully loaded.\r\n *\r\n * In web-core, this also activates the keyboard; in other modules, this method\r\n * may be replaced with other implementations.\r\n */\r\n registerKeyboard(Pk): void {\r\n // NOTE: This implementation is web-core specific and is intentionally replaced, whole-sale,\r\n // by DOM-aware code.\r\n let keyboard = new Keyboard(Pk);\r\n this.loadedKeyboard = keyboard;\r\n }\r\n\r\n /**\r\n * Get *cached or uncached* keyboard context for a specified range, relative to caret\r\n *\r\n * @param {number} n Number of characters to move back from caret\r\n * @param {number} ln Number of characters to return\r\n * @param {Object} Pelem Element to work with (must be currently focused element)\r\n * @return {string} Context string\r\n *\r\n * Example [abcdef|ghi] as INPUT, with the caret position marked by |:\r\n * KC(2,1,Pelem) == \"e\"\r\n * KC(3,3,Pelem) == \"def\"\r\n * KC(10,10,Pelem) == \"abcdef\" i.e. return as much as possible of the requested string\r\n */\r\n\r\n context(n: number, ln: number, outputTarget: OutputTarget): string {\r\n var v = this.cachedContext.get(n, ln);\r\n if(v !== null) {\r\n return v;\r\n }\r\n\r\n var r = this.KC_(n, ln, outputTarget);\r\n this.cachedContext.set(n, ln, r);\r\n return r;\r\n }\r\n\r\n /**\r\n * Get (uncached) keyboard context for a specified range, relative to caret\r\n *\r\n * @param {number} n Number of characters to move back from caret\r\n * @param {number} ln Number of characters to return\r\n * @param {Object} Pelem Element to work with (must be currently focused element)\r\n * @return {string} Context string\r\n *\r\n * Example [abcdef|ghi] as INPUT, with the caret position marked by |:\r\n * KC(2,1,Pelem) == \"e\"\r\n * KC(3,3,Pelem) == \"def\"\r\n * KC(10,10,Pelem) == \"XXXXabcdef\" i.e. return as much as possible of the requested string, where X = \\uFFFE\r\n */\r\n private KC_(n: number, ln: number, outputTarget: OutputTarget): string {\r\n var tempContext = '';\r\n\r\n // If we have a selection, we have an empty context\r\n tempContext = outputTarget.isSelectionEmpty() ? outputTarget.getTextBeforeCaret() : \"\";\r\n\r\n if(tempContext._kmwLength() < n) {\r\n tempContext = Array(n-tempContext._kmwLength()+1).join(\"\\uFFFE\") + tempContext;\r\n }\r\n\r\n return tempContext._kmwSubstr(-n)._kmwSubstr(0,ln);\r\n }\r\n\r\n /**\r\n * Function nul KN\r\n * Scope Public\r\n * @param {number} n Length of context to check\r\n * @param {Object} Ptarg Element to work with (must be currently focused element)\r\n * @return {boolean} True if length of context is less than or equal to n\r\n * Description Test length of context, return true if the length of the context is less than or equal to n\r\n *\r\n * Example [abc|def] as INPUT, with the caret position marked by |:\r\n * KN(3,Pelem) == TRUE\r\n * KN(2,Pelem) == FALSE\r\n * KN(4,Pelem) == TRUE\r\n */\r\n nul(n: number, outputTarget: OutputTarget): boolean {\r\n var cx=this.context(n+1, 1, outputTarget);\r\n\r\n // With #31, the result will be a replacement character if context is empty.\r\n return cx === \"\\uFFFE\";\r\n }\r\n\r\n /**\r\n * Function contextMatch KCM\r\n * Scope Public\r\n * @param {number} n Number of characters to move back from caret\r\n * @param {Object} Ptarg Focused element\r\n * @param {string} val String to match\r\n * @param {number} ln Number of characters to return\r\n * @return {boolean} True if selected context matches val\r\n * Description Test keyboard context for match\r\n */\r\n contextMatch(n: number, outputTarget: OutputTarget, val: string, ln: number): boolean {\r\n var cx=this.context(n, ln, outputTarget);\r\n if(cx === val) {\r\n return true; // I3318\r\n }\r\n outputTarget.deadkeys().resetMatched(); // I3318\r\n return false;\r\n }\r\n\r\n /**\r\n * Builds the *cached or uncached* keyboard context for a specified range, relative to caret\r\n *\r\n * @param {number} n Number of characters to move back from caret\r\n * @param {number} ln Number of characters to return\r\n * @param {Object} Pelem Element to work with (must be currently focused element)\r\n * @return {Array} Context array (of strings and numbers)\r\n */\r\n private _BuildExtendedContext(n: number, ln: number, outputTarget: OutputTarget): CachedExEntry {\r\n var cache: CachedExEntry = this.cachedContextEx.get(n, ln);\r\n if(cache !== null) {\r\n return cache;\r\n } else {\r\n // By far the easiest way to correctly build what we want is to start from the right and work to what we need.\r\n // We may have done it for a similar cursor position before.\r\n cache = this.cachedContextEx.get(n, n);\r\n if(cache === null) {\r\n // First, let's make sure we have a cloned, sorted copy of the deadkey array.\r\n let unmatchedDeadkeys = outputTarget.deadkeys().toSortedArray(); // Is reverse-order sorted for us already.\r\n\r\n // Time to build from scratch!\r\n var index = 0;\r\n cache = { valContext: [], deadContext: []};\r\n while(cache.valContext.length < n) {\r\n // As adapted from `deadkeyMatch`.\r\n var sp = outputTarget.getDeadkeyCaret();\r\n var deadPos = sp - index;\r\n if(unmatchedDeadkeys.length > 0 && unmatchedDeadkeys[0].p > deadPos) {\r\n // We have deadkeys at the right-hand side of the caret! They don't belong in the context, so pop 'em off.\r\n unmatchedDeadkeys.splice(0, 1);\r\n continue;\r\n } else if(unmatchedDeadkeys.length > 0 && unmatchedDeadkeys[0].p == deadPos) {\r\n // Take the deadkey.\r\n cache.deadContext[n-cache.valContext.length-1] = unmatchedDeadkeys[0];\r\n cache.valContext = ([unmatchedDeadkeys[0].d] as (string|number)[]).concat(cache.valContext);\r\n unmatchedDeadkeys.splice(0, 1);\r\n } else {\r\n // Take the character. We get \"\\ufffe\" if it doesn't exist.\r\n var kc = this.context(++index, 1, outputTarget);\r\n cache.valContext = ([kc] as (string|number)[]).concat(cache.valContext);\r\n }\r\n }\r\n this.cachedContextEx.set(n, n, cache);\r\n }\r\n\r\n // Now that we have the cache...\r\n var subCache = cache;\r\n subCache.valContext = subCache.valContext.slice(0, ln);\r\n for(var i=0; i < subCache.valContext.length; i++) {\r\n if(subCache[i] == '\\ufffe') {\r\n subCache.valContext.splice(0, 1);\r\n subCache.deadContext.splice(0, 1);\r\n }\r\n }\r\n\r\n if(subCache.valContext.length == 0) {\r\n subCache.valContext = ['\\ufffe'];\r\n subCache.deadContext = [];\r\n }\r\n\r\n this.cachedContextEx.set(n, ln, subCache);\r\n\r\n return subCache;\r\n }\r\n }\r\n\r\n /**\r\n * Function fullContextMatch KFCM\r\n * Scope Private\r\n * @param {number} n Number of characters to move back from caret\r\n * @param {Object} Ptarg Focused element\r\n * @param {Array} rule An array of ContextEntries to match.\r\n * @return {boolean} True if the fully-specified rule context matches the current KMW state.\r\n *\r\n * A KMW 10+ function designed to bring KMW closer to Keyman Desktop functionality,\r\n * near-directly modeling (externally) the compiled form of Desktop rules' context section.\r\n */\r\n fullContextMatch(n: number, outputTarget: OutputTarget, rule: ContextEntry[]): boolean {\r\n // Stage one: build the context index map.\r\n var fullContext = this._BuildExtendedContext(n, rule.length, outputTarget);\r\n this.ruleContextEx = this.cachedContextEx.clone();\r\n var context = fullContext.valContext;\r\n var deadContext = fullContext.deadContext;\r\n\r\n var mismatch = false;\r\n\r\n // This symbol internally indicates lack of context in a position. (See KC_)\r\n const NUL_CONTEXT = \"\\uFFFE\";\r\n\r\n var assertNever = function(x: never): never {\r\n // Could be accessed by improperly handwritten calls to `fullContextMatch`.\r\n throw new Error(\"Unexpected object in fullContextMatch specification: \" + x);\r\n }\r\n\r\n // Stage two: time to match against the rule specified.\r\n for(var i=0; i < rule.length; i++) {\r\n if(typeof rule[i] == 'string') {\r\n var str = rule[i] as string;\r\n if(str !== context[i]) {\r\n mismatch = true;\r\n break;\r\n }\r\n } else {\r\n // TypeScript needs a cast to this intermediate type to do its discriminated union magic.\r\n var r = rule[i] as ContextNonCharEntry;\r\n switch(r.t) {\r\n case 'd':\r\n // We still need to set a flag here;\r\n if(r['d'] !== context[i]) {\r\n mismatch = true;\r\n } else {\r\n deadContext[i].set();\r\n }\r\n break;\r\n case 'a':\r\n var lookup: KeyboardStoreElement;\r\n\r\n if(typeof context[i] == 'string') {\r\n lookup = context[i] as string;\r\n } else {\r\n lookup = {'t': 'd', 'd': context[i] as number};\r\n }\r\n\r\n var result = this.any(i, lookup, r.a);\r\n\r\n if(!r.n) { // If it's a standard 'any'...\r\n if(!result) {\r\n mismatch = true;\r\n } else if(deadContext[i] !== undefined) {\r\n // It's a deadkey match, so indicate that.\r\n deadContext[i].set();\r\n }\r\n // 'n' for 'notany'.\r\n // - if `result === true`, `any` would match: this should thus fail.\r\n // - if `context[i] === NUL_CONTEXT`, `notany` should not match.\r\n } else if(r.n && (result || context[i] === NUL_CONTEXT)) {\r\n mismatch = true;\r\n }\r\n break;\r\n case 'i':\r\n // The context will never hold a 'beep.'\r\n var ch = this._Index(r.i, r.o) as string | RuleDeadkey;\r\n\r\n if(ch !== undefined && (typeof(ch) == 'string' ? ch : ch.d) !== context[i]) {\r\n mismatch = true;\r\n } else if(deadContext[i] !== undefined) {\r\n deadContext[i].set();\r\n }\r\n break;\r\n case 'c':\r\n if(context[r.c - 1] !== context[i]) {\r\n mismatch = true;\r\n } else if(deadContext[i] !== undefined) {\r\n deadContext[i].set();\r\n }\r\n break;\r\n case 'n':\r\n // \\uFFFE is the internal 'no context here sentinel'.\r\n if(context[i] != NUL_CONTEXT) {\r\n mismatch = true;\r\n }\r\n break;\r\n default:\r\n assertNever(r);\r\n }\r\n }\r\n }\r\n\r\n if(mismatch) {\r\n // Reset the matched 'any' indices, if any.\r\n outputTarget.deadkeys().resetMatched();\r\n this._AnyIndices = [];\r\n }\r\n\r\n return !mismatch;\r\n }\r\n\r\n /**\r\n * Function KIK\r\n * Scope Public\r\n * @param {Object} e keystroke event\r\n * @return {boolean} true if keypress event\r\n * Description Test if event as a keypress event\r\n */\r\n isKeypress(e: KeyEvent): boolean {\r\n if(this.activeKeyboard.isMnemonic) { // I1380 - support KIK for positional layouts\r\n return !e.LisVirtualKey; // will now return true for U_xxxx keys, but not for T_xxxx keys\r\n } else {\r\n return KeyMapping._USKeyCodeToCharCode(e) ? true : false; // I1380 - support KIK for positional layouts\r\n }\r\n }\r\n\r\n /**\r\n * Maps a KeyEvent's modifiers to their appropriate value for key-rule evaluation\r\n * based on the rule's specified target modifier set.\r\n *\r\n * Mostly used to correct chiral OSK-keys targeting non-chiral rules.\r\n * @param e The source KeyEvent\r\n * @returns\r\n */\r\n private static matchModifiersToRuleChirality(eventModifiers: number, targetModifierMask: number): number {\r\n const CHIRAL_ALT = Codes.modifierCodes[\"LALT\"] | Codes.modifierCodes[\"RALT\"];\r\n const CHIRAL_CTRL = Codes.modifierCodes[\"LCTRL\"] | Codes.modifierCodes[\"RCTRL\"];\r\n\r\n let modifiers = eventModifiers;\r\n\r\n // If the target rule does not use chiral alt...\r\n if(!(targetModifierMask & CHIRAL_ALT)) {\r\n const altIntersection = modifiers & CHIRAL_ALT;\r\n\r\n if(altIntersection) {\r\n // Undo the chiral part and replace with non-chiral.\r\n modifiers ^= altIntersection | Codes.modifierCodes[\"ALT\"];\r\n }\r\n }\r\n\r\n // If the target rule does not use chiral ctrl...\r\n if(!(targetModifierMask & CHIRAL_CTRL)) {\r\n const ctrlIntersection = modifiers & CHIRAL_CTRL;\r\n\r\n if(ctrlIntersection) {\r\n // Undo the chiral part and replace with non-chiral.\r\n modifiers ^= ctrlIntersection | Codes.modifierCodes[\"CTRL\"];\r\n }\r\n }\r\n\r\n return modifiers;\r\n }\r\n\r\n /**\r\n * Function keyMatch KKM\r\n * Scope Public\r\n * @param {Object} e keystroke event\r\n * @param {number} Lruleshift\r\n * @param {number} Lrulekey\r\n * @return {boolean} True if key matches rule\r\n * Description Test keystroke with modifiers against rule\r\n */\r\n keyMatch(e: KeyEvent, Lruleshift:number, Lrulekey:number): boolean {\r\n var retVal = false; // I3318\r\n var keyCode = (e.Lcode == 173 ? 189 : e.Lcode); //I3555 (Firefox hyphen issue)\r\n\r\n let bitmask = this.activeKeyboard.modifierBitmask;\r\n var modifierBitmask = bitmask & Codes.modifierBitmasks[\"ALL\"];\r\n var stateBitmask = bitmask & Codes.stateBitmasks[\"ALL\"];\r\n\r\n const eventModifiers = KeyboardInterface.matchModifiersToRuleChirality(e.Lmodifiers, Lruleshift);\r\n\r\n if(e.vkCode > 255) {\r\n keyCode = e.vkCode; // added to support extended (touch-hold) keys for mnemonic layouts\r\n }\r\n\r\n if(e.LisVirtualKey || keyCode > 255) {\r\n if((Lruleshift & 0x4000) == 0x4000 || (keyCode > 255)) { // added keyCode test to support extended keys\r\n retVal = ((Lrulekey == keyCode) && ((Lruleshift & modifierBitmask) == eventModifiers)); //I3318, I3555\r\n retVal = retVal && this.stateMatch(e, Lruleshift & stateBitmask);\r\n }\r\n } else if((Lruleshift & 0x4000) == 0) {\r\n retVal = (keyCode == Lrulekey); // I3318, I3555\r\n }\r\n if(!retVal) {\r\n this.activeTargetOutput.deadkeys().resetMatched(); // I3318\r\n }\r\n return retVal; // I3318\r\n };\r\n\r\n /**\r\n * Function stateMatch KSM\r\n * Scope Public\r\n * @param {Object} e keystroke event\r\n * @param {number} Lstate\r\n * Description Test keystroke against state key rules\r\n */\r\n stateMatch(e: KeyEvent, Lstate: number) {\r\n return ((Lstate & e.Lstates) == Lstate);\r\n }\r\n\r\n /**\r\n * Function keyInformation KKI\r\n * Scope Public\r\n * @param {Object} e\r\n * @return {Object} Object with event's virtual key flag, key code, and modifiers\r\n * Description Get object with extended key event information\r\n */\r\n keyInformation(e: KeyEvent): KeyInformation {\r\n var ei = new KeyInformation();\r\n ei['vk'] = e.LisVirtualKey;\r\n ei['code'] = e.Lcode;\r\n ei['modifiers'] = e.Lmodifiers;\r\n return ei;\r\n };\r\n\r\n /**\r\n * Function deadkeyMatch KDM\r\n * Scope Public\r\n * @param {number} n offset from current cursor position\r\n * @param {Object} Ptarg target element\r\n * @param {number} d deadkey\r\n * @return {boolean} True if deadkey found selected context matches val\r\n * Description Match deadkey at current cursor position\r\n */\r\n deadkeyMatch(n: number, outputTarget: OutputTarget, d: number): boolean {\r\n return outputTarget.hasDeadkeyMatch(n, d);\r\n }\r\n\r\n /**\r\n * Function beep KB\r\n * Scope Public\r\n * @param {Object} Pelem element to flash\r\n * Description Flash body as substitute for audible beep; notify embedded device to vibrate\r\n */\r\n beep(outputTarget: OutputTarget): void {\r\n this.resetContextCache();\r\n\r\n // Denote as part of the matched rule's behavior.\r\n this.ruleBehavior.beep = true;\r\n }\r\n\r\n _ExplodeStore(store: KeyboardStore): ComplexKeyboardStore {\r\n if(typeof(store) == 'string') {\r\n let cachedStores = this.activeKeyboard.explodedStores;\r\n\r\n // Is the result cached?\r\n if(cachedStores[store]) {\r\n return cachedStores[store];\r\n }\r\n\r\n // Nope, so let's build its cache.\r\n var result: ComplexKeyboardStore = [];\r\n for(var i=0; i < store._kmwLength(); i++) {\r\n result.push(store._kmwCharAt(i));\r\n }\r\n\r\n // Cache the result for later!\r\n cachedStores[store] = result;\r\n return result;\r\n } else {\r\n return store;\r\n }\r\n }\r\n\r\n /**\r\n * Function any KA\r\n * Scope Public\r\n * @param {number} n character position (index)\r\n * @param {string} ch character to find in string\r\n * @param {string} s 'any' string\r\n * @return {boolean} True if character found in 'any' string, sets index accordingly\r\n * Description Test for character matching\r\n */\r\n any(n: number, ch: KeyboardStoreElement, s: KeyboardStore): boolean {\r\n if(ch == '') {\r\n return false;\r\n }\r\n\r\n s = this._ExplodeStore(s);\r\n var Lix = -1;\r\n for(var i=0; i < s.length; i++) {\r\n if(typeof(s[i]) == 'string') {\r\n if(s[i] == ch) {\r\n Lix = i;\r\n break;\r\n }\r\n } else if(s[i]['d'] === ch['d']) {\r\n Lix = i;\r\n break;\r\n }\r\n }\r\n this._AnyIndices[n] = Lix;\r\n return Lix >= 0;\r\n }\r\n\r\n /**\r\n * Function _Index\r\n * Scope Public\r\n * @param {string} Ps string\r\n * @param {number} Pn index\r\n * Description Returns the character from a store string according to the offset in the index array\r\n */\r\n _Index(Ps: KeyboardStore, Pn: number): KeyboardStoreElement {\r\n Ps = this._ExplodeStore(Ps);\r\n\r\n if(this._AnyIndices[Pn-1] < Ps.length) { //I3319\r\n return Ps[this._AnyIndices[Pn-1]];\r\n } else {\r\n /* Should not be possible for a compiled keyboard, but may arise\r\n * during the development of handwritten keyboards.\r\n */\r\n console.warn(\"Unmatched contextual index() statement detected in rule with index \" + Pn + \"!\");\r\n return \"\";\r\n }\r\n }\r\n\r\n /**\r\n * Function indexOutput KIO\r\n * Scope Public\r\n * @param {number} Pdn no of character to overwrite (delete)\r\n * @param {string} Ps string\r\n * @param {number} Pn index\r\n * @param {Object} Pelem element to output to\r\n * Description Output a character selected from the string according to the offset in the index array\r\n */\r\n indexOutput(Pdn: number, Ps: KeyboardStore, Pn: number, outputTarget: OutputTarget): void {\r\n this.resetContextCache();\r\n\r\n var assertNever = function(x: never): never {\r\n // Could be accessed by improperly handwritten calls to `fullContextMatch`.\r\n throw new Error(\"Unexpected object in fullContextMatch specification: \" + x);\r\n }\r\n\r\n var indexChar = this._Index(Ps, Pn);\r\n if(indexChar !== \"\") {\r\n if(typeof indexChar == 'string' ) {\r\n this.output(Pdn, outputTarget, indexChar); //I3319\r\n } else if(indexChar['t']) {\r\n var storeEntry = indexChar as StoreNonCharEntry;\r\n\r\n switch(storeEntry.t) {\r\n case 'b': // Beep commands may appear within stores.\r\n this.beep(outputTarget);\r\n break;\r\n case 'd':\r\n this.deadkeyOutput(Pdn, outputTarget, indexChar['d']);\r\n break;\r\n default:\r\n assertNever(storeEntry);\r\n }\r\n } else { // For keyboards developed during 10.0's alpha phase - t:'d' was assumed.\r\n this.deadkeyOutput(Pdn, outputTarget, indexChar['d']);\r\n }\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Function deleteContext KDC\r\n * Scope Public\r\n * @param {number} dn number of context entries to overwrite\r\n * @param {Object} Pelem element to output to\r\n * @param {string} s string to output\r\n * Description Keyboard output\r\n */\r\n deleteContext(dn: number, outputTarget: OutputTarget): void {\r\n var context: CachedExEntry;\r\n\r\n // We want to control exactly which deadkeys get removed.\r\n if(dn > 0) {\r\n context = this._BuildExtendedContext(dn, dn, outputTarget);\r\n let nulCount = 0;\r\n\r\n for(var i=0; i < context.valContext.length; i++) {\r\n var dk = context.deadContext[i];\r\n\r\n if(dk) {\r\n // Remove deadkey in context.\r\n outputTarget.deadkeys().remove(dk);\r\n\r\n // Reduce our reported context size.\r\n dn--;\r\n } else if(context.valContext[i] == \"\\uFFFE\") {\r\n // Count any `nul` sentinels that would contribute to our deletion count.\r\n nulCount++;\r\n }\r\n }\r\n\r\n // Prevent attempts to delete nul sentinels, as they don't exist in the actual context.\r\n // (Addresses regression from KMW v 12.0 paired with Developer bug through same version)\r\n let contextLength = context.valContext.length - nulCount;\r\n if(dn > contextLength) {\r\n dn = contextLength;\r\n }\r\n }\r\n\r\n // If a matched deadkey hasn't been deleted, we don't WANT to delete it.\r\n outputTarget.deadkeys().resetMatched();\r\n\r\n // Why reinvent the wheel? Delete the remaining characters by 'inserting a blank string'.\r\n this.output(dn, outputTarget, '');\r\n }\r\n\r\n /**\r\n * Function output KO\r\n * Scope Public\r\n * @param {number} dn number of characters to overwrite\r\n * @param {Object} Pelem element to output to\r\n * @param {string} s string to output\r\n * Description Keyboard output\r\n */\r\n output(dn: number, outputTarget: OutputTarget, s:string): void {\r\n this.resetContextCache();\r\n\r\n outputTarget.saveProperties();\r\n outputTarget.clearSelection();\r\n outputTarget.deadkeys().deleteMatched(); // I3318\r\n if(dn >= 0) {\r\n // Automatically manages affected deadkey positions. Does not delete deadkeys b/c legacy behavior support.\r\n outputTarget.deleteCharsBeforeCaret(dn);\r\n }\r\n // Automatically manages affected deadkey positions.\r\n outputTarget.insertTextBeforeCaret(s);\r\n outputTarget.restoreProperties();\r\n }\r\n\r\n /**\r\n * `contextExOutput` function emits the character or object at `contextOffset` from the\r\n * current matched rule's context. Introduced in Keyman 14.0, in order to resolve a\r\n * gap between desktop and web core functionality for context(n) matching on notany().\r\n * See #917 for additional detail.\r\n * @alias KCXO\r\n * @public\r\n * @param {number} Pdn number of characters to delete left of cursor\r\n * @param {OutputTarget} outputTarget target to output to\r\n * @param {number} contextLength length of current rule context to retrieve\r\n * @param {number} contextOffset offset from start of current rule context, 1-based\r\n */\r\n contextExOutput(Pdn: number, outputTarget: OutputTarget, contextLength: number, contextOffset: number): void {\r\n this.resetContextCache();\r\n\r\n if(Pdn >= 0) {\r\n this.output(Pdn, outputTarget, \"\");\r\n }\r\n\r\n const context = this.ruleContextEx.get(contextLength, contextLength);\r\n const dk = context.deadContext[contextOffset-1], vc = context.valContext[contextOffset-1];\r\n if(dk) {\r\n outputTarget.insertDeadkeyBeforeCaret(dk.d);\r\n } else if(typeof vc == 'string') {\r\n this.output(-1, outputTarget, vc);\r\n } else {\r\n throw new Error(\"contextExOutput: should never be a numeric valContext with no corresponding deadContext\");\r\n }\r\n }\r\n\r\n /**\r\n * Function deadkeyOutput KDO\r\n * Scope Public\r\n * @param {number} Pdn no of character to overwrite (delete)\r\n * @param {Object} Pelem element to output to\r\n * @param {number} Pd deadkey id\r\n * Description Record a deadkey at current cursor position, deleting Pdn characters first\r\n */\r\n deadkeyOutput(Pdn: number, outputTarget: OutputTarget, Pd: number): void {\r\n this.resetContextCache();\r\n\r\n if(Pdn >= 0) {\r\n this.output(Pdn, outputTarget,\"\"); //I3318 corrected to >=\r\n }\r\n\r\n outputTarget.insertDeadkeyBeforeCaret(Pd);\r\n // _DebugDeadKeys(Pelem, 'KDeadKeyOutput: dn='+Pdn+'; deadKey='+Pd);\r\n }\r\n\r\n /**\r\n * KIFS compares the content of a system store with a string value\r\n *\r\n * @param {number} systemId ID of the system store to test (only TSS_LAYER currently supported)\r\n * @param {string} strValue String value to compare to\r\n * @param {Object} Pelem Currently active element (may be needed by future tests)\r\n * @return {boolean} True if the test succeeds\r\n */\r\n ifStore(systemId: number, strValue: string, outputTarget: OutputTarget): boolean {\r\n var result=true;\r\n let store = this.systemStores[systemId];\r\n if(store) {\r\n result = store.matches(strValue);\r\n }\r\n return result; //Moved from previous line, now supports layer selection, Build 350\r\n }\r\n\r\n /**\r\n * KSETS sets the value of a system store to a string\r\n *\r\n * @param {number} systemId ID of the system store to set (only TSS_LAYER currently supported)\r\n * @param {string} strValue String to set as the system store content\r\n * @param {Object} Pelem Currently active element (may be needed in future tests)\r\n * @return {boolean} True if command succeeds\r\n * (i.e. for TSS_LAYER, if the layer is successfully selected)\r\n *\r\n * Note that option/variable stores are instead set within keyboard script code, as they only\r\n * affect keyboard behavior.\r\n */\r\n setStore(systemId: number, strValue: string, outputTarget: OutputTarget): boolean {\r\n this.resetContextCache();\r\n // Unique case: we only allow set(&layer) ops from keyboard rules triggered by touch OSKs.\r\n if(systemId == SystemStoreIDs.TSS_LAYER && this.activeDevice.touchable) {\r\n // Denote the changed store as part of the matched rule's behavior.\r\n this.ruleBehavior.setStore[systemId] = strValue;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Load an option store value from a cookie or default value\r\n *\r\n * @param {string} kbdName keyboard internal name\r\n * @param {string} storeName store (option) name, embedded in cookie name\r\n * @param {string} dfltValue default value\r\n * @return {string} current or default option value\r\n *\r\n * This will only ever be called when the keyboard is loaded, as it is used by keyboards\r\n * to initialize a store value on the keyboard's script object.\r\n */\r\n loadStore(kbdName: string, storeName:string, dfltValue:string): string {\r\n this.resetContextCache();\r\n if(this.variableStoreSerializer) {\r\n let cValue = this.variableStoreSerializer.loadStore(kbdName, storeName);\r\n return cValue[storeName] || dfltValue;\r\n } else {\r\n return dfltValue;\r\n }\r\n }\r\n\r\n /**\r\n * Save an option store value to a cookie\r\n *\r\n * @param {string} storeName store (option) name, embedded in cookie name\r\n * @param {string} optValue option value to save\r\n * @return {boolean} true if save successful\r\n *\r\n * Note that a keyboard will freely manipulate the value of its variable stores on the\r\n * script object within its own code. This function's use is merely to _persist_ that\r\n * value across sessions, providing a custom user default for later uses of the keyboard.\r\n */\r\n saveStore(storeName:string, optValue:string): boolean {\r\n this.resetContextCache();\r\n var kbd=this.activeKeyboard;\r\n if(!kbd || typeof kbd.id == 'undefined' || kbd.id == '') {\r\n return false;\r\n }\r\n\r\n // And the lookup under that entry looks for the value under the store name, again.\r\n let valueObj: VariableStore = {};\r\n valueObj[storeName] = optValue;\r\n\r\n // Null-check in case of invocation during unit-test\r\n if(this.ruleBehavior) {\r\n this.ruleBehavior.saveStore[storeName] = valueObj;\r\n } else {\r\n // We're in a unit-test environment, directly invoking this method from outside of a keyboard.\r\n // In this case, we should immediately commit the change.\r\n this.variableStoreSerializer.saveStore(this.activeKeyboard.id, storeName, valueObj);\r\n }\r\n return true;\r\n }\r\n\r\n resetContextCache(): void {\r\n this.cachedContext.reset();\r\n this.cachedContextEx.reset();\r\n }\r\n\r\n defaultBackspace(outputTarget: OutputTarget) {\r\n if(outputTarget.isSelectionEmpty()) {\r\n // Delete the character left of the caret\r\n this.output(1, outputTarget, \"\");\r\n } else {\r\n // Delete just the selection\r\n this.output(0, outputTarget, \"\");\r\n }\r\n }\r\n\r\n /**\r\n * Function processNewContextEvent\r\n * Scope Private\r\n * @param {Object} outputTarget The target receiving input\r\n * @param {Object} keystroke The input keystroke (with its properties) to be mapped by the keyboard.\r\n * Description Calls the keyboard's `begin newContext` group\r\n * @returns {RuleBehavior} Record of commands and state changes that result from executing `begin NewContext`\r\n */\r\n processNewContextEvent(outputTarget: OutputTarget, keystroke: KeyEvent): RuleBehavior {\r\n if(!this.activeKeyboard) {\r\n throw \"No active keyboard for keystroke processing!\";\r\n }\r\n return this.process(this.activeKeyboard.processNewContextEvent.bind(this.activeKeyboard), outputTarget, keystroke, true);\r\n }\r\n\r\n /**\r\n * Function processPostKeystroke\r\n * Scope Private\r\n * @param {Object} outputTarget The target receiving input\r\n * @param {Object} keystroke The input keystroke with relevant properties to be mapped by the keyboard.\r\n * Description Calls the keyboard's `begin postKeystroke` group\r\n * @returns {RuleBehavior} Record of commands and state changes that result from executing `begin PostKeystroke`\r\n */\r\n processPostKeystroke(outputTarget: OutputTarget, keystroke: KeyEvent): RuleBehavior {\r\n if(!this.activeKeyboard) {\r\n throw \"No active keyboard for keystroke processing!\";\r\n }\r\n return this.process(this.activeKeyboard.processPostKeystroke.bind(this.activeKeyboard), outputTarget, keystroke, true);\r\n }\r\n\r\n /**\r\n * Function processKeystroke\r\n * Scope Private\r\n * @param {Object} outputTarget The target receiving input\r\n * @param {Object} keystroke The input keystroke (with its properties) to be mapped by the keyboard.\r\n * Description Encapsulates calls to keyboard input processing.\r\n * @returns {RuleBehavior} Record of commands and state changes that result from executing `begin Unicode`\r\n */\r\n processKeystroke(outputTarget: OutputTarget, keystroke: KeyEvent): RuleBehavior {\r\n if(!this.activeKeyboard) {\r\n throw \"No active keyboard for keystroke processing!\";\r\n }\r\n return this.process(this.activeKeyboard.process.bind(this.activeKeyboard), outputTarget, keystroke, false);\r\n }\r\n\r\n private process(callee, outputTarget: OutputTarget, keystroke: KeyEvent, readonly: boolean): RuleBehavior {\r\n // Clear internal state tracking data from prior keystrokes.\r\n if(!outputTarget) {\r\n throw \"No target specified for keyboard output!\";\r\n } else if(!this.activeKeyboard) {\r\n throw \"No active keyboard for keystroke processing!\";\r\n } else if(!callee) {\r\n throw \"No callee for keystroke processing!\";\r\n }\r\n\r\n outputTarget.invalidateSelection();\r\n\r\n outputTarget.deadkeys().resetMatched(); // I3318\r\n this.resetContextCache();\r\n\r\n // Capture the initial state of the OutputTarget before any rules are matched.\r\n let preInput = Mock.from(outputTarget, true);\r\n\r\n // Capture the initial state of any variable stores\r\n const cachedVariableStores = this.activeKeyboard.variableStores;\r\n\r\n // Establishes the results object, allowing corresponding commands to set values here as appropriate.\r\n this.ruleBehavior = new RuleBehavior();\r\n\r\n // Ensure the settings are in place so that KIFS/ifState activates and deactivates\r\n // the appropriate rule(s) for the modeled device.\r\n this.activeDevice = keystroke.device;\r\n\r\n // Calls the start-group of the active keyboard.\r\n this.activeTargetOutput = outputTarget;\r\n var matched = callee(outputTarget, keystroke);\r\n this.activeTargetOutput = null;\r\n\r\n // Finalize the rule's results.\r\n this.ruleBehavior.transcription = outputTarget.buildTranscriptionFrom(preInput, keystroke, readonly);\r\n\r\n // We always backup the changes to variable stores to the RuleBehavior, to\r\n // be applied during finalization, then restore them to the cached initial\r\n // values to avoid side-effects with predictive text mocks.\r\n this.ruleBehavior.variableStores = this.activeKeyboard.variableStores;\r\n this.activeKeyboard.variableStores = cachedVariableStores;\r\n\r\n // `matched` refers to whether or not the FINAL rule (from any group) matched, rather than\r\n // whether or not ANY rule matched. If the final rule doesn't match, we trigger the key's\r\n // default behavior (if appropriate).\r\n //\r\n // See https://github.com/keymanapp/keyman/pull/4350#issuecomment-768753852\r\n this.ruleBehavior.triggerKeyDefault = !matched;\r\n\r\n // Clear our result-tracking variable to prevent any possible pollution for future processing.\r\n let behavior = this.ruleBehavior;\r\n this.ruleBehavior = null;\r\n\r\n return behavior;\r\n }\r\n\r\n /**\r\n * Applies the dictionary of variable store values to the active keyboard\r\n *\r\n * Has no effect on keyboards compiled with 14.0 or earlier; system store\r\n * names are not exposed unless compiled with Developer 15.0 or later.\r\n *\r\n * @param stores A dictionary of stores which should be found in the\r\n * keyboard\r\n */\r\n applyVariableStores(stores: VariableStoreDictionary): void {\r\n this.activeKeyboard.variableStores = stores;\r\n }\r\n\r\n /**\r\n * Publishes the KeyboardInterface's shorthand API names. As this assigns the current functions\r\n * held by the longform versions, note that this should be called after replacing any of them via\r\n * JS method extension.\r\n *\r\n * DOM-aware KeymanWeb should call this after its domKbdInterface.ts code is loaded, as it replaces\r\n * a few. (This is currently done within its kmwapi.ts.)\r\n */\r\n static __publishShorthandAPI() {\r\n // Keyboard callbacks\r\n let prototype = this.prototype;\r\n\r\n var exportKBCallback = function(miniName: string, longName: string) {\r\n if(prototype[longName]) {\r\n prototype[miniName] = prototype[longName];\r\n }\r\n }\r\n\r\n exportKBCallback('KSF', 'saveFocus');\r\n exportKBCallback('KBR', 'beepReset');\r\n exportKBCallback('KT', 'insertText');\r\n exportKBCallback('KR', 'registerKeyboard');\r\n exportKBCallback('KRS', 'registerStub');\r\n exportKBCallback('KC', 'context');\r\n exportKBCallback('KN', 'nul');\r\n exportKBCallback('KCM', 'contextMatch');\r\n exportKBCallback('KFCM', 'fullContextMatch');\r\n exportKBCallback('KIK', 'isKeypress');\r\n exportKBCallback('KKM', 'keyMatch');\r\n exportKBCallback('KSM', 'stateMatch');\r\n exportKBCallback('KKI', 'keyInformation');\r\n exportKBCallback('KDM', 'deadkeyMatch');\r\n exportKBCallback('KB', 'beep');\r\n exportKBCallback('KA', 'any');\r\n exportKBCallback('KDC', 'deleteContext');\r\n exportKBCallback('KO', 'output');\r\n exportKBCallback('KDO', 'deadkeyOutput');\r\n exportKBCallback('KCXO', 'contextExOutput');\r\n exportKBCallback('KIO', 'indexOutput');\r\n exportKBCallback('KIFS', 'ifStore');\r\n exportKBCallback('KSETS', 'setStore');\r\n exportKBCallback('KLOAD', 'loadStore');\r\n exportKBCallback('KSAVE', 'saveStore');\r\n }\r\n}\r\n\r\n(function() {\r\n // This will be the only call within the keyboard-processor module.\r\n KeyboardInterface.__publishShorthandAPI();\r\n}());", + "// #region Big ol' list of imports\r\n\r\nimport EventEmitter from 'eventemitter3';\r\n\r\nimport Codes from \"./codes.js\";\r\nimport type Keyboard from \"../keyboards/keyboard.js\";\r\nimport { MinimalKeymanGlobal } from '../keyboards/keyboardHarness.js';\r\nimport KeyEvent from \"./keyEvent.js\";\r\nimport { Layouts } from \"../keyboards/defaultLayouts.js\";\r\nimport type { MutableSystemStore } from \"./systemStores.js\";\r\n\r\nimport DefaultRules, { EmulationKeystrokes } from \"./defaultRules.js\";\r\nimport type OutputTarget from \"./outputTarget.js\";\r\nimport { Mock } from \"./outputTarget.js\";\r\n\r\nimport KeyboardInterface, { SystemStoreIDs, VariableStore } from \"./kbdInterface.js\";\r\nimport RuleBehavior from \"./ruleBehavior.js\";\r\n\r\nimport { DeviceSpec, globalObject } from \"@keymanapp/web-utils\";\r\n\r\n// #endregion\r\n\r\n// Also relies on @keymanapp/web-utils, which is included via tsconfig.json.\r\n\r\nexport type BeepHandler = (outputTarget: OutputTarget) => void;\r\nexport type LogMessageHandler = (str: string) => void;\r\n\r\nexport interface VariableStoreSerializer {\r\n loadStore(keyboardID: string, storeName: string): VariableStore;\r\n saveStore(keyboardID: string, storeName: string, storeMap: VariableStore);\r\n}\r\n\r\nexport interface ProcessorInitOptions {\r\n baseLayout?: string;\r\n keyboardInterface?: KeyboardInterface;\r\n defaultOutputRules?: DefaultRules; // Takes the class def object, not an instance thereof.\r\n}\r\n\r\ninterface EventMap {\r\n statekeychange: (stateKeys: typeof KeyboardProcessor.prototype.stateKeys) => void;\r\n}\r\n\r\nexport default class KeyboardProcessor extends EventEmitter {\r\n public static readonly DEFAULT_OPTIONS: ProcessorInitOptions = {\r\n baseLayout: 'us',\r\n defaultOutputRules: new DefaultRules()\r\n };\r\n\r\n // Tracks the simulated value for supported state keys, allowing the OSK to mirror a physical keyboard for them.\r\n // Using the exact keyCode name from the Codes definitions will allow for certain optimizations elsewhere in the code.\r\n stateKeys = {\r\n \"K_CAPS\":false,\r\n \"K_NUMLOCK\":false,\r\n \"K_SCROLL\":false\r\n };\r\n\r\n // Tracks the most recent modifier state information in order to quickly detect changes\r\n // in keyboard state not otherwise captured by the hosting page in the browser.\r\n // Needed for AltGr simulation.\r\n modStateFlags: number = 0;\r\n\r\n keyboardInterface: KeyboardInterface;\r\n\r\n /**\r\n * Indicates the device (platform) to be used for non-keystroke events,\r\n * such as those sent to `begin postkeystroke` and `begin newcontext`\r\n * entry points.\r\n */\r\n contextDevice: DeviceSpec;\r\n\r\n baseLayout: string;\r\n\r\n defaultRules: DefaultRules;\r\n\r\n // Callbacks for various feedback types\r\n beepHandler?: BeepHandler;\r\n warningLogger?: LogMessageHandler;\r\n errorLogger?: LogMessageHandler;\r\n\r\n constructor(device: DeviceSpec, options?: ProcessorInitOptions) {\r\n super();\r\n\r\n if(!options) {\r\n options = KeyboardProcessor.DEFAULT_OPTIONS;\r\n }\r\n\r\n this.contextDevice = device;\r\n\r\n this.baseLayout = options.baseLayout || KeyboardProcessor.DEFAULT_OPTIONS.baseLayout;\r\n this.keyboardInterface = options.keyboardInterface || new KeyboardInterface(globalObject(), MinimalKeymanGlobal);\r\n this.defaultRules = options.defaultOutputRules || KeyboardProcessor.DEFAULT_OPTIONS.defaultOutputRules;\r\n }\r\n\r\n public get activeKeyboard(): Keyboard {\r\n return this.keyboardInterface.activeKeyboard;\r\n }\r\n\r\n public set activeKeyboard(keyboard: Keyboard) {\r\n this.keyboardInterface.activeKeyboard = keyboard;\r\n\r\n // All old deadkeys and keyboard-specific cache should immediately be invalidated\r\n // on a keyboard change.\r\n this.resetContext();\r\n }\r\n\r\n get layerStore(): MutableSystemStore {\r\n return this.keyboardInterface.systemStores[SystemStoreIDs.TSS_LAYER] as MutableSystemStore;\r\n }\r\n\r\n public get newLayerStore(): MutableSystemStore {\r\n return this.keyboardInterface.systemStores[SystemStoreIDs.TSS_NEWLAYER] as MutableSystemStore;\r\n }\r\n\r\n public get oldLayerStore(): MutableSystemStore {\r\n return this.keyboardInterface.systemStores[SystemStoreIDs.TSS_OLDLAYER] as MutableSystemStore;\r\n }\r\n\r\n public get layerId(): string {\r\n return this.layerStore.value;\r\n }\r\n\r\n // Note: will trigger an 'event' callback designed to notify the OSK of layer changes.\r\n public set layerId(value: string) {\r\n this.layerStore.set(value);\r\n }\r\n\r\n /**\r\n * Get the default RuleBehavior for the specified key, attempting to mimic standard browser defaults\r\n * where and when appropriate.\r\n *\r\n * @param {object} Lkc The pre-analyzed KeyEvent object\r\n * @param {boolean} outputTarget The OutputTarget receiving the KeyEvent\r\n * @return {string}\r\n */\r\n defaultRuleBehavior(Lkc: KeyEvent, outputTarget: OutputTarget, readonly: boolean): RuleBehavior {\r\n let preInput = Mock.from(outputTarget, readonly);\r\n let ruleBehavior = new RuleBehavior();\r\n\r\n let matched = false;\r\n var char = '';\r\n var special: EmulationKeystrokes;\r\n if(Lkc.isSynthetic || outputTarget.isSynthetic) {\r\n matched = true; // All the conditions below result in matches until the final else, which restores the expected default\r\n // if no match occurs.\r\n\r\n if(this.defaultRules.isCommand(Lkc)) {\r\n // Note this in the rule behavior, return successfully. We'll consider applying it later.\r\n ruleBehavior.triggersDefaultCommand = true;\r\n\r\n // We'd rather let the browser handle these keys, but we're using emulated keystrokes, forcing KMW\r\n // to emulate default behavior here.\r\n } else if((special = this.defaultRules.forSpecialEmulation(Lkc)) != null) {\r\n switch(special) {\r\n case EmulationKeystrokes.Backspace:\r\n this.keyboardInterface.defaultBackspace(outputTarget);\r\n break;\r\n case EmulationKeystrokes.Enter:\r\n outputTarget.handleNewlineAtCaret();\r\n break;\r\n // case '\\u007f': // K_DEL\r\n // // For (possible) future implementation.\r\n // // Would recommend (conceptually) equaling K_RIGHT + K_BKSP, the former of which would technically be a 'command'.\r\n default:\r\n // In case we extend the allowed set, but forget to implement its handling case above.\r\n ruleBehavior.errorLog = \"Unexpected 'special emulation' character (\\\\u\" + (special as String).kmwCharCodeAt(0).toString(16) + \") went unhandled!\";\r\n }\r\n } else {\r\n // Back to the standard default, pending normal matching.\r\n matched = false;\r\n }\r\n }\r\n\r\n let isMnemonic = this.activeKeyboard && this.activeKeyboard.isMnemonic;\r\n\r\n if(!matched) {\r\n if((char = this.defaultRules.forAny(Lkc, isMnemonic)) != null) {\r\n special = this.defaultRules.forSpecialEmulation(Lkc)\r\n if(special == EmulationKeystrokes.Backspace) {\r\n // A browser's default backspace may fail to delete both parts of an SMP character.\r\n this.keyboardInterface.defaultBackspace(outputTarget);\r\n } else if(special || this.defaultRules.isCommand(Lkc)) { // Filters out 'commands' like TAB.\r\n // We only do the \"for special emulation\" cases under the condition above... aside from backspace\r\n // Let the browser handle those.\r\n return null;\r\n } else {\r\n this.keyboardInterface.output(0, outputTarget, char);\r\n }\r\n } else {\r\n // No match, no default RuleBehavior.\r\n return null;\r\n }\r\n }\r\n\r\n // Shortcut things immediately if there were issues generating this rule behavior.\r\n if(ruleBehavior.errorLog) {\r\n return ruleBehavior;\r\n }\r\n\r\n let transcription = outputTarget.buildTranscriptionFrom(preInput, Lkc, readonly);\r\n ruleBehavior.transcription = transcription;\r\n\r\n return ruleBehavior;\r\n }\r\n\r\n processNewContextEvent(device: DeviceSpec, outputTarget: OutputTarget): RuleBehavior {\r\n return this.activeKeyboard ?\r\n this.keyboardInterface.processNewContextEvent(outputTarget, this.activeKeyboard.constructNullKeyEvent(device, this.stateKeys)) :\r\n null;\r\n }\r\n\r\n processPostKeystroke(device: DeviceSpec, outputTarget: OutputTarget): RuleBehavior {\r\n return this.activeKeyboard ?\r\n this.keyboardInterface.processPostKeystroke(outputTarget, this.activeKeyboard.constructNullKeyEvent(device, this.stateKeys)) :\r\n null;\r\n }\r\n\r\n processKeystroke(keyEvent: KeyEvent, outputTarget: OutputTarget): RuleBehavior {\r\n var matchBehavior: RuleBehavior;\r\n\r\n // Pass this key code and state to the keyboard program\r\n if(this.activeKeyboard && keyEvent.Lcode != 0) {\r\n matchBehavior = this.keyboardInterface.processKeystroke(outputTarget, keyEvent);\r\n }\r\n\r\n if(!matchBehavior || matchBehavior.triggerKeyDefault) {\r\n // Restore the virtual key code if a mnemonic keyboard is being used\r\n // If no vkCode value was stored, maintain the original Lcode value.\r\n keyEvent.Lcode=keyEvent.vkCode || keyEvent.Lcode;\r\n\r\n // Handle unmapped keys, including special keys\r\n // The following is physical layout dependent, so should be avoided if possible. All keys should be mapped.\r\n this.keyboardInterface.activeTargetOutput = outputTarget;\r\n\r\n // Match against the 'default keyboard' - rules to mimic the default string output when typing in a browser.\r\n // Many keyboards rely upon these 'implied rules'.\r\n let defaultBehavior = this.defaultRuleBehavior(keyEvent, outputTarget, false);\r\n if(defaultBehavior) {\r\n if(!matchBehavior) {\r\n matchBehavior = defaultBehavior;\r\n } else {\r\n matchBehavior.mergeInDefaults(defaultBehavior);\r\n }\r\n matchBehavior.triggerKeyDefault = false; // We've triggered it successfully.\r\n } // If null, we must rely on something else (like the browser, in DOM-aware code) to fulfill the default.\r\n\r\n this.keyboardInterface.activeTargetOutput = null;\r\n }\r\n\r\n return matchBehavior;\r\n }\r\n\r\n /**\r\n * Function _UpdateVKShift\r\n * Scope Private\r\n * @param {Object} e OSK event\r\n * @return {boolean} Always true\r\n * Description Updates the current shift state within KMW, updating the OSK's visualization thereof.\r\n */\r\n _UpdateVKShift(e: KeyEvent): boolean {\r\n let keyShiftState=0;\r\n\r\n const lockNames = ['CAPS', 'NUM_LOCK', 'SCROLL_LOCK'];\r\n const lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'];\r\n\r\n if(!this.activeKeyboard) {\r\n return true;\r\n }\r\n\r\n if(e) {\r\n // read shift states from Pevent\r\n keyShiftState = e.Lmodifiers;\r\n\r\n // Are we simulating AltGr? If it's a simulation and not real, time to un-simulate for the OSK.\r\n if(this.activeKeyboard.isChiral && (this.activeKeyboard.emulatesAltGr) &&\r\n (this.modStateFlags & Codes.modifierBitmasks['ALT_GR_SIM']) == Codes.modifierBitmasks['ALT_GR_SIM']) {\r\n keyShiftState |= Codes.modifierBitmasks['ALT_GR_SIM'];\r\n keyShiftState &= ~Codes.modifierCodes['RALT'];\r\n }\r\n\r\n // Set stateKeys where corresponding value is passed in e.Lstates\r\n let stateMutation = false;\r\n for(let i=0; i < lockNames.length; i++) {\r\n if(e.Lstates & Codes.stateBitmasks[lockNames[i]]) {\r\n this.stateKeys[lockKeys[i]] = !!(e.Lstates & Codes.modifierCodes[lockNames[i]]);\r\n stateMutation = true;\r\n }\r\n }\r\n\r\n if(stateMutation) {\r\n this.emit('statekeychange', this.stateKeys);\r\n }\r\n }\r\n\r\n this.updateStates();\r\n\r\n if(this.activeKeyboard.isMnemonic && this.stateKeys['K_CAPS']) {\r\n // Modifier keypresses doesn't trigger mnemonic manipulation of modifier state.\r\n // Only an output key does; active use of Caps will also flip the SHIFT flag.\r\n if(!e || !e.isModifier) {\r\n // Mnemonic keystrokes manipulate the SHIFT property based on CAPS state.\r\n // We need to unflip them when tracking the OSK layer.\r\n keyShiftState ^= Codes.modifierCodes['SHIFT'];\r\n }\r\n }\r\n\r\n this.layerId = this.getLayerId(keyShiftState);\r\n return true;\r\n }\r\n\r\n private updateStates(): void {\r\n var lockNames = ['CAPS', 'NUM_LOCK', 'SCROLL_LOCK'];\r\n var lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'];\r\n\r\n for(let i=0; i < lockKeys.length; i++) {\r\n const key = lockKeys[i];\r\n const flag = this.stateKeys[key];\r\n const onBit = lockNames[i];\r\n const offBit = 'NO_' + lockNames[i];\r\n\r\n // Ensures that the current mod-state info properly matches the currently-simulated\r\n // state key states.\r\n if(flag) {\r\n this.modStateFlags |= Codes.modifierCodes[onBit];\r\n this.modStateFlags &= ~Codes.modifierCodes[offBit];\r\n } else {\r\n this.modStateFlags &= ~Codes.modifierCodes[onBit];\r\n this.modStateFlags |= Codes.modifierCodes[offBit];\r\n }\r\n }\r\n }\r\n\r\n getLayerId(modifier: number): string {\r\n return Layouts.getLayerId(modifier);\r\n }\r\n\r\n /**\r\n * Select the OSK's next keyboard layer based upon layer switching keys as a default\r\n * The next layer will be determined from the key name unless otherwise specifed\r\n *\r\n * @param {string} keyName key identifier\r\n * @return {boolean} return true if keyboard layer changed\r\n */\r\n selectLayer(keyEvent: KeyEvent): boolean {\r\n let keyName = keyEvent.kName;\r\n var nextLayer = keyEvent.kNextLayer;\r\n var isChiral = this.activeKeyboard && this.activeKeyboard.isChiral;\r\n\r\n // Layer must be identified by name, not number (27/08/2015)\r\n if(typeof nextLayer == 'number') {\r\n nextLayer = this.getLayerId(nextLayer * 0x10);\r\n }\r\n\r\n // Identify next layer, if required by key\r\n if(!nextLayer) {\r\n switch(keyName) {\r\n case 'K_LSHIFT':\r\n case 'K_RSHIFT':\r\n case 'K_SHIFT':\r\n nextLayer = 'shift';\r\n break;\r\n case 'K_LCONTROL':\r\n case 'K_LCTRL':\r\n if(isChiral) {\r\n nextLayer = 'leftctrl';\r\n break;\r\n }\r\n case 'K_RCONTROL':\r\n case 'K_RCTRL':\r\n if(isChiral) {\r\n nextLayer = 'rightctrl';\r\n break;\r\n }\r\n case 'K_CTRL':\r\n nextLayer = 'ctrl';\r\n break;\r\n case 'K_LMENU':\r\n case 'K_LALT':\r\n if(isChiral) {\r\n nextLayer = 'leftalt';\r\n break;\r\n }\r\n case 'K_RMENU':\r\n case 'K_RALT':\r\n if(isChiral) {\r\n nextLayer = 'rightalt';\r\n break;\r\n }\r\n case 'K_ALT':\r\n nextLayer = 'alt';\r\n break;\r\n case 'K_ALTGR':\r\n if(isChiral) {\r\n nextLayer = 'leftctrl-rightalt';\r\n } else {\r\n nextLayer = 'ctrl-alt';\r\n }\r\n break;\r\n case 'K_CURRENCIES':\r\n case 'K_NUMERALS':\r\n case 'K_SHIFTED':\r\n case 'K_UPPER':\r\n case 'K_LOWER':\r\n case 'K_SYMBOLS':\r\n nextLayer = 'default';\r\n break;\r\n }\r\n }\r\n\r\n // If no key corresponding to a layer transition is pressed, maintain the current layer.\r\n if(!nextLayer) {\r\n return false;\r\n }\r\n\r\n // Change layer and refresh OSK\r\n this.updateLayer(keyEvent, nextLayer);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Sets the new layer id, allowing for toggling shift/ctrl/alt while preserving the remainder\r\n * of the modifiers represented by the current layer id (where applicable)\r\n *\r\n * @param {string} id layer id (e.g. ctrlshift)\r\n */\r\n updateLayer(keyEvent: KeyEvent, id: string) {\r\n let activeLayer = this.layerId;\r\n var s = activeLayer;\r\n\r\n // Do not change layer unless needed (27/08/2015)\r\n if(id == activeLayer && keyEvent.device.formFactor != DeviceSpec.FormFactor.Desktop) {\r\n return false;\r\n }\r\n\r\n var idx=id;\r\n var i;\r\n\r\n if(keyEvent.device.formFactor == DeviceSpec.FormFactor.Desktop) {\r\n // Need to test if target layer is a standard layer (based on the plain 'default')\r\n var replacements= ['leftctrl', 'rightctrl', 'ctrl', 'leftalt', 'rightalt', 'alt', 'shift'];\r\n\r\n for(i=0; i < replacements.length; i++) {\r\n // Don't forget to remove the kebab-case hyphens!\r\n idx=idx.replace(replacements[i] + '-', '');\r\n idx=idx.replace(replacements[i],'');\r\n }\r\n\r\n // If we are presently on the default layer, drop the 'default' and go straight to the shifted mode.\r\n // If on a common symbolic layer, drop out of symbolic mode and go straight to the shifted mode.\r\n if(activeLayer == 'default' || activeLayer == 'numeric' || activeLayer == 'symbol' || activeLayer == 'currency' || idx != '') {\r\n s = id;\r\n }\r\n // Otherwise, we are based upon a layer that accepts modifier variations.\r\n // Modify the layer according to the current state and key pressed.\r\n //\r\n // TODO: Consider: should this ever be allowed for a base layer other than 'default'? If not,\r\n // if(idx == '') with accompanying if-else structural shift would be a far better test here.\r\n else {\r\n // Save our current modifier state.\r\n var modifier=Codes.getModifierState(s);\r\n\r\n // Strip down to the base modifiable layer.\r\n for(i=0; i < replacements.length; i++) {\r\n // Don't forget to remove the kebab-case hyphens!\r\n s=s.replace(replacements[i] + '-', '');\r\n s=s.replace(replacements[i],'');\r\n }\r\n\r\n // Toggle the modifier represented by our input argument.\r\n switch(id) {\r\n case 'shift':\r\n modifier ^= Codes.modifierCodes['SHIFT'];\r\n break;\r\n case 'leftctrl':\r\n modifier ^= Codes.modifierCodes['LCTRL'];\r\n break;\r\n case 'rightctrl':\r\n modifier ^= Codes.modifierCodes['RCTRL'];\r\n break;\r\n case 'ctrl':\r\n modifier ^= Codes.modifierCodes['CTRL'];\r\n break;\r\n case 'leftalt':\r\n modifier ^= Codes.modifierCodes['LALT'];\r\n break;\r\n case 'rightalt':\r\n modifier ^= Codes.modifierCodes['RALT'];\r\n break;\r\n case 'alt':\r\n modifier ^= Codes.modifierCodes['ALT'];\r\n break;\r\n default:\r\n s = id;\r\n }\r\n\r\n // Combine our base modifiable layer and attach the new modifier variation info to obtain our destination layer.\r\n if(s != 'default') {\r\n if(s == '') {\r\n s = this.getLayerId(modifier);\r\n } else {\r\n s = this.getLayerId(modifier) + '-' + s;\r\n }\r\n }\r\n }\r\n\r\n if(s == '') {\r\n s = 'default';\r\n }\r\n } else {\r\n // Mobile form-factor. Either the layout is specified by a keyboard developer with direct layer name references\r\n // or all layers are accessed via subkey of a single layer-shifting key - no need for modifier-combining logic.\r\n s = id;\r\n }\r\n\r\n let layout = this.activeKeyboard.layout(keyEvent.device.formFactor);\r\n if(layout.getLayer(s)) {\r\n this.layerId = s;\r\n } else {\r\n this.layerId = 'default';\r\n }\r\n\r\n let baseModifierState = Codes.getModifierState(this.layerId);\r\n this.modStateFlags = baseModifierState | keyEvent.Lstates;\r\n }\r\n\r\n // Returns true if the key event is a modifier press, allowing keyPress to return selectively\r\n // in those cases.\r\n doModifierPress(Levent: KeyEvent, outputTarget: OutputTarget, isKeyDown: boolean): boolean {\r\n if(!this.activeKeyboard) {\r\n return false;\r\n }\r\n\r\n if(Levent.Lcode == 8) {\r\n // I3318 (always clear deadkeys after backspace)\r\n outputTarget.deadkeys().clear();\r\n } else if(Levent.isModifier) {\r\n this.activeKeyboard.notify(Levent.Lcode, outputTarget, isKeyDown ? 1 : 0);\r\n // For eventual integration - we bypass an OSK update for physical keystrokes when in touch mode.\r\n if(!Levent.device.touchable) {\r\n return this._UpdateVKShift(Levent); // I2187\r\n } else {\r\n return true;\r\n }\r\n }\r\n\r\n if(Levent.LmodifierChange) {\r\n this.activeKeyboard.notify(0, outputTarget, 1);\r\n if(!Levent.device.touchable) {\r\n this._UpdateVKShift(Levent);\r\n }\r\n }\r\n\r\n // No modifier keypresses detected.\r\n return false;\r\n }\r\n\r\n /**\r\n * Tell the currently active keyboard that a new context has been selected,\r\n * e.g. by focus change, selection change, keyboard change, etc.\r\n *\r\n * @param {Object} outputTarget The OutputTarget that has focus\r\n * @returns {Object} A RuleBehavior object describing the cumulative effects of\r\n * all matched keyboard rules\r\n */\r\n performNewContextEvent(outputTarget: OutputTarget): RuleBehavior {\r\n const ruleBehavior = this.processNewContextEvent(this.contextDevice, outputTarget);\r\n\r\n if(ruleBehavior) {\r\n ruleBehavior.finalize(this, outputTarget, true);\r\n }\r\n return ruleBehavior;\r\n }\r\n\r\n resetContext(target?: OutputTarget) {\r\n this.layerId = 'default';\r\n this.keyboardInterface.resetContextCache();\r\n\r\n // May be null if it's a keyboard swap.\r\n // Performed before _UpdateVKShift since the op may modify the displayed layer\r\n // Also updates the layer for predictions.\r\n if(target) {\r\n this.performNewContextEvent(target);\r\n }\r\n\r\n if(!this.contextDevice.touchable) {\r\n this._UpdateVKShift(null);\r\n }\r\n };\r\n\r\n setNumericLayer(device: DeviceSpec) {\r\n if (this.activeKeyboard) {\r\n let layout = this.activeKeyboard.layout(device.formFactor);\r\n if(layout.getLayer('numeric')) {\r\n this.layerId = 'numeric';\r\n }\r\n }\r\n };\r\n}\r\n", + "import { PathOptionSpec } from \"./optionSpec.interface.js\";\r\nimport { OSKResourcePathConfiguration } from 'keyman/engine/osk';\r\n\r\nconst addDelimiter = (p: string) => {\r\n // Add delimiter if missing\r\n if(p.substring(p.length-1) != '/') {\r\n return p + '/';\r\n } else {\r\n return p;\r\n }\r\n}\r\n\r\nexport default class PathConfiguration implements OSKResourcePathConfiguration {\r\n private readonly sourcePath: string;\r\n private _root: string;\r\n private _resources: string;\r\n private _keyboards: string;\r\n\r\n // May get its initial value from the Keyman Cloud API after a query if not\r\n // otherwise specified.\r\n private _fonts: string;\r\n readonly protocol: string;\r\n\r\n /*\r\n * Pre-modularization code corresponding to `sourcePath`:\r\n ```\r\n // Determine path and protocol of executing script, setting them as\r\n // construction defaults.\r\n //\r\n // This can only be done during load when the active script will be the\r\n // last script loaded. Otherwise the script must be identified by name.\r\n\r\n var scripts = document.getElementsByTagName('script');\r\n var ss = scripts[scripts.length-1].src;\r\n var sPath = ss.substr(0,ss.lastIndexOf('/')+1);\r\n ```\r\n */\r\n constructor(pathSpec: Required, sourcePath: string) {\r\n sourcePath = addDelimiter(sourcePath);\r\n this.sourcePath = sourcePath;\r\n this.protocol = sourcePath.replace(/(.{3,5}:)(.*)/,'$1');\r\n\r\n this.updateFromOptions(pathSpec);\r\n }\r\n\r\n updateFromOptions(pathSpec: Required) {\r\n const _rootPath = this.sourcePath.replace(/(https?:\\/\\/)([^\\/]*)(.*)/,'$1$2/');\r\n\r\n // Get default paths and device options\r\n this._root = _rootPath;\r\n if(pathSpec.root != '') {\r\n this._root = this.fixPath(pathSpec.root);\r\n } else {\r\n this._root = this.fixPath(_rootPath);\r\n }\r\n\r\n // Resources are located with respect to the engine by default\r\n let resources = pathSpec.resources; // avoid mutating the parameter!\r\n if(resources == '') {\r\n resources = this.sourcePath;\r\n }\r\n\r\n // Convert resource, keyboard and font paths to absolute URLs\r\n this._resources = this.fixPath(resources);\r\n this._keyboards = this.fixPath(pathSpec.keyboards);\r\n this._fonts = this.fixPath(pathSpec.fonts);\r\n }\r\n\r\n // Local function to convert relative to absolute URLs\r\n // with respect to the source path, server root and protocol\r\n fixPath(p: string) {\r\n if(p.length == 0) {\r\n return p;\r\n }\r\n\r\n p = addDelimiter(p);\r\n\r\n // Absolute\r\n if((p.replace(/^(http)s?:.*/,'$1') == 'http') || (p.replace(/^(file):.*/,'$1') == 'file')) {\r\n return p;\r\n }\r\n\r\n // Absolute (except for protocol)\r\n if(p.substring(0,2) == '//') {\r\n return this.protocol + p;\r\n }\r\n\r\n // Relative to server root\r\n if(p.substring(0,1) == '/') {\r\n return this.root + p.substring(1);\r\n }\r\n\r\n // Otherwise, assume relative to source path\r\n return this.sourcePath + p;\r\n }\r\n\r\n get fonts(): string {\r\n return this._fonts;\r\n }\r\n\r\n updateFontPath(path: string) {\r\n this._fonts = this.fixPath(path);\r\n }\r\n\r\n get root(): string {\r\n return this._root;\r\n }\r\n\r\n get resources(): string {\r\n return this._resources;\r\n }\r\n\r\n get keyboards(): string {\r\n return this._keyboards;\r\n }\r\n}", + "export interface PathOptionSpec {\r\n /**\r\n * If defined, specifies the root path of the default location hosting KMW resources.\r\n * Is typically just the protocol + domain name.\r\n */\r\n root?: string;\r\n\r\n /**\r\n * The base path to prepend on relative paths for other types of resources.\r\n */\r\n resources?: string;\r\n\r\n /**\r\n * The base path to prepend on relative paths when loading keyboards.\r\n */\r\n keyboards?: string;\r\n\r\n /**\r\n * The base path to prepend on relative paths when loading fonts.\r\n */\r\n fonts?: string;\r\n}\r\n\r\nexport const PathOptionDefaults: Required = {\r\n root: '',\r\n resources: '',\r\n keyboards: '',\r\n fonts: ''\r\n}", + "import { DeviceSpec } from \"@keymanapp/web-utils\";\r\n\r\n/*\r\n * This file is intended for CSS-styling constants that see use with the OSK.\r\n */\r\n\r\n/**\r\n * Defines device-level constants used for CSS styling.\r\n */\r\nexport default class StyleConstants {\r\n constructor(device: DeviceSpec) {\r\n // popupCanvasBackgroundColor\r\n if(device.OS == DeviceSpec.OperatingSystem.Android) {\r\n this.popupCanvasBackgroundColor = '#999';\r\n } else {\r\n this.popupCanvasBackgroundColor = StyleConstants.prefersDarkMode() ? '#0f1319' : '#ffffff';\r\n }\r\n }\r\n\r\n /**\r\n * Checks is a user's browser is in dark mode, if the feature is supported. Returns false otherwise.\r\n *\r\n * Thanks to https://stackoverflow.com/a/57795518 for this code.\r\n */\r\n static prefersDarkMode(): boolean {\r\n // Ensure the detector exists (otherwise, returns false)\r\n return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;\r\n }\r\n\r\n public readonly popupCanvasBackgroundColor: string;\r\n}", + "import StyleConstants from './utils/styleConstants.js';\r\nimport { DeviceSpec, Version } from \"@keymanapp/web-utils\";\r\n\r\n// The Device object definition -------------------------------------------------\r\n\r\nexport class Device {\r\n // These correspond directly to the properties & parameters for `DeviceSpec`.\r\n touchable: boolean;\r\n OS: string;\r\n formFactor: string;\r\n browser: string;\r\n\r\n // These components aren't needed for key events. All but `version` could be a sort\r\n // of `DeviceStyle`.\r\n dyPortrait: number; // Its value is only referenced by an unused method.\r\n dyLandscape: number; // Its value is only referenced by an unused method.\r\n orientation: string|number; // Appears to be unused as well?\r\n colorScheme: 'light' | 'dark'; // Also unused?\r\n version: string; // As in, device version; only really persisted for Android.\r\n // No real sign of actual use, though.\r\n\r\n private detected: boolean = false;\r\n\r\n // Generates a default Device value.\r\n constructor() {\r\n this.touchable = !!('ontouchstart' in window);\r\n this.OS = '';\r\n this.formFactor='desktop';\r\n this.browser='';\r\n\r\n this.dyPortrait=0;\r\n this.dyLandscape=0;\r\n this.version='0';\r\n this.orientation=window.orientation;\r\n }\r\n\r\n /**\r\n * Get device horizontal DPI for touch devices, to set actual size of active regions\r\n * Note that the actual physical DPI may be somewhat different.\r\n *\r\n * @return {number}\r\n */\r\n getDPI(): number {\r\n var t=document.createElement('DIV') ,s=t.style,dpi=96;\r\n if(document.readyState !== 'complete') {\r\n return dpi;\r\n }\r\n\r\n t.id='calculateDPI';\r\n s.position='absolute'; s.display='block';s.visibility='hidden';\r\n s.left='10px'; s.top='10px'; s.width='1in'; s.height='10px';\r\n document.body.appendChild(t);\r\n dpi=(typeof window.devicePixelRatio == 'undefined') ? t.offsetWidth : t.offsetWidth * window.devicePixelRatio;\r\n document.body.removeChild(t);\r\n return dpi;\r\n }\r\n\r\n detect() : DeviceSpec {\r\n var possMacSpoof = false;\r\n\r\n if(navigator && navigator.userAgent) {\r\n var agent=navigator.userAgent;\r\n\r\n if(agent.indexOf('iPad') >= 0) {\r\n this.OS='iOS';\r\n this.formFactor='tablet';\r\n this.dyPortrait=this.dyLandscape=0;\r\n } else if(agent.indexOf('iPhone') >= 0) {\r\n this.OS='iOS';\r\n this.formFactor='phone';\r\n this.dyPortrait=this.dyLandscape=25;\r\n } else if(agent.indexOf('Android') >= 0) {\r\n this.OS='Android';\r\n this.formFactor='phone'; // form factor may be redefined on initialization\r\n this.dyPortrait=75;\r\n this.dyLandscape=25;\r\n try {\r\n var rx=new RegExp(\"(?:Android\\\\s+)(\\\\d+\\\\.\\\\d+\\\\.\\\\d+)\");\r\n this.version=agent.match(rx)[1];\r\n } catch(ex) {}\r\n } else if(agent.indexOf('Linux') >= 0) {\r\n this.OS='Linux';\r\n } else if(agent.indexOf('Macintosh') >= 0) {\r\n // Starting with 13.1, \"Macintosh\" can reflect iPads (by default) or iPhones\r\n // (by user setting); a new \"Request Desktop Website\" setting for Safari will\r\n // change the user agent string to match a desktop Mac.\r\n //\r\n // Firefox uses '.' between version components, while Chrome and Safari use\r\n // '_' instead. So, we have to check for both. Yay.\r\n let regex = /Intel Mac OS X (\\d+(?:[_\\.]\\d+)+)/i;\r\n let results = regex.exec(agent);\r\n\r\n // Match result: a version string with components separated by underscores.\r\n if(!results) {\r\n console.warn(\"KMW could not properly parse the user agent string.\"\r\n + \"A suboptimal keyboard layout may result.\");\r\n this.OS='MacOSX';\r\n } else if(results.length > 1 && results[1]) {\r\n // Convert version string into a usable form.\r\n let versionString = results[1].replace('_', '.');\r\n let version = new Version(versionString);\r\n\r\n possMacSpoof = Version.MAC_POSSIBLE_IPAD_ALIAS.compareTo(version) <= 0;\r\n this.OS='MacOSX';\r\n }\r\n } else if(agent.indexOf('Windows NT') >= 0) {\r\n this.OS='Windows';\r\n if(agent.indexOf('Touch') >= 0) {\r\n this.formFactor='phone'; // will be redefined as tablet if resolution high enough\r\n }\r\n\r\n // Windows Phone and Tablet PC\r\n if(typeof (navigator).msMaxTouchPoints == 'number' && (navigator).msMaxTouchPoints > 0) {\r\n this.touchable=true;\r\n }\r\n }\r\n }\r\n\r\n // We look at the screen resolution for Android, because we can't tell from\r\n // the user agent string whether or not this is supposed to be a tablet.\r\n // It seems that there are a handful of older phones out there that report a\r\n // higher resolution than 700px*___px, but it is proving hard to test these,\r\n // and the majority have an aspect ratio <= 0.5625 anyway.\r\n // But we trust what iOS tells us for phone vs tablet.\r\n\r\n const dimMin = Math.min(screen.width,screen.height), dimMax = Math.max(screen.width,screen.height);\r\n const aspect = dimMin / dimMax;\r\n\r\n if(this.OS != 'iOS' &&\r\n this.formFactor == 'phone' &&\r\n ((dimMin >= 600 && aspect > 0.5625) || // 0.5625 -> 1920x1080 is common phone res\r\n (aspect >= 0.625)) // all reported devices with aspect >= 0.625 are tablets per https://screensiz.es/\r\n ) {\r\n this.formFactor='tablet';\r\n }\r\n\r\n // Test for potential Chrome emulation on Windows or macOS X (used only in next if-check)\r\n let possibleChromeEmulation = navigator.platform == 'Win32' || navigator.platform == 'MacIntel'\r\n\r\n // alert(sxx+'->'+device.formFactor);\r\n // Check for phony iOS devices (but don't undo for Chrome emulation used during development)\r\n if(this.OS == 'iOS' && !('ongesturestart' in window) && !possibleChromeEmulation) {\r\n this.OS='Android';\r\n }\r\n\r\n // Determine application or browser\r\n this.browser='web';\r\n if(this.OS == 'iOS' || this.OS.toLowerCase() == 'macosx') {\r\n this.browser='safari';\r\n }\r\n\r\n var bMatch=/Firefox|Chrome|OPR|Safari|Edge/;\r\n if(bMatch.test(navigator.userAgent)) {\r\n if((navigator.userAgent.indexOf('Firefox') >= 0) && ('onmozorientationchange' in screen)) {\r\n this.browser='firefox';\r\n } else if(navigator.userAgent.indexOf('OPR') >= 0) {\r\n this.browser='opera';\r\n } else if(navigator.userAgent.indexOf(' Edge/') >= 0) {\r\n // Edge is too common a word, so test for Edge/ :)\r\n // Must come before Chrome and Safari test because\r\n // Edge pretends to be both\r\n this.browser='edge';\r\n } else if(navigator.userAgent.indexOf('Chrome') >= 0) {\r\n // This test must come before Safari test because on macOS,\r\n // Chrome also reports \"Safari\"\r\n this.browser='chrome';\r\n } else if(navigator.userAgent.indexOf('Safari') >= 0) {\r\n this.browser='safari';\r\n }\r\n }\r\n\r\n if(possMacSpoof && this.browser == 'safari') {\r\n // Indistinguishable user agent string! We need a different test; fortunately, true macOS\r\n // Safari doesn't support TouchEvents. (Chrome does, though! Hence the filter above.)\r\n if(window['TouchEvent']) {\r\n this.OS='iOS';\r\n this.formFactor='tablet';\r\n this.dyPortrait=this.dyLandscape=0;\r\n\r\n // It's currently impossible to differentiate between iPhone and iPad here\r\n // except for by screen dimensions.\r\n let aspectRatio = screen.height / screen.width;\r\n if(aspectRatio < 1) {\r\n aspectRatio = 1 / aspectRatio;\r\n }\r\n\r\n // iPhones usually have a ratio of 16:9 (or 1.778) or higher, while iPads use 4:3 (or 1.333)\r\n if(aspectRatio > 1.6) {\r\n // Override - we'll treat this device as an iPhone.\r\n this.formFactor = 'phone';\r\n this.dyPortrait=this.dyLandscape=25;\r\n }\r\n }\r\n }\r\n\r\n this.colorScheme = StyleConstants.prefersDarkMode() ? 'dark' : 'light';\r\n this.detected = true;\r\n\r\n return this.coreSpec;\r\n }\r\n\r\n /**\r\n * Returns a slimmer, web-core compatible version of this object.\r\n */\r\n public get coreSpec(): DeviceSpec {\r\n return new DeviceSpec(this.browser, this.formFactor, this.OS, this.touchable);\r\n }\r\n}\r\n\r\nexport default Device;", + "import EventEmitter from 'eventemitter3';\r\nimport { DeviceSpec, ManagedPromise, type Keyboard, type KeyboardInterface, type OutputTarget } from '@keymanapp/keyboard-processor';\r\nimport { StubAndKeyboardCache, type KeyboardStub } from 'keyman/engine/package-cache';\r\nimport { PredictionContext } from '@keymanapp/input-processor';\r\nimport { EngineConfiguration } from './engineConfiguration.js';\r\n\r\ninterface EventMap {\r\n // target, then keyboard.\r\n 'targetchange': (target: OutputTarget) => boolean;\r\n\r\n /**\r\n * This event is raised whenever a keyboard change is requested.\r\n *\r\n * Note that if the keyboard has not been previously loaded, this event will be raised twice.\r\n * 1. Before the keyboard is loaded into Keyman Engine for Web.\r\n * 2. Once the keyboard is loaded, but before it is activated.\r\n * @param metadata The to-be-activated keyboard's properties\r\n * @returns\r\n */\r\n 'beforekeyboardchange': (metadata: KeyboardStub) => void;\r\n\r\n /**\r\n * This event is raised whenever an activating keyboard is being loaded into Keyman Engine for\r\n * the first time in the user's current session, which is an asynchronous operation. It is called\r\n * once the async request is initiated.\r\n * @param metadata The registered properties for the keyboard being asynchronously loaded\r\n * @param onload A Promise that resolves with `null` when loading successfully completes or\r\n * with an `error` if it fails.\r\n * @returns\r\n */\r\n 'keyboardasyncload': (metadata: KeyboardStub, onload: Promise) => void;\r\n\r\n /**\r\n * This event is raised whenever a keyboard is fully activated and set as the current active\r\n * keyboard within Keyman Engine for Web.\r\n * @param kbd\r\n * @returns\r\n */\r\n 'keyboardchange': (kbd: {keyboard: Keyboard, metadata: KeyboardStub}) => void;\r\n}\r\n\r\nexport interface ContextManagerConfiguration {\r\n /**\r\n * A function that resets any state-dependent keyboard key-state information such as\r\n * emulated modifier state and layer id. Also purges the context cache.\r\n * If an `outputTarget` is specified, it will also trigger new-context rule processing.\r\n *\r\n * Does not reset option-stores, variable-stores, etc.\r\n */\r\n readonly resetContext: (outputTarget?: OutputTarget) => void;\r\n\r\n /**\r\n * A predictive-state management object that interfaces the predictive-text banner\r\n * with the active context.\r\n */\r\n readonly predictionContext: PredictionContext;\r\n\r\n /**\r\n * The stub & keyboard curation cache holding preloaded keyboards and metadata useable\r\n * to load those not yet loaded.\r\n */\r\n readonly keyboardCache: StubAndKeyboardCache;\r\n}\r\n\r\ninterface PendingActivation {\r\n target: OutputTarget,\r\n keyboard: Promise,\r\n stub: KeyboardStub;\r\n}\r\n\r\nexport abstract class ContextManagerBase extends EventEmitter {\r\n public static readonly TIMEOUT_THRESHOLD = 10000;\r\n\r\n abstract initialize(): void;\r\n\r\n abstract get activeTarget(): OutputTarget;\r\n\r\n private _predictionContext: PredictionContext;\r\n protected keyboardCache: StubAndKeyboardCache;\r\n private _resetContext: (outputTarget?: OutputTarget) => void;\r\n\r\n private pendingActivations: PendingActivation[] = [];\r\n protected engineConfig: MainConfig;\r\n\r\n get predictionContext(): PredictionContext {\r\n return this._predictionContext;\r\n }\r\n\r\n constructor(engineConfig: MainConfig) {\r\n super();\r\n\r\n this.engineConfig = engineConfig;\r\n }\r\n\r\n configure(config: ContextManagerConfiguration) {\r\n this._resetContext = config.resetContext;\r\n this._predictionContext = config.predictionContext;\r\n this.keyboardCache = config.keyboardCache;\r\n }\r\n\r\n insertText(kbdInterface: KeyboardInterface, Ptext: string, PdeadKey: number) {\r\n // Find the correct output target to manipulate.\r\n const outputTarget = this.activeTarget;\r\n\r\n if(outputTarget != null) {\r\n if(Ptext != null) {\r\n kbdInterface.output(0, outputTarget, Ptext);\r\n }\r\n\r\n if((typeof(PdeadKey)!=='undefined') && (PdeadKey !== null)) {\r\n kbdInterface.deadkeyOutput(0, outputTarget, PdeadKey);\r\n }\r\n\r\n outputTarget.invalidateSelection();\r\n\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n resetContext() {\r\n this._resetContext(this.activeTarget);\r\n this.predictionContext.resetContext();\r\n }\r\n\r\n abstract get activeKeyboard(): {keyboard: Keyboard, metadata: KeyboardStub};\r\n\r\n /**\r\n * Determines the 'target' currently used to determine which keyboard should be active.\r\n * When `null`, keyboard-activation operations will affect the global default; otherwise,\r\n * such operations affect only the specified `target`.\r\n *\r\n * This method exists to facilitate independent-keyboard mode operations for specific\r\n * attached elements within the app/browser target. For `app/webview`, this should\r\n * always return a consistent value - likely, `null`.\r\n */\r\n protected abstract currentKeyboardSrcTarget(): OutputTarget;\r\n\r\n /**\r\n * Ensures that newly activated keyboards are set correctly within managed context, possibly\r\n * against inactive output targets.\r\n * @param kbd\r\n * @param target\r\n */\r\n protected abstract activateKeyboardForTarget(kbd: {keyboard: Keyboard, metadata: KeyboardStub}, target: OutputTarget);\r\n\r\n /**\r\n * Checks the pending keyboard-activation array for an entry corresponding to the specified\r\n * OutputTarget. If found, also removes the entry for bookkeeping purposes.\r\n * @param target The specific OutputTarget affected by the pending Keyboard activation.\r\n * May be `null`, which corresponds to the global default Keyboard.\r\n * @returns `true` if pending activation is still valid, `false` otherwise.\r\n */\r\n private findAndPopActivation(target: OutputTarget): PendingActivation {\r\n // Array.findIndex requires Chrome 45+. :(\r\n let activationIndex;\r\n for(activationIndex = 0; activationIndex < this.pendingActivations.length; activationIndex++) {\r\n if(this.pendingActivations[activationIndex].target == target) {\r\n break;\r\n }\r\n }\r\n\r\n if(activationIndex == this.pendingActivations.length) {\r\n return null;\r\n }\r\n\r\n return this.pendingActivations.splice(activationIndex, 1)[0];\r\n }\r\n\r\n /**\r\n * Internally registers a pending keyboard-activation's properties, only resolving to a non-null\r\n * activation if it is still the most recent keyboard-activation request that would affect the\r\n * corresponding context.\r\n * @param kbdPromise\r\n * @param metadata\r\n * @param target\r\n * @returns\r\n */\r\n protected async deferredKeyboardActivation(\r\n kbdPromise: Promise,\r\n metadata: KeyboardStub,\r\n target: OutputTarget\r\n ): Promise {\r\n const activation: PendingActivation = {\r\n target: target,\r\n keyboard: kbdPromise,\r\n stub: metadata\r\n };\r\n\r\n // Invalidate existing requests for the specified target.\r\n this.findAndPopActivation(target);\r\n this.pendingActivations.push(activation);\r\n await kbdPromise;\r\n\r\n // The keyboard-load is complete; is the activation still desired?\r\n const activationAfterAwait = this.findAndPopActivation(target);\r\n if(activationAfterAwait == activation) {\r\n return activation;\r\n } else if(activationAfterAwait) {\r\n // Restore the popped element; it doesn't match the current activation attempt.\r\n this.pendingActivations.push(activationAfterAwait);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Specifies the keyboard id and the language code to use when a 'default' keyboard\r\n * must be selected by the engine for fallback behaviors.\r\n */\r\n protected abstract getFallbackStubKey(): {\r\n id: string,\r\n langId: string\r\n };\r\n\r\n /**\r\n * Change active keyboard to keyboard selected by (internal) name and language code\r\n *\r\n * Test if selected keyboard already loaded, and simply update active stub if so.\r\n * Otherwise, insert a script to download and insert the keyboard from the repository\r\n * or user-indicated file location.\r\n *\r\n * @param keyboardId\r\n * @param languageCode\r\n * @param saveCookie\r\n * @returns\r\n */\r\n public async activateKeyboard(keyboardId: string, languageCode?: string, saveCookie?: boolean): Promise {\r\n // TODO: relocate default keyboard behavior here once we can also move core error handling for\r\n // unfound stubs here.\r\n\r\n // If there was a previous activation attempt set and still active for the specified keyboard target,\r\n // cancel it. For exmaple, if the user selects a preloaded keyboard after having tried to select one\r\n // still async-loading, we should go with the later setting - the preloaded one.\r\n this.findAndPopActivation(this.currentKeyboardSrcTarget());\r\n\r\n const activatingKeyboard = this.prepareKeyboardForActivation(keyboardId, languageCode);\r\n\r\n const originalKeyboardTarget = this.currentKeyboardSrcTarget();\r\n\r\n const keyboard = await activatingKeyboard.keyboard;\r\n if(keyboard == null && activatingKeyboard.metadata) {\r\n // The activation was async and was cancelled - either by `beforeKeyboardChange` first-pass\r\n // cancellation or because a different keyboard was requested before completion of the async load.\r\n return false;\r\n }\r\n\r\n /*\r\n * Triggers `beforeKeyboardChange` event if the current context at the time when activation is possible\r\n * would be affected by the requested keyboard change.\r\n * - if a keyboard was asynchronously loaded for this...\r\n * - it is possible for the context (in app/browser) to have changed to a page element in\r\n * \"independent keyboard\" mode (or away from one)\r\n * - This is the \"second\" `beforeKeyboardChange` call - a loaded keyboard may now be activated.\r\n *\r\n * If the now-current context would be unaffected by the keyboard change, we do not raise the corresponding\r\n * event.\r\n */\r\n if(this.currentKeyboardSrcTarget() == originalKeyboardTarget) {\r\n this.emit('beforekeyboardchange', activatingKeyboard.metadata);\r\n }\r\n\r\n let kbdStubPair: { keyboard: Keyboard, metadata: KeyboardStub } = null;\r\n if(keyboard) {\r\n kbdStubPair = {\r\n keyboard: keyboard,\r\n metadata: activatingKeyboard.metadata\r\n };\r\n }\r\n\r\n this.activateKeyboardForTarget(kbdStubPair, originalKeyboardTarget);\r\n\r\n // Only trigger `keyboardchange` events when they will affect the active context.\r\n if(this.currentKeyboardSrcTarget() == originalKeyboardTarget) {\r\n // Perform standard context-reset ops, including the processing of new-context events.\r\n this.resetContext();\r\n // Will trigger KeymanEngine handler that passes keyboard to the OSK, displays it.\r\n this.emit('keyboardchange', this.activeKeyboard);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Based on the provided keyboard id and language code, selects and (if necessary) loads the\r\n * corresponding keyboard but does not activate it.\r\n *\r\n * This acts as a helper to `activateKeyboard`, helping to centralize and DRY out the actual\r\n * activation of the requested keyboard. Note that it is a synchronous method and should stay\r\n * that way, though it should return a `Promise` for the activating keyboard.\r\n * @param keyboardId\r\n * @param languageCode\r\n * @returns\r\n */\r\n protected prepareKeyboardForActivation(\r\n keyboardId: string,\r\n languageCode?: string\r\n ): {keyboard: Promise, metadata: KeyboardStub} {\r\n // Set default language code\r\n languageCode ||= '';\r\n\r\n // Check that the saved keyboard is currently registered\r\n let requestedStub = null;\r\n if(keyboardId) {\r\n requestedStub = this.keyboardCache.getStub(keyboardId, languageCode);\r\n } else {\r\n languageCode == '';\r\n }\r\n\r\n if(!requestedStub) {\r\n if(keyboardId) {\r\n throw new Error(\"No matching stub has been registered.\");\r\n } else {\r\n return {\r\n keyboard: Promise.resolve(null),\r\n metadata: null\r\n }\r\n }\r\n }\r\n\r\n // Check if current keyboard matches requested keyboard, but not (necessarily) stub\r\n if(this.activeKeyboard?.metadata && keyboardId == this.activeKeyboard.metadata.id) {\r\n const keyboard = this.activeKeyboard.keyboard;\r\n // In this case, the keyboard is loaded; just update the stub.\r\n\r\n return {\r\n keyboard: Promise.resolve(keyboard),\r\n metadata: requestedStub\r\n };\r\n }\r\n\r\n // Determine if the keyboard was previously loaded but is not active; use the cached, pre-loaded version if so.\r\n let keyboard: Keyboard;\r\n if(keyboard = this.keyboardCache.getKeyboardForStub(requestedStub)) {\r\n return {\r\n keyboard: Promise.resolve(keyboard),\r\n metadata: requestedStub\r\n };\r\n } else {\r\n // It's async time - the keyboard is not preloaded within the cache. Use the stub's data to load it.\r\n\r\n // `beforeKeyboardChange` - first call\r\n this.emit('beforekeyboardchange', requestedStub);\r\n\r\n const defermentPromise = this.engineConfig.deferForInitialization.then(() => {\r\n // Provide a Promise for completion of the async load process.\r\n const completionPromise = new ManagedPromise();\r\n this.emit('keyboardasyncload', requestedStub, completionPromise.corePromise);\r\n\r\n let keyboardPromise = this.keyboardCache.fetchKeyboardForStub(requestedStub);\r\n let timeoutPromise = new Promise((resolve, reject) => {\r\n const timeoutMsg = `Sorry, the ${requestedStub.name} keyboard for ${requestedStub.langName} is not currently available.`;\r\n window.setTimeout(() => reject(new Error(timeoutMsg)), ContextManagerBase.TIMEOUT_THRESHOLD);\r\n });\r\n\r\n let combinedPromise = Promise.race([keyboardPromise, timeoutPromise]);\r\n\r\n // Ensure the async-load Promise completes properly.\r\n combinedPromise.then(() => {\r\n completionPromise.resolve(null);\r\n // Prevent any 'unhandled Promise rejection' events that may otherwise occur from the timeout promise.\r\n timeoutPromise.catch(() => {});\r\n });\r\n combinedPromise.catch((err) => {\r\n completionPromise.resolve(err);\r\n throw err;\r\n });\r\n\r\n return combinedPromise;\r\n });\r\n\r\n // Now the fun part: note the original call's parameters as a pending activation.\r\n let promise = this.deferredKeyboardActivation(defermentPromise, requestedStub, this.currentKeyboardSrcTarget());\r\n return {\r\n keyboard: promise.then(async (activation) => {\r\n // Is the activation we requested still pending, or was it cancelled in favor of a\r\n // different activation in some manner?\r\n if(!activation) {\r\n // If the user chose to load a different keyboard afterward that would affect the same\r\n // output target, the activation is no longer valid.\r\n return Promise.resolve(null);\r\n } else {\r\n return defermentPromise;\r\n }\r\n }),\r\n metadata: requestedStub\r\n }\r\n }\r\n }\r\n}", + "import EventEmitter from \"eventemitter3\";\r\nimport { type KeyEvent, type RuleBehavior } from \"@keymanapp/keyboard-processor\";\r\nimport KeyEventSourceInterface from './keyEventSource.interface.js';\r\n\r\ninterface EventMap {\r\n /**\r\n * Designed to pass key events off to any consuming modules/libraries.\r\n */\r\n 'keyevent': (event: KeyEvent, callback?: (result: RuleBehavior, error?: Error) => void) => void\r\n}\r\n\r\nexport default class HardKeyboard extends EventEmitter implements KeyEventSourceInterface { }\r\n\r\n// Intended design:\r\n// - KeyEventKeyboard: website-integrated handler for hardware-keystroke input; interprets DOM events.\r\n// - app/web\r\n// - AppPassthroughKeyboard: WebView-hosted forwarding of hardware key events through to the Web engine.\r\n// - app/embed", + "import { Keyboard, KeyboardLoaderBase as KeyboardLoader } from \"@keymanapp/keyboard-processor\";\r\nimport EventEmitter from \"eventemitter3\";\r\n\r\nimport KeyboardStub from \"./keyboardStub.js\";\r\n\r\nconst KEYBOARD_PREFIX = \"Keyboard_\";\r\n\r\nfunction prefixed(text: string) {\r\n if(!text.startsWith(KEYBOARD_PREFIX)) {\r\n return KEYBOARD_PREFIX + text;\r\n } else {\r\n return text;\r\n }\r\n}\r\n\r\nexport {prefixed as toPrefixedKeyboardId};\r\n\r\nfunction withoutPrefix(text: string) {\r\n if(text.startsWith(KEYBOARD_PREFIX)) {\r\n return text.substring(KEYBOARD_PREFIX.length);\r\n } else {\r\n return text;\r\n }\r\n}\r\n\r\nexport {withoutPrefix as toUnprefixedKeyboardId};\r\n\r\ninterface EventMap {\r\n /**\r\n * Indicates that the specified stub has just been registered within the cache.\r\n *\r\n * Note for future hook: establish a listener for this event during engine init\r\n * to denote the first added stub to facilitate auto-activation of the first\r\n * keyboard to be registered.\r\n */\r\n stubadded: (stub: KeyboardStub) => void;\r\n\r\n /**\r\n * Indicates that the specified Keyboard has just been added to the cache.\r\n */\r\n keyboardadded: (keyboard: Keyboard) => void;\r\n}\r\n\r\nexport default class StubAndKeyboardCache extends EventEmitter {\r\n private stubSetTable: Record> = {};\r\n private keyboardTable: Record> = {};\r\n\r\n private readonly keyboardLoader: KeyboardLoader;\r\n\r\n constructor(keyboardLoader?: KeyboardLoader) {\r\n super();\r\n this.keyboardLoader = keyboardLoader;\r\n }\r\n\r\n getKeyboardForStub(stub: KeyboardStub): Keyboard {\r\n return this.getKeyboard(stub.KI);\r\n }\r\n\r\n getKeyboard(keyboardID: string): Keyboard {\r\n if(!keyboardID) {\r\n return null;\r\n }\r\n const entry = this.keyboardTable[prefixed(keyboardID)];\r\n\r\n // Unit testing may 'trip up' in the DOM, as bundled versions of a class from one bundled\r\n // module will fail against an `instanceof` expecting the version bundled in a second.\r\n //\r\n // Thus, we filter based on `Promise`, which needs no module.\r\n return entry instanceof Promise ? null : entry;\r\n }\r\n\r\n get defaultStub(): KeyboardStub {\r\n /* See the following two StackOverflow links:\r\n * - https://stackoverflow.com/a/23202095\r\n * - https://stackoverflow.com/a/5525820\r\n *\r\n * Also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values#description\r\n *\r\n * As keyboard IDs are never purely numeric, any sufficiently-recent browser will\r\n * maintain the order in which stubs were added to this cache.\r\n *\r\n * Note that if a keyboard is removed, its matching stubs are also removed, so the next most-recent\r\n * property will take precedence.\r\n *\r\n * Might possibly fail to return the oldest registered stub for the oldest of supported browsers\r\n * (i.e, Android 5.0), but will work for anything decently recent. Even then... we still supply\r\n * _a_ keyboard. Just not in a way that will seem deterministic/controllable to site designers.\r\n *\r\n * Warning: Object.values and Object.entries require Chrome for Android 54, which is higher than\r\n * API 21's base. Object.keys only requires Chrome for Android 18, so is safe.\r\n */\r\n\r\n // An `Object.keys`-based helper function. Gets the first entry of Object.values for the object.\r\n // Can be written with stronger type safety... if we get very explicit with generics during calls.\r\n // That'd be more verbose than desired here.\r\n function getFirstValue(obj: any) {\r\n const keys = Object.keys(obj);\r\n if(keys.length == 0) {\r\n return undefined;\r\n } else {\r\n return obj[keys[0]];\r\n }\r\n };\r\n\r\n const stubTable = getFirstValue(this.stubSetTable) as Record;\r\n if(!stubTable) {\r\n return undefined;\r\n } else {\r\n // First value = first registered stub for that first keyboard.\r\n // Does not consider later-added stubs, but neither does removeKeyboard - removal is \"all or nothing\".\r\n return getFirstValue(stubTable) as KeyboardStub;\r\n }\r\n }\r\n\r\n addKeyboard(keyboard: Keyboard) {\r\n const keyboardID = prefixed(keyboard.id);\r\n this.keyboardTable[keyboardID] = keyboard;\r\n\r\n this.emit('keyboardadded', keyboard);\r\n }\r\n\r\n fetchKeyboardForStub(stub: KeyboardStub) : Promise {\r\n return this.fetchKeyboard(stub.KI);\r\n }\r\n\r\n isFetchingKeyboard(keyboardID: string): boolean {\r\n if(!keyboardID) {\r\n throw new Error(\"Keyboard ID must be specified\");\r\n }\r\n\r\n keyboardID = prefixed(keyboardID);\r\n\r\n const cachedEntry = this.keyboardTable[keyboardID];\r\n return cachedEntry instanceof Promise;\r\n }\r\n\r\n fetchKeyboard(keyboardID: string): Promise {\r\n if(!keyboardID) {\r\n throw new Error(\"Keyboard ID must be specified\");\r\n }\r\n\r\n if(!this.keyboardLoader) {\r\n throw new Error(\"Cannot load keyboards; this cache was configured without a loader\");\r\n }\r\n\r\n keyboardID = prefixed(keyboardID);\r\n\r\n const cachedEntry = this.keyboardTable[keyboardID];\r\n if(cachedEntry instanceof Keyboard) {\r\n return Promise.resolve(cachedEntry);\r\n } else if(cachedEntry instanceof Promise) {\r\n return cachedEntry;\r\n }\r\n\r\n const stub = this.getStub(keyboardID, null);\r\n if(!stub) {\r\n throw new Error(`No stub for ${withoutPrefix(keyboardID)} has been registered`);\r\n }\r\n\r\n if(!stub.filename) {\r\n throw new Error(`The registered stub for ${withoutPrefix(keyboardID)} lacks a path to the main keyboard file`);\r\n }\r\n\r\n const promise = this.keyboardLoader.loadKeyboardFromStub(stub);\r\n this.keyboardTable[keyboardID] = promise;\r\n\r\n promise.then((kbd) => {\r\n // Overrides the built-in ID in case of keyboard namespacing.\r\n kbd.scriptObject[\"KI\"] = keyboardID;\r\n this.addKeyboard(kbd);\r\n }).catch((err) => {\r\n delete this.keyboardTable[keyboardID];\r\n throw err;\r\n })\r\n\r\n return promise;\r\n }\r\n\r\n addStub(stub: KeyboardStub) {\r\n const keyboardID = prefixed(stub.KI);\r\n const stubTable = this.stubSetTable[keyboardID] = this.stubSetTable[keyboardID] ?? {};\r\n stubTable[stub.KLC] = stub;\r\n\r\n this.emit('stubadded', stub);\r\n }\r\n\r\n findMatchingStub(stub: KeyboardStub) {\r\n return this.getStub(stub.KI, stub.KLC);\r\n }\r\n\r\n getStub(keyboardID: string, languageID: string): KeyboardStub;\r\n getStub(keyboard: Keyboard, languageID?: string): KeyboardStub;\r\n getStub(arg0: string | Keyboard, arg1?: string): KeyboardStub {\r\n let keyboardID: string;\r\n let languageID = arg1 || '---';\r\n\r\n if(arg0 instanceof Keyboard) {\r\n keyboardID = arg0.id;\r\n } else {\r\n keyboardID = arg0;\r\n }\r\n\r\n if(keyboardID) {\r\n keyboardID = prefixed(keyboardID);\r\n }\r\n\r\n const stubTable = this.stubSetTable[keyboardID] ?? {};\r\n\r\n if(languageID != '---') {\r\n return stubTable[languageID];\r\n } else {\r\n const keys = Object.keys(stubTable);\r\n if(keys.length == 0) {\r\n return null;\r\n } else {\r\n return stubTable[keys[0]];\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Removes all metadata (stubs) associated with a specific keyboard from the cache, optionally\r\n * removing the cached keyboard as well.\r\n * @param keyboard Either the keyboard ID or `Keyboard` instance\r\n * @param purge If `true`, will also purge the `Keyboard` instance itself from the cache.\r\n * If `false`, only forgets the metadata (stubs).\r\n */\r\n forgetKeyboard(keyboard: string | Keyboard, purge: boolean = false) {\r\n let id: string = (keyboard instanceof Keyboard) ? keyboard.id : prefixed(keyboard);\r\n\r\n if(this.stubSetTable[id]) {\r\n delete this.stubSetTable[id];\r\n }\r\n\r\n if(purge && this.keyboardTable[id]) {\r\n delete this.keyboardTable[id];\r\n }\r\n }\r\n\r\n getStubList(): KeyboardStub[] {\r\n let arr: KeyboardStub[] = [];\r\n\r\n const kbdIds = Object.keys(this.stubSetTable);\r\n for(let kbdId of kbdIds) {\r\n let row = this.stubSetTable[kbdId];\r\n const langIds = Object.keys(row);\r\n for(let langId of langIds) {\r\n arr.push(row[langId]);\r\n }\r\n }\r\n\r\n return arr;\r\n }\r\n}", + "import {\r\n type KeyboardAPIPropertySpec as APISimpleKeyboard,\r\n type KeyboardAPIPropertyMultilangSpec as APICompoundKeyboard,\r\n KeyboardProperties,\r\n type LanguageAPIPropertySpec,\r\n} from '@keymanapp/keyboard-processor';\r\nimport { toPrefixedKeyboardId as prefixed } from './stubAndKeyboardCache.js';\r\n\r\n\r\n// Language regions as defined by cloud server\r\nexport const REGIONS = ['World','Africa','Asia','Europe','South America','North America','Oceania','Central America','Middle East'];\r\nexport const REGION_CODES = ['un','af','as','eu','sa','na','oc','ca','me'];\r\n\r\nexport type KeyboardAPISpec = (APISimpleKeyboard | APICompoundKeyboard) & {\r\n displayName?: string;\r\n filename: string\r\n};\r\n\r\nexport interface RawKeyboardStub extends KeyboardStub {};\r\n\r\n/*\r\n * Get keyboard path (relative or absolute)\r\n * KeymanWeb 2 revised keyboard location specification:\r\n * (a) absolute URL (includes ':') - load from specified URL\r\n * (b) relative URL (starts with /, ./, ../) - load with respect to current page\r\n * (c) filename only (anything else) - prepend keyboards option to URL\r\n * (e.g. default keyboards option will be set by Cloud)\r\n *\r\n * So, to fully interpret the following regex, it detects the following patterns (at minimum):\r\n * ../file (but not .../file)\r\n * ./file\r\n * /file\r\n * http:// (on the colon)\r\n * hello:world (on the colon) - that one miiiight be less intentional, though. Would 'fall\r\n * over' on attempted use anyway, since it's not a valid path.\r\n *\r\n * Alternative clearer version - '^(\\.{0,2}/)|(:)'?\r\n * Unless backslashes should be able to replace dots?\r\n */\r\nconst REGEX_FOR_PRECONFIGURED_PATH=RegExp('^(([\\\\.]/)|([\\\\.][\\\\.]/)|(/))|(:)');\r\n\r\nfunction configureFilePathing(path: string, configurationBasePath: string) {\r\n configurationBasePath = configurationBasePath || '';\r\n if(path && !REGEX_FOR_PRECONFIGURED_PATH.test(path)) {\r\n return configurationBasePath + path;\r\n } else {\r\n return path;\r\n }\r\n}\r\n\r\nexport default class KeyboardStub extends KeyboardProperties {\r\n KR: string;\r\n KRC: string;\r\n KF: string;\r\n\r\n KP?: string;\r\n\r\n // For the first flavor of constructor, note that Developer relies on KMW's path config to complete the paths...\r\n // even though supplying an 'internal'-style stub.\r\n public constructor(rawStub: RawKeyboardStub, keyboardBaseUri?: string, fontBaseUri?: string);\r\n public constructor(apiSpec: APISimpleKeyboard & { filename: string }, keyboardBaseUri?: string, fontBaseUri?: string);\r\n public constructor(kbdId: string, lngId: string);\r\n constructor(arg0: string | RawKeyboardStub | (APISimpleKeyboard & { filename: string }), arg1?: string, arg2?: string) {\r\n if(typeof arg0 !== 'string') {\r\n if(arg0.id !== undefined) {\r\n let apiSpec = arg0 as APISimpleKeyboard & { filename: string };\r\n apiSpec.id = prefixed(apiSpec.id);\r\n super(apiSpec, arg2);\r\n this.KF = configureFilePathing(apiSpec.filename, arg1);\r\n this.mapRegion(apiSpec.languages);\r\n } else {\r\n let rawStub = arg0 as RawKeyboardStub;\r\n rawStub.KI = prefixed(rawStub.KI);\r\n super(rawStub, arg2);\r\n\r\n this.KF = configureFilePathing(rawStub.KF, arg1);\r\n this.KP = rawStub.KP;\r\n this.KR = rawStub.KR;\r\n this.KRC = rawStub.KRC;\r\n\r\n\r\n return;\r\n }\r\n } else {\r\n super(prefixed(arg0), arg1);\r\n }\r\n }\r\n\r\n private mapRegion(language: LanguageAPIPropertySpec) {\r\n // Accept region as number (from Cloud server), code, or name\r\n const region=language.region;\r\n let rIndex=0;\r\n if(typeof(region) == 'number') {\r\n if(region < 1 || region > 9) {\r\n rIndex = 0;\r\n } else {\r\n rIndex = region-1;\r\n }\r\n } else if(typeof(region) == 'string') {\r\n let list = (region.length == 2 ? REGION_CODES : REGIONS);\r\n for(let i=0; i {\r\n // The deprecated `language` is assigned to satisfy TS type-checking.\r\n const intermediate = {...arg, languages: language, language: undefined};\r\n const stub: KeyboardStub = new KeyboardStub(intermediate, keyboardBaseUri, fontBaseUri);\r\n\r\n stubs.push(stub);\r\n })\r\n\r\n return stubs;\r\n }\r\n\r\n public merge(stub: KeyboardStub) {\r\n this.KL ||= stub.KL;\r\n this.KR ||= stub.KR;\r\n this.KRC ||= stub.KRC;\r\n this.KN ||= stub.KN;\r\n this.KF ||= stub.KF;\r\n this.KFont ||= stub.KFont;\r\n this.KOskFont ||= stub.KOskFont;\r\n\r\n if(stub._displayName) {\r\n this._displayName ||= stub._displayName;\r\n }\r\n }\r\n\r\n public validateForCustomKeyboard(): Error {\r\n if(super.validateForCustomKeyboard() || !this.KF || !this.KR) {\r\n return new Error('To use a custom keyboard, you must specify file name, keyboard id, keyboard name, language, language code, and region.');\r\n } else {\r\n return null;\r\n }\r\n }\r\n}\r\n\r\n// Information about a keyboard that fails to get added\r\nexport interface ErrorStub {\r\n keyboard?: {\r\n id: string;\r\n name: string;\r\n },\r\n language?: {\r\n id?: string;\r\n name?: string;\r\n }\r\n\r\n error: Error;\r\n}\r\n\r\nexport function mergeAndResolveStubPromises(keyboardStubs: (KeyboardStub|ErrorStub)[], errorStubs: ErrorStub[]) :\r\n Promise<(KeyboardStub|ErrorStub)[]> {\r\n if (errorStubs.length == 0) {\r\n return Promise.resolve(keyboardStubs);\r\n } if (keyboardStubs.length == 0) {\r\n return Promise.reject(errorStubs);\r\n } else {\r\n // Merge this with errorStubs\r\n let result: (KeyboardStub|ErrorStub)[] = keyboardStubs;\r\n return Promise.resolve(result.concat(errorStubs));\r\n }\r\n}", + "import EventEmitter from 'eventemitter3';\r\n\r\nimport { PathConfiguration } from 'keyman/engine/paths';\r\n\r\nimport { default as KeyboardStub, ErrorStub, KeyboardAPISpec, mergeAndResolveStubPromises } from '../keyboardStub.js';\r\nimport { LanguageAPIPropertySpec, ManagedPromise, Version } from '@keymanapp/keyboard-processor';\r\nimport CloudRequesterInterface from './requesterInterface.js';\r\n\r\n// For when the API call straight-up times out.\r\nexport const CLOUD_TIMEOUT_ERR = \"The Cloud API request timed out.\";\r\n// Currently cannot distinguish between \"no matching keyboard\" and other script-load errors.\r\nexport const CLOUD_MALFORMED_OBJECT_ERR = \"Could not find a keyboard with that ID.\";\r\n// Represents unspecified errors that occur when registering the results of a successful API call.\r\nexport const CLOUD_STUB_REGISTRATION_ERR = \"The Cloud API failed to find an appropriate keyboard.\";\r\n// Represents custom, specified KMW errors that occur when registering the results of a successful API call.\r\nexport const CLOUD_REGISTRATION_ERR = \"Error occurred while registering keyboards: \";\r\n\r\nexport const MISSING_KEYBOARD = function(kbdid: string) {\r\n return kbdid + ' keyboard not found.';\r\n}\r\n\r\ntype CloudAPIFont = {\r\n family: string,\r\n source: string | string[]\r\n}\r\n\r\ntype CloudQueryOptions = {\r\n context: 'keyboard' | 'language';\r\n keyboardid?: string,\r\n keyboardBaseUri?: string,\r\n fontBaseUri?: string\r\n}\r\n\r\ntype CloudKeyboardQueryResult = {\r\n /**\r\n * A 1D array is returned for keyboard-id based queries: `addKeyboards('sil_cameroon_qwerty')`\r\n * returns a single array with one entry.\r\n *\r\n * A 2D array is returned for language-code based keyboard queries: `addKeyboards('@fr,@en')`\r\n * returns two arrays of keyboards, one per language code.\r\n * - First index = fr\r\n * - Second = en\r\n */\r\n keyboard: KeyboardAPISpec | KeyboardAPISpec[] | KeyboardAPISpec[][],\r\n options: { context: 'keyboard' } & CloudQueryOptions,\r\n error?: string,\r\n timerid: string\r\n};\r\n\r\ntype CloudLanguagesQueryResult = {\r\n languages: LanguageAPIPropertySpec[],\r\n options: { context: 'language' } & CloudQueryOptions,\r\n error?: string,\r\n keyboardid?: string,\r\n timerid: string\r\n}\r\n\r\nexport type CloudQueryResult = CloudKeyboardQueryResult | CloudLanguagesQueryResult;\r\n\r\ninterface EventMap {\r\n 'unboundregister': (registration: ReturnType) => void\r\n}\r\n\r\nexport default class CloudQueryEngine extends EventEmitter {\r\n private cloudResolutionPromises: Record>> = {};\r\n\r\n private _languageListPromise: ManagedPromise;\r\n private languageFetchStarted: boolean = false;\r\n\r\n private requestEngine: CloudRequesterInterface;\r\n private pathConfig: PathConfiguration;\r\n\r\n constructor(requestEngine: CloudRequesterInterface, pathConfig: PathConfiguration) {\r\n super();\r\n\r\n this.requestEngine = requestEngine;\r\n this.pathConfig = pathConfig;\r\n\r\n this._languageListPromise = new ManagedPromise;\r\n }\r\n\r\n public get languageListPromise(): Promise {\r\n if(!this.languageFetchStarted) {\r\n this.languageFetchStarted = true;\r\n\r\n this.keymanCloudRequest('', true).catch((error) => {\r\n // If promise is not error, then...\r\n this.languageFetchStarted = false;\r\n\r\n // We should allow retries.\r\n this._languageListPromise.reject(error);\r\n this._languageListPromise = new ManagedPromise;\r\n });\r\n }\r\n\r\n return this._languageListPromise.corePromise;\r\n }\r\n\r\n /**\r\n * Request keyboard metadata from the Keyman Cloud keyboard metadata server\r\n *\r\n * @param {string} cmd command string\r\n * @param {boolean?} byLanguage if true, context=languages, else context=keyboards\r\n * @returns {Promise<(KeyboardStub[]>} Promise of added keyboard stubs\r\n **/\r\n keymanCloudRequest(cmd: string, byLanguage: true): Promise;\r\n keymanCloudRequest(cmd: string, byLanguage: false): Promise;\r\n keymanCloudRequest(cmd: string, byLanguage?: boolean): Promise | Promise {\r\n // Some basic support toward #5044, but definitely not a full solution toward it.\r\n // Wraps the cloud API keyboard-stub request in a Promise, allowing response on network\r\n // and/or parser errors. Also detects when `register` returns due to an error case that\r\n // does not throw errors. (There are a few such \"empty\" `return` statements there.)\r\n const URL='https://api.keyman.com/cloud/4.0/'\r\n + ((arguments.length > 1) && byLanguage ? 'languages' : 'keyboards');\r\n\r\n\r\n const queryConfig = '?jsonp=keyman.register&languageidtype=bcp47&version='+Version.CURRENT.toString();\r\n\r\n const query = URL + queryConfig + cmd;\r\n\r\n let { promise, queryId } = this.requestEngine.request(query);\r\n this.cloudResolutionPromises[queryId] = promise as any;\r\n\r\n promise.finally(() => {\r\n delete this.cloudResolutionPromises[queryId];\r\n });\r\n\r\n return promise.corePromise as any;\r\n }\r\n\r\n /**\r\n * Call back from cloud for adding keyboard metadata\r\n *\r\n * This function should be published to scripts returned from the cloud;\r\n * they will expect to call it as `keyman.register`.\r\n *\r\n * @param {Object} x metadata object\r\n **/\r\n registerFromCloud = (x: CloudQueryResult) => {\r\n const promiseid = x.timerid;\r\n\r\n let result: KeyboardStub[] | LanguageAPIPropertySpec[] | Error;\r\n try {\r\n result = this._registerCore(x);\r\n } catch(err) {\r\n result = new Error(CLOUD_REGISTRATION_ERR + err);\r\n }\r\n\r\n if(!promiseid) {\r\n this.emit('unboundregister', result);\r\n return;\r\n } else {\r\n const promise: ManagedPromise | ManagedPromise = this.cloudResolutionPromises[promiseid];\r\n\r\n if(!promise) {\r\n this.emit('unboundregister', result);\r\n return;\r\n } else {\r\n try {\r\n if(result instanceof Error) {\r\n promise.reject(result as Error);\r\n } else {\r\n promise.resolve(result as any);\r\n }\r\n } finally {\r\n delete this.cloudResolutionPromises[promiseid];\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Call back from cloud for adding keyboard metadata\r\n *\r\n * @param {Object} queryResult metadata object\r\n **/\r\n private _registerCore(queryResult: CloudQueryResult): KeyboardStub[] | LanguageAPIPropertySpec[] | Error { // TODO (#5044): should return heterogenous type; allow array of stubs.\r\n const options: CloudQueryOptions = queryResult.options;\r\n\r\n // Font path defined by cloud entry\r\n let fontPath=options['fontBaseUri'];\r\n\r\n // or overridden locally, in page source\r\n if(this.pathConfig.fonts != '') {\r\n fontPath=this.pathConfig.fonts;\r\n }\r\n else {\r\n // If there's no preconfigured option for font paths, uses the cloud's returned `fontPath` in its place.\r\n this.pathConfig.updateFontPath(fontPath);\r\n }\r\n\r\n // Indicate if unable to register keyboard\r\n if(typeof(queryResult.error) == 'string') {\r\n // Currently unreachable (24 May 2021 - API returns a 404; returned 'script' does not call register)\r\n var badName='';\r\n if(typeof(queryResult.options.keyboardid) == 'string') {\r\n let keyboardId = queryResult.options.keyboardid;\r\n badName = keyboardId.substring(0,1).toUpperCase() + keyboardId.substring(1);\r\n }\r\n\r\n return new Error(MISSING_KEYBOARD(badName));\r\n }\r\n\r\n // Ignore callback unless the context is defined\r\n if(typeof(options) == 'undefined' || typeof(options['context']) == 'undefined') {\r\n return new Error(CLOUD_MALFORMED_OBJECT_ERR);\r\n }\r\n\r\n // Register each keyboard for the specified language codes\r\n let stubs: KeyboardStub[] = [];\r\n\r\n if(options.context == 'keyboard') {\r\n let i, kp=(queryResult as CloudKeyboardQueryResult).keyboard;\r\n // Process array of keyboard definitions\r\n if(Array.isArray(kp)) {\r\n for(i=0; i stub.KLC == lgCode)];\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Build 362: addKeyboardArray() link to Cloud. One or more arguments may be used\r\n *\r\n * @param x keyboard name string or keyboard metadata JSON object\r\n * @returns resolved or rejected promise with merged array of stubs.\r\n */\r\n async fetchCloudStubs(cloudList: string[]): Promise<(KeyboardStub|ErrorStub)[]> {\r\n // // Ensure keymanweb is initialized before continuing to add keyboards\r\n // if(!this.keymanweb.initialized) {\r\n // await this.deferment;\r\n // }\r\n\r\n if(cloudList.length == 0) {\r\n return Promise.resolve([]);\r\n }\r\n\r\n // Update the keyboard metadata list from keyman.com - build the command\r\n let cmd='&keyboardid=';\r\n let comma = '';\r\n for(let i=0; i {\r\n // Internal, undocumented use-case of `keyman.register`: precached keyboard loading\r\n // Other uses may trigger errors, especially if there's a type-structure mismatch.\r\n // Those errors should not be handled here; let them surface.\r\n if(Array.isArray(registration)) {\r\n registration.forEach((entry) => {\r\n this.cache.addStub(entry);\r\n });\r\n }\r\n });\r\n }\r\n\r\n addKeyboardArray(x: (string|RawKeyboardMetadata)[]): Promise<(KeyboardStub | ErrorStub)[]> {\r\n let completeStubs: KeyboardStub[] = [];\r\n let incompleteStubs: KeyboardStub[] = [];\r\n let stubs: KeyboardStub[] = [];\r\n let identifiers: string[] = [];\r\n let errorStubs: ErrorStub[] = [];\r\n\r\n // #region Parameter preprocessing: is incoming data already 'complete', or do we need to fetch the 'complete' version?\r\n\r\n for(let entry of x) {\r\n if(typeof entry == 'string' && entry.length > 0) {\r\n identifiers.push(entry);\r\n } else { // is some sort of object.\r\n if(entry['KI'] || entry['KL'] || entry['KLC'] || entry['KFont'] || entry['KOskFont']) {\r\n stubs.push(new KeyboardStub(entry as RawKeyboardStub));\r\n } else {\r\n let apiSpecEntry = entry as KeyboardAPISpec;\r\n if(typeof(apiSpecEntry.language) != \"undefined\") {\r\n console.warn(\"The 'language' property for keyboard stubs has been deprecated. Please use the 'languages' property instead.\");\r\n }\r\n apiSpecEntry.languages ||= apiSpecEntry.language;\r\n\r\n if(typeof apiSpecEntry.languages === 'undefined') {\r\n let msg = 'To use keyboard \\'' + apiSpecEntry.id + '\\', you must specify languages.';\r\n errorStubs.push(convertToErrorStub(apiSpecEntry, msg));\r\n } else if(Array.isArray(apiSpecEntry.languages)) {\r\n let splitStubs = KeyboardStub.toStubs(apiSpecEntry, this.pathConfig.keyboards, this.pathConfig.fonts);\r\n for(let stub of splitStubs) {\r\n if(stub instanceof KeyboardStub) {\r\n stubs.push(stub);\r\n } else {\r\n errorStubs.push(stub);\r\n }\r\n }\r\n } else { // is a single-language entry.\r\n const singleLangEntry = apiSpecEntry as KeyboardAPIPropertySpec & { filename: string };\r\n stubs.push(new KeyboardStub(singleLangEntry, this.pathConfig.keyboards, this.pathConfig.fonts));\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Next pass: determine which stubs are fully-formed and which are not.\r\n for(let stub of stubs) {\r\n if(stub.KF) {\r\n let err = stub.validateForCustomKeyboard();\r\n if(err) {\r\n errorStubs.push(convertToErrorStub(stub, err));\r\n } else {\r\n completeStubs.push(stub); // completes are directly added (if possible without error)\r\n }\r\n } else {\r\n incompleteStubs.push(stub); // incompletes are only used to build a query & are not merged back later.\r\n }\r\n }\r\n\r\n // #endregion\r\n\r\n // After that, request stubs that aren't fully-formed / are just requested by string.\r\n // Verify that we have at least a keyboard ID or a language code.\r\n let cloudList: CloudRequestEntry[] = [];\r\n for(let incomplete of incompleteStubs) {\r\n if(!incomplete.KI && !incomplete.KLC) {\r\n errorStubs.push(convertToErrorStub(incomplete, \"Cannot fetch keyboard information without a keyboard ID or language code.\"));\r\n continue;\r\n }\r\n\r\n // Requests not of string form never specify a specific version.\r\n // If an 'incomplete stub', we may have prefixed the keyboard ID - undo that!\r\n const querySpec = toQuerySpecs(unprefixed(incomplete.id), incomplete.langId);\r\n if(isUniqueRequest(this.cache, cloudList, querySpec)) {\r\n cloudList.push(querySpec);\r\n }\r\n }\r\n\r\n // Double-check the incoming string-based queries, too!\r\n for(let identifier of identifiers) {\r\n const pList=identifier.split('@');\r\n let lList=[''];\r\n if(pList[0].toLowerCase() == 'english') {\r\n pList[0] = 'us';\r\n }\r\n\r\n if(pList.length > 1) {\r\n lList=pList[1].split(',');\r\n }\r\n\r\n for(let j=0; j 0 && lList[j] == '') { // for j==0 => '', no language was specified.\r\n continue;\r\n }\r\n\r\n const querySpec = toQuerySpecs(pList[0], lList[j], pList[2]);\r\n if(isUniqueRequest(this.cache, cloudList, querySpec)) {\r\n cloudList.push(querySpec);\r\n }\r\n }\r\n }\r\n\r\n // Go ahead and register 'complete' stubs.\r\n completeStubs.forEach((stub) => this.cache.addStub(stub));\r\n\r\n // After that, note that we do merge non-fully-formed stubs with returned stubs that match?\r\n let resultPromise = this.cloudQueryEngine.fetchCloudStubs(cloudList.map((spec) => spec.toString()));\r\n return resultPromise.then((queryResults) => {\r\n for(let result of queryResults) {\r\n if(result instanceof KeyboardStub) {\r\n // Register the newly-complete stub.\r\n this.cache.addStub(result);\r\n completeStubs.push(result);\r\n } else {\r\n errorStubs.push(result);\r\n }\r\n }\r\n\r\n return [].concat(errorStubs).concat(completeStubs);\r\n });\r\n }\r\n\r\n async addLanguageKeyboards(languages: string[]): Promise<(ErrorStub | KeyboardStub)[]> {\r\n // Covers the 'add a keyboard by language name' angle.\r\n let errorStubs: ErrorStub[] = [];\r\n let fetchedLanguageList: LanguageAPIPropertySpec[] = [];\r\n\r\n try {\r\n fetchedLanguageList = await this.cloudQueryEngine.languageListPromise;\r\n } catch (error) {\r\n console.error(error);\r\n errorStubs.push({error: error});\r\n return errorStubs;\r\n }\r\n\r\n // Defer registering keyboards by language until the language list has been loaded\r\n const languageList = fetchedLanguageList;\r\n\r\n // Identify and register each keyboard by language name\r\n let cmd = '';\r\n for(let i=0; i {\r\n console.error(err);\r\n let stub: ErrorStub = {error: err};\r\n errorStubs.push(stub);\r\n return Promise.reject(errorStubs);\r\n });\r\n }\r\n\r\n async fetchCloudCatalog() {\r\n try {\r\n const stubs = await this.cloudQueryEngine.keymanCloudRequest('', false);\r\n stubs.forEach((stub) => this.cache.addStub(stub));\r\n return stubs;\r\n } catch(error) {\r\n return Promise.reject([{error: error}]);\r\n }\r\n }\r\n\r\n /**\r\n * Display warning if language name unavailable to add keyboard\r\n * @param {string} languageName\r\n * @returns string of Error message\r\n */\r\n private alertLanguageUnavailable(languageName: string): string {\r\n let msg = 'No keyboards are available for '+ languageName + '. '\r\n +'Does it have another language name?';\r\n\r\n // TODO: hooks for internal alerts!\r\n // this.keymanweb.util.internalAlert(msg);\r\n return msg;\r\n }\r\n}", + "import { ModelSpec } from \"@keymanapp/input-processor\";\r\n\r\nexport default class ModelManager {\r\n // Tracks registered models by ID.\r\n private registeredModels: {[id: string]: ModelSpec} = {};\r\n\r\n // Allows for easy model lookup by language code; useful when switching keyboards.\r\n languageModelMap: {[language:string]: ModelSpec} = {};\r\n\r\n modelForLanguage(lgCode: string) {\r\n return this.languageModelMap[lgCode];\r\n }\r\n\r\n // Accessible publicly as keyman.modelManager.register(model: ModelSpec)\r\n register(model: ModelSpec): void {\r\n // Forcibly lowercase the model ID before proceeding.\r\n model.id = model.id.toLowerCase();\r\n\r\n if(JSON.stringify(model) == JSON.stringify(this.registeredModels[model.id])) {\r\n // We are already registered, let's not go through and re-register\r\n // because we'll already have the correct model active\r\n return;\r\n }\r\n this.registeredModels[model.id] = model;\r\n\r\n // Register the model for each targeted language code variant.\r\n let mm = this;\r\n model.languages.forEach(function(code: string) {\r\n // Prevent null / undefined codes; they're invalid.\r\n if(!code) {\r\n console.warn(\"Null / undefined language codes are not permitted for registration.\");\r\n return;\r\n }\r\n\r\n mm.languageModelMap[code] = model;\r\n });\r\n }\r\n\r\n unregister(modelId: string): ModelSpec {\r\n let model: ModelSpec;\r\n\r\n modelId = modelId.toLowerCase();\r\n\r\n // Remove the model from the id-lookup associative array.\r\n if(this.registeredModels[modelId]) {\r\n model = this.registeredModels[modelId];\r\n delete this.registeredModels[modelId];\r\n } else {\r\n return;\r\n }\r\n\r\n // Ensure the model is deregistered for each targeted language code variant.\r\n let mm = this;\r\n model.languages.forEach(function(code: string) {\r\n if(mm.languageModelMap[code].id == modelId) {\r\n delete mm.languageModelMap[code];\r\n }\r\n });\r\n\r\n return model;\r\n }\r\n\r\n isRegistered(model: ModelSpec): boolean {\r\n return !! this.registeredModels[model.id.toLowerCase()];\r\n }\r\n}\r\n", + "/**\r\n * Function arrayFromNodeList\r\n * Scope Public\r\n * @param {Object} nl a node list, as returned from getElementsBy_____ methods.\r\n * Description Transforms a node list into an array. *\r\n * @return {Array}\r\n */\r\nexport function arrayFromNodeList(nl: NodeList|HTMLCollectionOf): HTMLElement[] {\r\n let res: (HTMLElement)[] = [];\r\n for(let i=0; i < nl.length; i++) {\r\n // Typing says we could get Node instances; it's up to use to use this method responsibly.\r\n res.push(nl[i] as HTMLElement);\r\n }\r\n return res;\r\n}", + "// Found a bit of magic formatting that allows dynamic return typing for a specified element tag!\r\nexport default function createUnselectableElement(nodeName:E) {\r\n const e = document.createElement(nodeName);\r\n\r\n e.style.userSelect=\"none\";\r\n e.style.webkitUserSelect=\"none\";\r\n e.style['MozUserSelect'] = \"none\";\r\n return e;\r\n}", + "import { DeviceSpec } from '@keymanapp/web-utils';\r\nimport { type InternalKeyboardFont as KeyboardFont } from '@keymanapp/keyboard-processor';\r\n\r\ntype FontFamilyStyleMap = {[family: string]: HTMLStyleElement};\r\n\r\nexport class StylesheetManager {\r\n private fontStyleDefinitions: { [os: string]: FontFamilyStyleMap} = {};\r\n private linkedSheets: HTMLStyleElement[] = [];\r\n private doCacheBusting: boolean;\r\n\r\n public readonly linkNode: Node;\r\n\r\n public constructor(linkNode?: Node, doCacheBusting?: boolean) {\r\n if(!linkNode) {\r\n let _ElemHead=document.getElementsByTagName('HEAD');\r\n if(_ElemHead.length > 0) {\r\n linkNode = _ElemHead[0];\r\n } else {\r\n linkNode = document.body; // Won't work on [old?] Chrome, ah well\r\n }\r\n }\r\n this.linkNode = linkNode;\r\n this.doCacheBusting = doCacheBusting || false;\r\n }\r\n\r\n linkStylesheet(sheet: HTMLStyleElement) {\r\n this.linkedSheets.push(sheet);\r\n this.linkNode.appendChild(sheet);\r\n }\r\n\r\n /**\r\n * Build a stylesheet with a font-face CSS descriptor for the embedded font appropriate\r\n * for the browser being used\r\n *\r\n * @param {Object} fd keymanweb font descriptor (internal format; should be preprocessed)\r\n * @param {string} fontPathRoot Should correspond to `this.keyman.options['fonts']`\r\n **/\r\n addStyleSheetForFont(fd: KeyboardFont, fontPathRoot: string, os?: DeviceSpec.OperatingSystem) {\r\n // Test if a valid font descriptor\r\n if(!fd) {\r\n return;\r\n }\r\n\r\n if(typeof(fd.files) == 'undefined') {\r\n return;\r\n }\r\n\r\n const fontKey = fd.family;\r\n\r\n let i, ttf='', woff='', eot='', svg='', fList=[];\r\n\r\n // TODO: 22 Aug 2014: check that font path passed from cloud is actually used!\r\n\r\n if(!os) {\r\n os = DeviceSpec.OperatingSystem.Other; // as a fallback option.\r\n }\r\n\r\n // Do not add a new font-face style sheet if already added for this font\r\n const fontStyleMap = this.fontStyleDefinitions[os] = this.fontStyleDefinitions[os] || {};\r\n\r\n if(fontStyleMap[fontKey]) {\r\n const sheet = fontStyleMap[fontKey];\r\n\r\n if(!sheet.parentNode) {\r\n this.linkStylesheet(sheet);\r\n }\r\n return;\r\n }\r\n\r\n if(typeof(fd.files) == 'string') {\r\n fList[0]=fd.files;\r\n } else {\r\n fList=fd.files;\r\n }\r\n\r\n for(i=0;i 0) ttf=fList[i];\r\n if(fList[i].toLowerCase().indexOf('.ttf') > 0) ttf=fList[i];\r\n if(fList[i].toLowerCase().indexOf('.woff') > 0) woff=fList[i];\r\n if(fList[i].toLowerCase().indexOf('.eot') > 0) eot=fList[i];\r\n if(fList[i].toLowerCase().indexOf('.svg') > 0) svg=fList[i];\r\n }\r\n\r\n // Font path qualified to support page-relative fonts (build 347)\r\n if(ttf != '' && (ttf.indexOf('/') < 0)) {\r\n ttf = fontPathRoot+ttf;\r\n }\r\n\r\n if(woff != '' && (woff.indexOf('/') < 0)) {\r\n woff = fontPathRoot+woff;\r\n }\r\n\r\n if(eot != '' && (eot.indexOf('/') < 0)) {\r\n eot = fontPathRoot+eot;\r\n }\r\n\r\n if(svg != '' && (svg.indexOf('/') < 0)) {\r\n svg = fontPathRoot+svg;\r\n }\r\n\r\n // Build the font-face definition according to the browser being used\r\n var s='@font-face {\\nfont-family:'\r\n + fd.family + ';\\nfont-style:normal;\\nfont-weight:normal;\\n';\r\n\r\n // Build the font source string according to the browser,\r\n // but return without adding the style sheet if the required font type is unavailable\r\n\r\n // Modern browsers: use WOFF, TTF and fallback finally to SVG. Don't provide EOT\r\n if(os == DeviceSpec.OperatingSystem.iOS) {\r\n if(ttf != '') {\r\n if(this.doCacheBusting) {\r\n ttf = this.cacheBust(ttf);\r\n }\r\n s=s+'src:url(\\''+ttf+'\\') format(\\'truetype\\');';\r\n } else {\r\n return null;\r\n }\r\n } else {\r\n var s0 = [];\r\n\r\n if(os == DeviceSpec.OperatingSystem.Android) {\r\n // Android 4.2 and 4.3 have bugs in their rendering for some scripts\r\n // with embedded ttf or woff. svg mostly works so is a better initial\r\n // choice on the Android browser.\r\n if(svg != '') {\r\n s0.push(\"url('\"+svg+\"') format('svg')\");\r\n }\r\n\r\n if(woff != '') {\r\n s0.push(\"url('\"+woff+\"') format('woff')\");\r\n }\r\n\r\n if(ttf != '') {\r\n s0.push(\"url('\"+ttf+\"') format('truetype')\");\r\n }\r\n } else {\r\n if(woff != '') {\r\n s0.push(\"url('\"+woff+\"') format('woff')\");\r\n }\r\n\r\n if(ttf != '') {\r\n s0.push(\"url('\"+ttf+\"') format('truetype')\");\r\n }\r\n\r\n if(svg != '') {\r\n s0.push(\"url('\"+svg+\"') format('svg')\");\r\n }\r\n }\r\n\r\n if(s0.length == 0) {\r\n return null;\r\n }\r\n\r\n s += 'src:'+s0.join(',')+';';\r\n }\r\n\r\n s=s+'\\n}\\n';\r\n\r\n const sheet = createStyleSheet(s);\r\n fontStyleMap[fontKey] = sheet;\r\n\r\n this.linkStylesheet(sheet);\r\n\r\n return sheet;\r\n }\r\n\r\n private cacheBust(uri: string) {\r\n // Our WebView version directly sets the keyboard path, and it may replace the file\r\n // after KMW has loaded. We need cache-busting to prevent the new version from\r\n // being ignored.\r\n return uri + \"?v=\" + (new Date()).getTime(); /*cache buster*/\r\n }\r\n\r\n /**\r\n * Add a reference to an external stylesheet file\r\n *\r\n * @param {string} href path to stylesheet file\r\n */\r\n linkExternalSheet(href: string): void {\r\n try {\r\n if(document.querySelector(\"link[href=\"+JSON.stringify(href)+\"]\") != null) {\r\n // We've already linked this stylesheet, don't do it again\r\n return;\r\n }\r\n } catch(e) {\r\n // We've built an invalid href, somehow?\r\n return;\r\n }\r\n\r\n const linkElement=document.createElement('link');\r\n linkElement.type='text/css';\r\n linkElement.rel='stylesheet';\r\n linkElement.href=href;\r\n\r\n this.linkStylesheet(linkElement);\r\n }\r\n\r\n public unlink(stylesheet: HTMLStyleElement) {\r\n const index = this.linkedSheets.indexOf(stylesheet);\r\n if(index > -1) {\r\n this.linkedSheets.splice(index, 1);\r\n stylesheet.parentNode.removeChild(stylesheet);\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n public unlinkAll() {\r\n for(let sheet of this.linkedSheets) {\r\n if(sheet.parentNode) {\r\n sheet.parentNode.removeChild(sheet);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Add a stylesheet to a page programmatically, for use by the OSK, the UI or the page creator\r\n *\r\n * @param {string} s style string\r\n * @return {Object} returns the object reference\r\n **/\r\nexport function createStyleSheet(styleString: string): HTMLStyleElement {\r\n var _ElemStyle: HTMLStyleElement = document.createElement<'style'>('style');\r\n\r\n _ElemStyle.type = 'text/css';\r\n _ElemStyle.appendChild(document.createTextNode(styleString));\r\n\r\n return _ElemStyle;\r\n}", + "/**\r\n * Get orientation of tablet or phone display\r\n *\r\n * @return {boolean}\r\n */\r\nexport default function landscapeView(): boolean\t{ // new for I3363 (Build 301)\r\n var orientation: number;\r\n\r\n // Assume portrait mode if orientation undefined\r\n if(typeof window.orientation != 'undefined') { // Used by iOS Safari\r\n // Else landscape for +/-90, portrait for 0, +/-180\r\n orientation = window.orientation as number;\r\n } else if(typeof window.screen.orientation != 'undefined') { // Used by Firefox, Chrome\r\n orientation = window.screen.orientation.angle;\r\n }\r\n\r\n if(orientation !== undefined) {\r\n return (Math.abs(orientation/90) == 1);\r\n } else {\r\n return false;\r\n }\r\n}", + "type DecodedCookieFieldValue = string | number | boolean;\r\n\r\ntype FilteredRecordEncoder = (value: DecodedCookieFieldValue, key: string) => string;\r\ntype FilteredRecordDecoder = (value: string, key: string) => DecodedCookieFieldValue;\r\nconst no_change = (val: string) => val as string;\r\n\r\nexport default class CookieSerializer> {\r\n readonly name: string;\r\n\r\n constructor(name: string) {\r\n this.name = name;\r\n }\r\n\r\n load(decoder?: FilteredRecordDecoder): Type {\r\n return this.loadCookie(this.name, decoder || no_change) as Type;\r\n }\r\n\r\n save(cookie: Type, encoder?: FilteredRecordEncoder) {\r\n this.saveCookie(this.name, cookie, encoder || no_change);\r\n }\r\n\r\n /**\r\n * Document cookie parsing for use by kernel, OSK, UI etc.\r\n *\r\n * @return {Object} array of names and strings\r\n */\r\n private _loadRawCookies(): Record {\r\n let v: Record = {};\r\n if(typeof(document.cookie) != 'undefined' && document.cookie != '') {\r\n let c = document.cookie.split(/;\\s*/);\r\n for(let i = 0; i < c.length; i++) {\r\n let d = c[i].split('=');\r\n if(d.length == 2) {\r\n v[d[0]] = d[1];\r\n }\r\n }\r\n }\r\n\r\n return v;\r\n }\r\n\r\n /**\r\n * Document cookie parsing for use by kernel, OSK, UI etc.\r\n *\r\n * @param {string} cookieName cookie name\r\n * @return {Object} array of variables and values\r\n */\r\n private loadCookie(cookieName: string, decoder: FilteredRecordDecoder): Record {\r\n let cookie: Record = {};\r\n let allCookies = this._loadRawCookies();\r\n const encodedCookie = allCookies[cookieName];\r\n\r\n if(encodedCookie) {\r\n let rawDecode = decodeURIComponent(encodedCookie).split(';');\r\n for(let i=0; i 1) {\r\n const [key, value] = record;\r\n // key, value\r\n cookie[key] = decoder(value, key);\r\n } else {\r\n // key, \r\n cookie[record[0]] = '';\r\n }\r\n }\r\n }\r\n return cookie;\r\n }\r\n\r\n /**\r\n * Standard cookie saving for use by kernel, OSK, UI etc.\r\n *\r\n * @param {string} cookieName name of cookie\r\n * @param {Object} cookieValueMap object with array of named arguments and values\r\n */\r\n private saveCookie(cookieName: string, cookieValueMap: Record, encoder: FilteredRecordEncoder) {\r\n let serialization='';\r\n for(let key in cookieValueMap) {\r\n serialization += key + '=' + encoder(cookieValueMap[key], key) + \";\";\r\n }\r\n\r\n let d = new Date(new Date().valueOf() + 1000 * 60 * 60 * 24 * 30).toUTCString();\r\n let cookieConfig = ' path=/; expires=' + d; //Fri, 31 Dec 2099 23:59:59 GMT;';\r\n document.cookie = `${cookieName}=${encodeURIComponent(serialization)}; ${cookieConfig}`;\r\n }\r\n}", + "/**\r\n * Function getAbsoluteX\r\n * Scope Public\r\n * @param {Object} Pobj HTML element\r\n * @return {number}\r\n * Description Returns x-coordinate of Pobj element absolute position with respect to page\r\n */\r\nexport function getAbsoluteX(Pobj: HTMLElement): number { // I1476 - Handle SELECT overlapping END\r\n var Lobj: HTMLElement\r\n\r\n if(!Pobj) {\r\n return 0;\r\n }\r\n\r\n var Lcurleft = Pobj.offsetLeft ? Pobj.offsetLeft : 0;\r\n Lobj = Pobj; \t// I2404 - Support for IFRAMEs\r\n\r\n if (Lobj.offsetParent) {\r\n while (Lobj.offsetParent) {\r\n Lobj = Lobj.offsetParent as HTMLElement;\r\n Lcurleft += Lobj.offsetLeft;\r\n }\r\n\r\n // On mobile devices, the OSK uses 'fixed' - this requires some extra offset work to handle.\r\n let Ldoc = Lobj.ownerDocument;\r\n if(Lobj.style.position == 'fixed' && Ldoc && Ldoc.scrollingElement) {\r\n Lcurleft += Ldoc.scrollingElement.scrollLeft;\r\n }\r\n }\r\n // Correct position if element is within a frame (but not if the controller is in document within that frame)\r\n // We used to reference a KMW state variable `this.keyman._MasterDocument`, but it was only ever set to `window.document`.\r\n if(Lobj && Lobj.ownerDocument && (Pobj.ownerDocument != window.document)) {\r\n var Ldoc=Lobj.ownerDocument; // I2404 - Support for IFRAMEs\r\n\r\n if(Ldoc && Ldoc.defaultView && Ldoc.defaultView.frameElement) {\r\n return Lcurleft + getAbsoluteX(Ldoc.defaultView.frameElement) - Ldoc.documentElement.scrollLeft;\r\n }\r\n }\r\n return Lcurleft;\r\n}\r\n\r\n/**\r\n * Function getAbsoluteY\r\n * Scope Public\r\n * @param {Object} Pobj HTML element\r\n * @return {number}\r\n * Description Returns y-coordinate of Pobj element absolute position with respect to page\r\n */\r\nexport function getAbsoluteY(Pobj: HTMLElement): number {\r\n var Lobj: HTMLElement\r\n\r\n if(!Pobj) {\r\n return 0;\r\n }\r\n var Lcurtop = Pobj.offsetTop ? Pobj.offsetTop : 0;\r\n Lobj = Pobj; // I2404 - Support for IFRAMEs\r\n\r\n if (Lobj.ownerDocument && Lobj instanceof Lobj.ownerDocument.defaultView.HTMLElement) {\r\n while (Lobj.offsetParent) {\r\n Lobj = Lobj.offsetParent as HTMLElement;\r\n Lcurtop += Lobj.offsetTop;\r\n }\r\n\r\n // On mobile devices, the OSK uses 'fixed' - this requires some extra offset work to handle.\r\n let Ldoc = Lobj.ownerDocument;\r\n if(Lobj.style.position == 'fixed' && Ldoc && Ldoc.scrollingElement) {\r\n Lcurtop += Ldoc.scrollingElement.scrollTop;\r\n }\r\n }\r\n\r\n // Correct position if element is within a frame (but not if the controller is in document within that frame)\r\n // We used to reference a KMW state variable `this.keyman._MasterDocument`, but it was only ever set to `window.document`.\r\n if(Lobj && Lobj.ownerDocument && (Pobj.ownerDocument != window.document)) {\r\n var Ldoc=Lobj.ownerDocument; // I2404 - Support for IFRAMEs\r\n\r\n if(Ldoc && Ldoc.defaultView && Ldoc.defaultView.frameElement) {\r\n return Lcurtop + getAbsoluteY(Ldoc.defaultView.frameElement);\r\n }\r\n }\r\n return Lcurtop;\r\n}", + "import { VariableStore, VariableStoreSerializer } from \"@keymanapp/keyboard-processor\";\r\nimport { CookieSerializer } from \"keyman/engine/dom-utils\";\r\n\r\n// While there's little reason we couldn't store all of a keyboard's store values within\r\n// the same cookie... that's not what we had implemented in the last pre-es-module version\r\n// of KeymanWeb. We're keeping this transformation _very_ straightforward.\r\n//\r\n// Also of note: there's nothing we can do to allow TS to provide type-checking of\r\n// dynamic property names; they'd have to be known at compile time to facilitate\r\n// strict type checking.\r\nclass VarStoreSerializer extends CookieSerializer {\r\n constructor(keyboardID: string, storeName: string) {\r\n super(`KeymanWeb_${keyboardID}_Option_${storeName}`);\r\n }\r\n\r\n load() {\r\n return super.load(decodeURIComponent);\r\n }\r\n\r\n save(storeMap: VariableStore) {\r\n super.save(storeMap, encodeURIComponent);\r\n }\r\n}\r\n\r\nexport class VariableStoreCookieSerializer implements VariableStoreSerializer {\r\n loadStore(keyboardID: string, storeName: string): VariableStore {\r\n const storeCookieSerializer = new VarStoreSerializer(keyboardID, storeName);\r\n return storeCookieSerializer.load();\r\n }\r\n\r\n saveStore(keyboardID: string, storeName: string, storeMap: VariableStore) {\r\n const storeCookieSerializer = new VarStoreSerializer(keyboardID, storeName);\r\n storeCookieSerializer.save(storeMap);\r\n }\r\n}", + "import {\r\n KeyboardInterface as KeyboardInterfaceBase,\r\n} from \"@keymanapp/keyboard-processor\";\r\nimport { KeyboardStub, RawKeyboardStub, toUnprefixedKeyboardId as unprefixed } from 'keyman/engine/package-cache';\r\n\r\nimport { ContextManagerBase } from './contextManagerBase.js';\r\nimport { VariableStoreCookieSerializer } from \"./variableStoreCookieSerializer.js\";\r\nimport KeymanEngine from \"./keymanEngine.js\";\r\nimport { EngineConfiguration } from \"./engineConfiguration.js\";\r\n\r\nexport default class KeyboardInterface> extends KeyboardInterfaceBase {\r\n protected readonly engine: KeymanEngine;\r\n private stubNamespacer?: (stub: RawKeyboardStub) => void;\r\n\r\n constructor(\r\n _jsGlobal: any,\r\n engine: KeymanEngine,\r\n stubNamespacer?: (stub: RawKeyboardStub) => void\r\n ) {\r\n super(_jsGlobal, engine, new VariableStoreCookieSerializer());\r\n this.engine = engine;\r\n this.stubNamespacer = stubNamespacer;\r\n }\r\n\r\n // Preserves a keyboard's ID, even if namespaced, via script tag tagging.\r\n preserveID(Pk: any /** a `Keyboard`'s `scriptObject` entry */) {\r\n var trueID;\r\n\r\n // Find the currently-executing script tag; KR is called directly from each keyboard's definition script.\r\n if(document.currentScript) {\r\n trueID = document.currentScript.id;\r\n } else {\r\n var scripts = document.getElementsByTagName('script');\r\n var currentScript = scripts[scripts.length-1];\r\n\r\n trueID = currentScript.id;\r\n }\r\n\r\n // Final check that the script tag is valid and appropriate for the loading keyboard.\r\n if(!trueID) {\r\n return;\r\n } else if(trueID.indexOf(unprefixed(Pk['KI'])) != -1) {\r\n Pk['KI'] = trueID; // Take the script's version of the ID, which may include package namespacing.\r\n } else {\r\n console.error(\"Error when registering keyboard: current SCRIPT tag's ID does not match!\");\r\n }\r\n }\r\n\r\n registerKeyboard(Pk): void {\r\n // Among other things, sets Pk as a newly-active Keyboard.\r\n super.registerKeyboard(Pk);\r\n const registeredKeyboard = this.loadedKeyboard;\r\n\r\n this.preserveID(Pk);\r\n\r\n this.engine.config.deferForInitialization.then(() => {\r\n if(!this.engine.keyboardRequisitioner.cache.isFetchingKeyboard(registeredKeyboard.id)) {\r\n // Deliberate keyboard pre-loading via direct script-tag link on the page.\r\n // Just load the keyboard and reset the harness's keyboard-receiver field.\r\n this.engine.keyboardRequisitioner.cache.addKeyboard(registeredKeyboard);\r\n this.loadedKeyboard = null;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Add the basic keyboard parameters (keyboard stub) to the array of keyboard stubs\r\n * If no language code is specified in a keyboard it cannot be registered,\r\n * and a keyboard stub must be registered before the keyboard is loaded\r\n * for the keyboard to be usable.\r\n *\r\n * @param {Object} Pstub Keyboard stub object\r\n * @return {?number} 1 if already registered, else null\r\n */\r\n registerStub(Pstub: RawKeyboardStub): number {\r\n if(this.stubNamespacer) {\r\n this.stubNamespacer(Pstub);\r\n }\r\n\r\n // This is where app-hosted KeymanWeb receives pre-formed stubs.\r\n // They're specified in the \"internal\" format (KI, KN, KLC...)\r\n // (SHIFT-CTRL-F @ repo-level for the mobile apps: `setKeymanLanguage`)\r\n // Keyman Developer may also use this method directly for its test-host page.\r\n //\r\n // It may also be used by documented legacy API:\r\n // https://help.keyman.com/DEVELOPER/ENGINE/WEB/2.0/guide/examples/manual-control\r\n // (See: referenced laokeys_load.js)\r\n //\r\n // The mobile apps typically have fully-preconfigured paths, but Developer's\r\n // test-host page does not.\r\n const pathConfig = this.engine.config.paths;\r\n const stub = new KeyboardStub(Pstub, pathConfig.keyboards, pathConfig.fonts);\r\n if(this.engine.keyboardRequisitioner?.cache.findMatchingStub(stub)) {\r\n return 1;\r\n }\r\n\r\n if(!this.engine.config.deferForInitialization.hasFinalized) {\r\n this.engine.config.deferForInitialization.then(() => this.engine.keyboardRequisitioner.cache.addStub(stub));\r\n } else {\r\n this.engine.keyboardRequisitioner.cache.addStub(stub);\r\n }\r\n\r\n return null;\r\n }\r\n\r\n insertText = (Ptext: string, PdeadKey:number): void => {\r\n this.resetContextCache();\r\n // As this function isn't provided a handle to an active outputTarget, we rely on\r\n // the context manager to resolve said issue.\r\n this.engine.contextManager.insertText(this, Ptext, PdeadKey);\r\n }\r\n\r\n // Short-hand name: necessary to do it this way due to assignment style.\r\n KT = this.insertText;\r\n}\r\n\r\n(function() {\r\n KeyboardInterface.__publishShorthandAPI();\r\n}());", + "// Enables DOM types, but just for this one module.\r\n\r\n///\r\n\r\nimport { Keyboard, KeyboardHarness, KeyboardLoaderBase, KeyboardLoadErrorBuilder, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor';\r\n\r\nimport { ManagedPromise } from '@keymanapp/web-utils';\r\n\r\nexport class DOMKeyboardLoader extends KeyboardLoaderBase {\r\n public readonly element: HTMLIFrameElement;\r\n private readonly performCacheBusting: boolean;\r\n\r\n constructor()\r\n constructor(harness: KeyboardHarness);\r\n constructor(harness: KeyboardHarness, cacheBust?: boolean)\r\n constructor(harness?: KeyboardHarness, cacheBust?: boolean) {\r\n if(harness && harness._jsGlobal != window) {\r\n // Copy the String typing over; preserve string extensions!\r\n harness._jsGlobal['String'] = window['String'];\r\n }\r\n\r\n if(!harness) {\r\n super(new KeyboardHarness(window, MinimalKeymanGlobal));\r\n } else {\r\n super(harness);\r\n }\r\n\r\n this.performCacheBusting = cacheBust || false;\r\n }\r\n\r\n protected loadKeyboardInternal(\r\n uri: string,\r\n errorBuilder: KeyboardLoadErrorBuilder,\r\n id?: string\r\n ): Promise {\r\n const promise = new ManagedPromise();\r\n\r\n if(this.performCacheBusting) {\r\n uri = this.cacheBust(uri);\r\n }\r\n\r\n try {\r\n const document = this.harness._jsGlobal.document;\r\n const script = document.createElement('script');\r\n if(id) {\r\n script.id = id;\r\n }\r\n document.head.appendChild(script);\r\n script.onerror = (err) => {\r\n promise.reject(errorBuilder.missingError(err));\r\n }\r\n script.onload = () => {\r\n if(this.harness.loadedKeyboard) {\r\n const keyboard = this.harness.loadedKeyboard;\r\n this.harness.loadedKeyboard = null;\r\n promise.resolve(keyboard);\r\n } else {\r\n promise.reject(errorBuilder.scriptError());\r\n }\r\n }\r\n\r\n // On the oldest mobile devices we support, Promise.finally may not actually exist.\r\n // Fortunately... it's not that hard of an issue to work around.\r\n // Note: es6-shim doesn't polyfill Promise.finally!\r\n promise.then(() => {\r\n // It is safe to remove the script once it has been run (https://stackoverflow.com/a/37393041)\r\n script.remove();\r\n }).catch(() => {\r\n script.remove();\r\n });\r\n\r\n // Now that EVERYTHING ELSE is ready, establish the link to the keyboard's script.\r\n script.src = uri;\r\n } catch (err) {\r\n return Promise.reject(err);\r\n }\r\n\r\n return promise.corePromise;\r\n }\r\n\r\n private cacheBust(uri: string) {\r\n // Our WebView version directly sets the keyboard path, and it may replace the file\r\n // after KMW has loaded. We need cache-busting to prevent the new version from\r\n // being ignored.\r\n return uri + \"?v=\" + (new Date()).getTime(); /*cache buster*/\r\n }\r\n}", + "import { Mock } from \"@keymanapp/keyboard-processor\";\r\n\r\nexport default class ContextWindow implements Context {\r\n // Used to limit the range of context replicated for use of keyboard rules within\r\n // the engine, as used for fat-finger prep / `Alternate` generation.\r\n public static readonly ENGINE_RULE_WINDOW: Configuration = {\r\n leftContextCodePoints: 64,\r\n rightContextCodePoints: 32\r\n };\r\n\r\n left: string;\r\n right?: string;\r\n\r\n startOfBuffer: boolean;\r\n endOfBuffer: boolean;\r\n\r\n casingForm?: CasingForm;\r\n\r\n constructor(mock: Mock, config: Configuration, layerId: string) {\r\n this.left = mock.getTextBeforeCaret();\r\n this.startOfBuffer = this.left._kmwLength() <= config.leftContextCodePoints;\r\n if(!this.startOfBuffer) {\r\n // Our custom substring version will return the last n characters if param #1 is given -n.\r\n this.left = this.left._kmwSubstr(-config.leftContextCodePoints);\r\n }\r\n\r\n this.right = mock.getTextAfterCaret();\r\n this.endOfBuffer = this.right._kmwLength() <= config.rightContextCodePoints;\r\n if(!this.endOfBuffer) {\r\n this.right = this.right._kmwSubstr(0, config.rightContextCodePoints);\r\n }\r\n\r\n this.casingForm =\r\n layerId == 'shift' ? 'initial' :\r\n layerId == 'caps' ? 'upper' :\r\n null;\r\n }\r\n\r\n public toMock(): Mock {\r\n let caretPos = this.left._kmwLength();\r\n\r\n return new Mock(this.left + (this.right || \"\"), caretPos);\r\n }\r\n}", + "import EventEmitter from \"eventemitter3\";\r\nimport { LMLayer } from \"@keymanapp/lexical-model-layer/web\";\r\nimport { OutputTarget, Transcription, Mock } from \"@keymanapp/keyboard-processor\";\r\nimport ContextWindow from \"../contextWindow.js\";\r\nimport ModelSpec from \"./modelSpec.js\"\r\n\r\n/**\r\n * Corresponds to the 'suggestionsready' LanguageProcessor event.\r\n */\r\nexport type ReadySuggestionsHandler = (prediction: ReadySuggestions) => boolean;\r\n\r\nexport type StateChangeEnum = 'active'|'configured'|'inactive';\r\n/**\r\n * Corresponds to the 'statechange' LanguageProcessor event.\r\n */\r\nexport type StateChangeHandler = (state: StateChangeEnum) => any;\r\n\r\n/**\r\n * Covers 'tryaccept' events.\r\n */\r\nexport type TryUIHandler = (source: string) => boolean;\r\n\r\nexport type InvalidateSourceEnum = 'new'|'context';\r\n\r\n/**\r\n * Corresponds to the 'invalidatesuggestions' LanguageProcessor event.\r\n */\r\nexport type InvalidateSuggestionsHandler = (source: InvalidateSourceEnum) => boolean;\r\n\r\nexport class ReadySuggestions {\r\n suggestions: Suggestion[];\r\n transcriptionID: number;\r\n\r\n constructor(suggestions: Suggestion[], id: number) {\r\n this.suggestions = suggestions;\r\n this.transcriptionID = id;\r\n }\r\n}\r\n\r\ninterface LanguageProcessorEventMap {\r\n 'suggestionsready': ReadySuggestionsHandler,\r\n 'invalidatesuggestions': InvalidateSuggestionsHandler,\r\n 'statechange': StateChangeHandler,\r\n 'tryaccept': TryUIHandler,\r\n 'tryrevert': () => void,\r\n\r\n /**\r\n * Is called synchronously once suggestion application is successful and the context has been updated.\r\n *\r\n * @param outputTarget The `OutputTarget` representation of the context the suggestion was applied to.\r\n * @returns\r\n */\r\n 'suggestionapplied': (outputTarget: OutputTarget) => boolean\r\n}\r\n\r\n/* Is more like the model configuration engine */\r\nexport default class LanguageProcessor extends EventEmitter {\r\n private lmEngine: LMLayer;\r\n private currentModel?: ModelSpec;\r\n private configuration?: Configuration;\r\n private currentPromise?: Promise;\r\n\r\n private recentTranscriptions: Transcription[] = [];\r\n\r\n private _mayPredict: boolean = true;\r\n private _mayCorrect: boolean = true;\r\n\r\n private _state: StateChangeEnum = 'inactive';\r\n\r\n private static readonly TRANSCRIPTION_BUFFER: 10 = 10;\r\n\r\n public constructor(predictiveTextWorker: Worker, supportsRightDeletions: boolean = false) {\r\n super();\r\n\r\n // Establishes KMW's platform 'capabilities', which limit the range of context a LMLayer\r\n // model may expect.\r\n let capabilities: Capabilities = {\r\n maxLeftContextCodePoints: 64,\r\n // Since the apps don't yet support right-deletions.\r\n maxRightContextCodePoints: supportsRightDeletions ? 0 : 64\r\n }\r\n\r\n if(!predictiveTextWorker) {\r\n return;\r\n }\r\n\r\n this.lmEngine = new LMLayer(capabilities, predictiveTextWorker);\r\n }\r\n\r\n public get activeModel(): ModelSpec {\r\n return this.currentModel;\r\n }\r\n\r\n public get isConfigured(): boolean {\r\n return !!this.configuration;\r\n }\r\n\r\n public get state(): StateChangeEnum {\r\n return this._state;\r\n }\r\n\r\n public unloadModel() {\r\n this.lmEngine.unloadModel();\r\n delete this.currentModel;\r\n delete this.configuration;\r\n\r\n this._state = 'inactive';\r\n this.emit('statechange', 'inactive');\r\n }\r\n\r\n loadModel(model: ModelSpec): Promise {\r\n if(!model) {\r\n throw new Error(\"Null reference not allowed.\");\r\n }\r\n\r\n let specType: 'file'|'raw' = model.path ? 'file' : 'raw';\r\n let source = specType == 'file' ? model.path : model.code;\r\n\r\n // We pre-emptively emit so that the banner's DOM elements may update synchronously.\r\n // Prevents an ugly \"flash of unstyled content\" layout issue during keyboard load\r\n // on our mobile platforms when embedded.\r\n this.currentModel = model;\r\n if(this.mayPredict) {\r\n this._state = 'active';\r\n this.emit('statechange', 'active');\r\n }\r\n\r\n return this.lmEngine.loadModel(source, specType).then((config: Configuration) => {\r\n this.configuration = config;\r\n this._state = 'configured';\r\n this.emit('statechange', 'configured');\r\n }).catch((error) => {\r\n // Does this provide enough logging information?\r\n let message: string;\r\n if(error instanceof Error) {\r\n message = error.message;\r\n } else {\r\n message = String(error);\r\n }\r\n console.error(\"Could not load model '\" + model.id + \"': \" + message);\r\n\r\n // Since the model couldn't load, immediately deactivate. Visually, it'll look\r\n // like the banner crashed shortly after load.\r\n this.currentModel = null;\r\n this._state = 'inactive';\r\n this.emit('statechange', 'inactive');\r\n });\r\n }\r\n\r\n public invalidateContext(outputTarget: OutputTarget, layerId: string): Promise {\r\n // Signal to any predictive text UI that the context has changed, invalidating recent predictions.\r\n this.emit('invalidatesuggestions', 'context');\r\n\r\n // If there's no active model, there can be no predictions.\r\n // We'll also be missing important data needed to even properly REQUEST the predictions.\r\n if(!this.currentModel || !this.configuration) {\r\n return Promise.resolve([]);\r\n }\r\n\r\n // Don't attempt predictions when disabled!\r\n // invalidateContext otherwise bypasses .predict()'s check against this.\r\n if(!this.isActive) {\r\n return Promise.resolve([]);\r\n } else if(outputTarget) {\r\n let transcription = outputTarget.buildTranscriptionFrom(outputTarget, null, false);\r\n return this.predict_internal(transcription, true, layerId);\r\n }\r\n }\r\n\r\n public wordbreak(target: OutputTarget, layerId: string): Promise {\r\n if(!this.isActive) {\r\n return null;\r\n }\r\n\r\n let context = new ContextWindow(Mock.from(target, false), this.configuration, layerId);\r\n return this.lmEngine.wordbreak(context);\r\n }\r\n\r\n public predict(transcription: Transcription, layerId: string): Promise {\r\n if(!this.isActive) {\r\n return null;\r\n }\r\n\r\n // If there's no active model, there can be no predictions.\r\n // We'll also be missing important data needed to even properly REQUEST the predictions.\r\n if(!this.currentModel || !this.configuration) {\r\n return null;\r\n }\r\n\r\n // We've already invalidated any suggestions resulting from any previously-existing Promise -\r\n // may as well officially invalidate them via event.\r\n this.emit(\"invalidatesuggestions\", 'new');\r\n\r\n return this.predict_internal(transcription, false, layerId);\r\n }\r\n\r\n /**\r\n *\r\n * @param suggestion\r\n * @param outputTarget\r\n * @param getLayerId a function that returns the current layerId,\r\n * required because layerid can be changed by PostKeystroke\r\n * @returns\r\n */\r\n public applySuggestion(suggestion: Suggestion, outputTarget: OutputTarget, getLayerId: ()=>string): Promise {\r\n if(!outputTarget) {\r\n throw \"Accepting suggestions requires a destination OutputTarget instance.\"\r\n }\r\n\r\n // Find the state of the context at the time the suggestion was generated.\r\n // This may refer to the context before an input keystroke or before application\r\n // of a predictive suggestion.\r\n let original = this.getPredictionState(suggestion.transformId);\r\n if(!original) {\r\n console.warn(\"Could not apply the Suggestion!\");\r\n return null;\r\n } else {\r\n // Apply the Suggestion!\r\n\r\n // Step 1: determine the final output text\r\n let final = Mock.from(original.preInput, false);\r\n final.apply(suggestion.transform);\r\n\r\n // Step 2: build a final, master Transform that will produce the desired results from the CURRENT state.\r\n // In embedded mode, both Android and iOS are best served by calculating this transform and applying its\r\n // values as needed for use with their IME interfaces.\r\n let transform = final.buildTransformFrom(outputTarget);\r\n outputTarget.apply(transform);\r\n\r\n // Tell the banner that a suggestion was applied, so it can call the\r\n // keyboard's PostKeystroke entry point as needed\r\n this.emit('suggestionapplied', outputTarget);\r\n\r\n // Build a 'reversion' Transcription that can be used to undo this apply() if needed,\r\n // replacing the suggestion transform with the original input text.\r\n let preApply = Mock.from(original.preInput, false);\r\n preApply.apply(original.transform);\r\n\r\n // Builds the reversion option according to the loaded lexical model's known\r\n // syntactic properties.\r\n let suggestionContext = new ContextWindow(original.preInput, this.configuration, getLayerId());\r\n\r\n // We must accept the Suggestion from its original context, which was before\r\n // `original.transform` was applied.\r\n let reversionPromise: Promise = this.lmEngine.acceptSuggestion(suggestion, suggestionContext, original.transform);\r\n\r\n // Also, request new prediction set based on the resulting context.\r\n reversionPromise = reversionPromise.then((reversion) => {\r\n let mappedReversion: Reversion = {\r\n // By mapping back to the original Transcription that generated the Suggestion,\r\n // the input will be automatically rewound to the preInput state.\r\n transform: original.transform,\r\n // The ID part is critical; the reversion can't be applied without it.\r\n transformId: -original.token, // reversions use the additive inverse.\r\n displayAs: reversion.displayAs, // The real reason we needed to call the LMLayer.\r\n id: reversion.id,\r\n tag: reversion.tag\r\n }\r\n // // If using the version from lm-layer:\r\n // let mappedReversion = reversion;\r\n // mappedReversion.transformId = reversionTranscription.token;\r\n this.predictFromTarget(outputTarget, getLayerId());\r\n return mappedReversion;\r\n });\r\n\r\n return reversionPromise;\r\n }\r\n }\r\n\r\n public applyReversion(reversion: Reversion, outputTarget: OutputTarget) {\r\n if(!outputTarget) {\r\n throw \"Accepting suggestions requires a destination OutputTarget instance.\"\r\n }\r\n\r\n // Find the state of the context at the time the suggestion was generated.\r\n // This may refer to the context before an input keystroke or before application\r\n // of a predictive suggestion.\r\n //\r\n // Reversions use the additive inverse of the id token of the Transcription being\r\n // reverted to.\r\n let original = this.getPredictionState(-reversion.transformId);\r\n if(!original) {\r\n console.warn(\"Could not apply the Suggestion!\");\r\n return;\r\n }\r\n\r\n // Apply the Reversion!\r\n\r\n // Step 1: determine the final output text\r\n let final = Mock.from(original.preInput, false);\r\n final.apply(reversion.transform); // Should match original.transform, actually. (See applySuggestion)\r\n\r\n // Step 2: build a final, master Transform that will produce the desired results from the CURRENT state.\r\n // In embedded mode, both Android and iOS are best served by calculating this transform and applying its\r\n // values as needed for use with their IME interfaces.\r\n let transform = final.buildTransformFrom(outputTarget);\r\n outputTarget.apply(transform);\r\n\r\n // The reason we need to preserve the additive-inverse 'transformId' property on Reversions.\r\n let promise = this.lmEngine.revertSuggestion(reversion, new ContextWindow(original.preInput, this.configuration, null))\r\n\r\n return promise.then((suggestions: Suggestion[]) => {\r\n let result = new ReadySuggestions(suggestions, transform.id);\r\n this.emit(\"suggestionsready\", result);\r\n this.currentPromise = null;\r\n\r\n return suggestions;\r\n });\r\n }\r\n\r\n public predictFromTarget(outputTarget: OutputTarget, layerId: string): Promise {\r\n if(!outputTarget) {\r\n return null;\r\n }\r\n\r\n let transcription = outputTarget.buildTranscriptionFrom(outputTarget, null, false);\r\n return this.predict(transcription, layerId);\r\n }\r\n\r\n /**\r\n * Called internally to do actual predictions after any relevant \"invalidatesuggestions\" events\r\n * have been raised.\r\n * @param transcription The triggering transcription (if it exists)\r\n */\r\n private predict_internal(transcription: Transcription, resetContext: boolean, layerId: string): Promise {\r\n if(!transcription) {\r\n return null;\r\n }\r\n\r\n let context = new ContextWindow(transcription.preInput, this.configuration, layerId);\r\n this.recordTranscription(transcription);\r\n\r\n if(resetContext) {\r\n this.lmEngine.resetContext(context);\r\n }\r\n\r\n let alternates = transcription.alternates;\r\n if(!alternates || alternates.length == 0) {\r\n alternates = [{\r\n sample: transcription.transform,\r\n p: 1.0\r\n }];\r\n }\r\n\r\n let transform = transcription.transform;\r\n var promise = this.currentPromise = this.lmEngine.predict(alternates, context);\r\n\r\n return promise.then((suggestions: Suggestion[]) => {\r\n if(promise == this.currentPromise) {\r\n let result = new ReadySuggestions(suggestions, transform.id);\r\n this.emit(\"suggestionsready\", result);\r\n this.currentPromise = null;\r\n }\r\n\r\n return suggestions;\r\n });\r\n }\r\n\r\n private recordTranscription(transcription: Transcription) {\r\n this.recentTranscriptions.push(transcription);\r\n\r\n if(this.recentTranscriptions.length > LanguageProcessor.TRANSCRIPTION_BUFFER) {\r\n this.recentTranscriptions.splice(0, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Retrieves the context and output state of KMW immediately before the prediction with\r\n * token `id` was generated. Must correspond to a 'recent' one, as only so many are stored\r\n * in `ModelManager`'s history buffer.\r\n * @param id A unique identifier corresponding to a recent `Transcription`.\r\n * @returns The matching `Transcription`, or `null` none is found.\r\n */\r\n public getPredictionState(id: number): Transcription {\r\n let match = this.recentTranscriptions.filter((t: Transcription) => {\r\n return t.token == id;\r\n })\r\n\r\n return match.length == 0 ? null : match[0];\r\n }\r\n\r\n public shutdown() {\r\n this.lmEngine.shutdown();\r\n }\r\n\r\n public get isActive(): boolean {\r\n if(!this.canEnable()) {\r\n this._mayPredict = false;\r\n return false;\r\n }\r\n return (this.activeModel || false) && this._mayPredict;\r\n }\r\n\r\n canEnable(): boolean {\r\n // Is not initialized if there is no worker.\r\n return !!this.lmEngine;\r\n }\r\n\r\n public get mayPredict() {\r\n return this._mayPredict;\r\n }\r\n\r\n public set mayPredict(flag: boolean) {\r\n if(!this.canEnable()) {\r\n return;\r\n }\r\n\r\n let oldVal = this._mayPredict;\r\n this._mayPredict = flag;\r\n\r\n if(oldVal != flag) {\r\n // If there's no model to be activated and we've reached this point,\r\n // the banner should remain inactive, as it already was.\r\n // If it there was one and we've reached this point, we're globally\r\n // deactivating, so we're fine.\r\n if(this.activeModel) {\r\n // If someone toggles predictions on and off without changing the model, it is possible\r\n // that the model is already configured!\r\n let state: StateChangeEnum = flag ? 'active' : 'inactive';\r\n\r\n // We always signal the 'active' state here, even if 'configured', b/c of an\r\n // anti-banner-flicker optimization in the Android app.\r\n this._state = state;\r\n this.emit('statechange', state);\r\n\r\n if(this.isConfigured) {\r\n this._state = 'configured';\r\n this.emit('statechange', 'configured');\r\n }\r\n }\r\n }\r\n }\r\n\r\n public get mayCorrect() {\r\n return this._mayCorrect;\r\n }\r\n\r\n public set mayCorrect(flag: boolean) {\r\n this._mayCorrect = flag;\r\n }\r\n\r\n public get wordbreaksAfterSuggestions() {\r\n return this.configuration.wordbreaksAfterSuggestions;\r\n }\r\n\r\n public tryAcceptSuggestion(source: string): boolean {\r\n // If and when we do auto-correct, the suggestion is to pass this object to the event and\r\n // denote any mutations to the contained value.\r\n //let returnObj = {shouldSwallow: false};\r\n this.emit('tryaccept', source);\r\n\r\n return false;\r\n }\r\n\r\n public tryRevertSuggestion(): boolean {\r\n // If and when we do auto-revert, the suggestion is to pass this object to the event and\r\n // denote any mutations to the contained value.\r\n //let returnObj = {shouldSwallow: false};\r\n this.emit('tryrevert');\r\n\r\n return false;\r\n }\r\n}", + "/*\r\n * Copyright (c) 2018 National Research Council Canada (author: Eddie A. Santos)\r\n * Copyright (c) 2018 SIL International\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy of\r\n * this software and associated documentation files (the \"Software\"), to deal in\r\n * the Software without restriction, including without limitation the rights to\r\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r\n * the Software, and to permit persons to whom the Software is furnished to do so,\r\n * subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r\n * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r\n * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r\n * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n */\r\n\r\n/// \r\n\r\ntype Resolve = (value?: T | PromiseLike) => void;\r\ntype Reject = (reason?: any) => void;\r\ninterface PromiseCallbacks {\r\n resolve: Resolve;\r\n reject: Reject;\r\n}\r\n\r\n\r\n/**\r\n * Associate tokens with promises.\r\n *\r\n * First, .make() a promise -- associate a token with resolve/reject callbacks.\r\n *\r\n * You can either .keep() a promise -- resolve() and forget it;\r\n * Or you may also .break() a promise -- reject() and forget it.\r\n *\r\n * is the type of resolved value (value yielded successfully by promise).\r\n */\r\nexport default class PromiseStore {\r\n // IE11 offers partial support for new Map().\r\n // Assume only .get(), .set(), .has(), .delete(), and .size work.\r\n // See: http://kangax.github.io/compat-table/es6/#test-Map\r\n private _promises: Map>;\r\n constructor() {\r\n this._promises = new Map();\r\n }\r\n /**\r\n * How many promises are currently being tracked?\r\n */\r\n get length(): number {\r\n return this._promises.size;\r\n }\r\n /**\r\n * Associate a token with its respective resolve and reject callbacks.\r\n */\r\n make(token: Token, resolve: Resolve, reject: Reject): void {\r\n if (this._promises.has(token)) {\r\n return reject(`Existing request with token ${token}`);\r\n }\r\n this._promises.set(token, { reject, resolve });\r\n }\r\n /**\r\n * Resolve the promise associated with a token (with a value!).\r\n * Once the promise is resolved, the token is removed..\r\n */\r\n keep(token: Token, value: T) {\r\n let callbacks = this._promises.get(token);\r\n if (!callbacks) {\r\n throw new Error(`No promise associated with token: ${token}`);\r\n }\r\n let accept = callbacks.resolve;\r\n this._promises.delete(token);\r\n return accept(value);\r\n }\r\n /**\r\n * Instantly reject and forget a promise associated with the token.\r\n */\r\n break(token: Token, reason?: any): void {\r\n let callbacks = this._promises.get(token);\r\n if (!callbacks) {\r\n throw new Error(`No promise associated with token: ${token}`);\r\n }\r\n this._promises.delete(token);\r\n callbacks.reject(reason);\r\n }\r\n}", + "/*\r\n * Copyright (c) 2018 National Research Council Canada (author: Eddie A. Santos)\r\n * Copyright (c) 2018 SIL International\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy of\r\n * this software and associated documentation files (the \"Software\"), to deal in\r\n * the Software without restriction, including without limitation the rights to\r\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r\n * the Software, and to permit persons to whom the Software is furnished to do so,\r\n * subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r\n * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r\n * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r\n * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n */\r\n\r\nimport PromiseStore from \"./promise-store.js\";\r\n\r\n/// \r\n/// \r\n\r\n/**\r\n * Top-level interface to the Language Modelling layer, or \"LMLayer\" for short.\r\n *\r\n * The Language Modelling layer provides a way for keyboards to offer prediction and\r\n * correction functionalities. The LMLayer proper runs within a Web Worker, however,\r\n * this class is intended to run in the main thread, and automatically spawn a Web\r\n * Worker, capable of offering predictions.\r\n *\r\n * Since the Worker runs in a different thread, the public methods of this class are\r\n * asynchronous. Methods of note include:\r\n *\r\n * - #loadModel() -- loads a specified model file\r\n * - #predict() -- ask the LMLayer to offer suggestions (predictions or corrections) for\r\n * the input event\r\n * - #unloadModel() -- unloads the LMLayer's currently loaded model, preparing it to\r\n * receive (load) a new model\r\n *\r\n * The top-level LMLayer will automatically starts up its own Web Worker.\r\n */\r\n\r\nexport default class LMLayer {\r\n /**\r\n * The underlying worker instance. By default, this is the LMLayerWorker.\r\n */\r\n private _worker: Worker;\r\n /** Call this when the LMLayer has sent us the 'ready' message! */\r\n private _declareLMLayerReady: (conf: Configuration) => void;\r\n private _predictPromises: PromiseStore;\r\n private _wordbreakPromises: PromiseStore;\r\n private _acceptPromises: PromiseStore;\r\n private _revertPromises: PromiseStore;\r\n private _nextToken: number;\r\n private capabilities: Capabilities;\r\n\r\n /**\r\n * Construct the top-level LMLayer interface. This also starts the underlying Worker.\r\n *\r\n * @param uri URI of the underlying LMLayer worker code. This will usually be a blob:\r\n * or file: URI. If uri is not provided, this will start the default Worker.\r\n */\r\n constructor(capabilities: Capabilities, worker: Worker, testMode?: boolean) {\r\n // Either use the given worker, or instantiate the default worker.\r\n this._worker = worker;\r\n this._worker.onmessage = this.onMessage.bind(this)\r\n this._declareLMLayerReady = null;\r\n this._predictPromises = new PromiseStore();\r\n this._wordbreakPromises = new PromiseStore();\r\n this._acceptPromises = new PromiseStore();\r\n this._revertPromises = new PromiseStore();\r\n this._nextToken = Number.MIN_SAFE_INTEGER;\r\n\r\n this.sendConfig(capabilities, !!testMode);\r\n }\r\n\r\n /**\r\n * Initializes the LMLayer worker with the host platform's capability set.\r\n *\r\n * @param capabilities The host platform's capability spec - a model cannot assume access to more context\r\n * than specified by this parameter.\r\n */\r\n private sendConfig(capabilities: Capabilities, testMode: boolean) {\r\n this._worker.postMessage({\r\n message: 'config',\r\n capabilities: capabilities,\r\n testMode: testMode\r\n });\r\n }\r\n\r\n /**\r\n * Initializes the LMLayer worker with a path to the desired model file.\r\n */\r\n loadModel(modelSource: string, loadType: 'file' | 'raw' = 'file'): Promise {\r\n return new Promise((resolve, _reject) => {\r\n // Sets up so the promise is resolved in the onMessage() callback, when it receives\r\n // the 'ready' message.\r\n this._declareLMLayerReady = resolve;\r\n\r\n let modelSourceSpec: any = {\r\n type: loadType\r\n };\r\n\r\n if(loadType == 'file') {\r\n modelSourceSpec.file = modelSource;\r\n } else {\r\n modelSourceSpec.code = modelSource;\r\n }\r\n\r\n this._worker.postMessage({\r\n message: 'load',\r\n source: modelSourceSpec\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Unloads the previously-active model from memory, resetting the LMLayer to prep\r\n * for transition to use of a new model.\r\n */\r\n public unloadModel() {\r\n this._worker.postMessage({\r\n message: 'unload'\r\n });\r\n }\r\n\r\n predict(transform: Transform | Distribution, context: Context): Promise {\r\n let token = this._nextToken++;\r\n return new Promise((resolve, reject) => {\r\n this._predictPromises.make(token, resolve, reject);\r\n this._worker.postMessage({\r\n message: 'predict',\r\n token: token,\r\n transform: transform,\r\n context: context,\r\n });\r\n });\r\n }\r\n\r\n wordbreak(context: Context): Promise {\r\n let token = this._nextToken++;\r\n return new Promise((resolve, reject) => {\r\n this._wordbreakPromises.make(token, resolve, reject);\r\n this._worker.postMessage({\r\n message: 'wordbreak',\r\n token: token,\r\n context: context\r\n })\r\n });\r\n }\r\n\r\n acceptSuggestion(suggestion: Suggestion, context: Context, postTransform: Transform): Promise {\r\n let token = this._nextToken++;\r\n return new Promise((resolve, reject) => {\r\n this._acceptPromises.make(token, resolve, reject);\r\n this._worker.postMessage({\r\n message: 'accept',\r\n token: token,\r\n suggestion: suggestion,\r\n context: context,\r\n postTransform: postTransform\r\n });\r\n });\r\n }\r\n\r\n revertSuggestion(reversion: Reversion, context: Context): Promise {\r\n let token = this._nextToken++;\r\n return new Promise((resolve, reject) => {\r\n this._revertPromises.make(token, resolve, reject);\r\n this._worker.postMessage({\r\n message: 'revert',\r\n token: token,\r\n reversion: reversion,\r\n context: context\r\n })\r\n });\r\n }\r\n\r\n resetContext(context: Context) {\r\n this._worker.postMessage({\r\n message: 'reset-context',\r\n context: context\r\n });\r\n }\r\n\r\n // TODO: asynchronous close() method.\r\n // Worker code must recognize message and call self.close().\r\n\r\n private onMessage(event: MessageEvent): void {\r\n let payload: OutgoingMessage = event.data;\r\n if (payload.message === 'error') {\r\n console.error(payload.log);\r\n if(payload.error) {\r\n console.error(payload.error);\r\n }\r\n }\r\n else if (payload.message === 'ready') {\r\n this._declareLMLayerReady(event.data.configuration);\r\n } else if (payload.message === 'suggestions') {\r\n this._predictPromises.keep(payload.token, payload.suggestions);\r\n } else if (payload.message === 'currentword') {\r\n this._wordbreakPromises.keep(payload.token, payload.word);\r\n } else if (payload.message === 'postaccept') {\r\n this._acceptPromises.keep(payload.token, payload.reversion);\r\n } else if (payload.message === 'postrevert') {\r\n this._revertPromises.keep(payload.token, payload.suggestions);\r\n } else {\r\n // This branch should never execute, but just in case...\r\n //@ts-ignore\r\n throw new Error(`Message not implemented: ${payload.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Clears out any computational resources in use by the LMLayer, including shutting\r\n * down any internal WebWorkers.\r\n */\r\n public shutdown() {\r\n this._worker.terminate();\r\n }\r\n}\r\n", + "/**\r\n * Given a function, this utility returns the source code within it, as a string.\r\n * This is intended to unwrap the \"wrapped\" source code created in the LMLayerWorker\r\n * build process.\r\n *\r\n * @param fn The function whose body will be returned.\r\n */\r\nexport default function unwrap(encodedSrc: string): string {\r\n // There used to be more to this, but now it's a pretty simple passthrough!\r\n return encodedSrc;\r\n}", + "\n// Autogenerated code. Do not modify!\n// --START:LMLayerWorkerCode--\n\nexport var LMLayerWorkerCode = \"\\\"use strict\\\";var ae=Object.defineProperty;var v=function(r,e){return ae(r,\\\"name\\\",{value:e,configurable:!0})};/*! https://mths.be/codepointat v0.2.0 by @mathias */String.prototype.codePointAt||function(){\\\"use strict\\\";var r=function(){try{var t={},n=Object.defineProperty,i=n(t,t,t)&&n}catch(a){}return i}(),e=v(function(t){if(this==null)throw TypeError();var n=String(this),i=n.length,a=t?Number(t):0;if(a!=a&&(a=0),!(a<0||a>=i)){var u=n.charCodeAt(a),o;return u>=55296&&u<=56319&&i>a+1&&(o=n.charCodeAt(a+1),o>=56320&&o<=57343)?(u-55296)*1024+o-56320+65536:u}},\\\"codePointAt\\\");r?r(String.prototype,\\\"codePointAt\\\",{value:e,configurable:!0,writable:!0}):String.prototype.codePointAt=e}(),Array.prototype.fill||Object.defineProperty(Array.prototype,\\\"fill\\\",{value:function(r){if(this==null)throw new TypeError(\\\"this is null or not defined\\\");for(var e=Object(this),t=e.length>>>0,n=arguments[1],i=n>>0,a=i<0?Math.max(t+i,0):Math.min(i,t),u=arguments[2],o=u===void 0?t:u>>0,l=o<0?Math.max(t+o,0):Math.min(o,t);a>>0;if(typeof r!=\\\"function\\\")throw new TypeError(\\\"predicate must be a function\\\");for(var n=arguments[1],i=0;i0?1:-1)*Math.floor(Math.abs(u))},\\\"toInteger\\\"),n=Math.pow(2,53)-1,i=v(function(a){var u=t(a);return Math.min(Math.max(u,0),n)},\\\"toLength\\\");return v(function(u){var o=this,l=Object(u);if(u==null)throw new TypeError(\\\"Array.from requires an array-like object - not null or undefined\\\");var s=arguments.length>1?arguments[1]:void 0,f;if(typeof s!=\\\"undefined\\\"){if(!e(s))throw new TypeError(\\\"Array.from: when provided, the second argument must be a function\\\");arguments.length>2&&(f=arguments[2])}for(var c=i(l.length),d=e(o)?Object(new o(c)):new Array(c),p=0,g;p=0&&typeof m.length==\\\"number\\\"&&m.length>=0){var O=Math.floor(h.length),k=Math.floor(m.length),A=0;for(h.length=O+k;A=0&&this._nextIndex=0))return(I=new k(0)).length=0,I;for(A=Math.floor(h.length),(I=new k(A)).length=A;E0&&g[g.length-1])&&(S[0]===6||S[0]===2)){c=0;continue}if(S[0]===3&&(!g||S[1]>g[0]&&S[1]=s.length&&(s=void 0),{value:s&&s[d++],done:!s}}};throw new TypeError(f?\\\"Object is not iterable.\\\":\\\"Symbol.iterator is not defined.\\\")},\\\"__values7\\\"),u=v(function(s,f){var c=typeof Symbol==\\\"function\\\"&&s[Symbol.iterator];if(!c)return s;var d=c.call(s),p,g=[],w;try{for(;(f===void 0||f-- >0)&&!(p=d.next()).done;)g.push(p.value)}catch(b){w={error:b}}finally{try{p&&!p.done&&(c=d.return)&&c.call(d)}finally{if(w)throw w.error}}return g},\\\"__read3\\\"),o(\\\"__extends\\\",t),o(\\\"__assign\\\",n),o(\\\"__generator\\\",i),o(\\\"__values\\\",a),o(\\\"__read\\\",u)})}}),build_exports={};__export(build_exports,{tslib:function(){return tslib_1}}),__reExport(build_exports,__toESM(require_tslib(),1));var tslib_1=__toESM(require_tslib(),1),DeviceSpec=function(){function r(e,t,n,i){switch(e.toLowerCase()){case r.Browser.Chrome:case r.Browser.Edge:case r.Browser.Firefox:case r.Browser.Native:case r.Browser.Opera:case r.Browser.Safari:this.browser=e.toLowerCase();break;default:this.browser=r.Browser.Other}switch(t.toLowerCase()){case r.FormFactor.Desktop:case r.FormFactor.Phone:case r.FormFactor.Tablet:this.formFactor=t.toLowerCase();break;default:throw\\\"Invalid form factor specified for device: \\\"+t}switch(n.toLowerCase()){case r.OperatingSystem.Windows.toLowerCase():case r.OperatingSystem.macOS.toLowerCase():case r.OperatingSystem.Linux.toLowerCase():case r.OperatingSystem.Android.toLowerCase():case r.OperatingSystem.iOS.toLowerCase():this.OS=n.toLowerCase();break;default:this.OS=r.OperatingSystem.Other}this.touchable=i}return v(r,\\\"DeviceSpec2\\\"),r}();(function(r){var e;(function(i){i.Chrome=\\\"chrome\\\",i.Edge=\\\"edge\\\",i.Firefox=\\\"firefox\\\",i.Native=\\\"native\\\",i.Opera=\\\"opera\\\",i.Safari=\\\"safari\\\",i.Other=\\\"other\\\"})(e=r.Browser||(r.Browser={}));var t;(function(i){i.Windows=\\\"windows\\\",i.macOS=\\\"macosx\\\",i.Linux=\\\"linux\\\",i.Android=\\\"android\\\",i.iOS=\\\"ios\\\",i.Other=\\\"other\\\"})(t=r.OperatingSystem||(r.OperatingSystem={}));var n;(function(i){i.Desktop=\\\"desktop\\\",i.Phone=\\\"phone\\\",i.Tablet=\\\"tablet\\\"})(n=r.FormFactor||(r.FormFactor={}))})(DeviceSpec||(DeviceSpec={}));function extendString(){String.kmwFromCharCode=function(r){var e=[],t;for(t=0;t1114111||Math.floor(n)!==n)throw new RangeError(\\\"Invalid code point \\\"+n);n<65536?e.push(n):(n-=65536,e.push((n>>10)+55296),e.push(n%1024+56320))}return String.fromCharCode.apply(void 0,e)},String.prototype.kmwCharCodeAt=function(r){var e=String(this),t=0;if(r<0||r>=e.length)return NaN;for(var n=0;n=55296&&i<=56319&&e.length>t+1){var a=e.charCodeAt(t+1);if(a>=56320&&a<=57343)return(i-55296<<10)+(a-56320)+65536}return i},String.prototype.kmwIndexOf=function(r,e){var t=String(this),n=t.indexOf(r,e);if(n<0)return n;for(var i=0,a=0;a!==null&&ae){var a=r;r=e,e=a}n=t.kmwCodePointToCodeUnit(r),i=t.kmwCodePointToCodeUnit(e)}return(isNaN(n)||n===null)&&(n=0),(isNaN(i)||i===null)&&(i=t.length),t.substring(n,i)},String.prototype.kmwNextChar=function(r){var e=String(this);if(r===null||r<0||r>=e.length-1)return null;var t=e.charCodeAt(r);if(t>=55296&&t<=56319&&e.length>r+1){var n=e.charCodeAt(r+1);if(n>=56320&&n<=57343)return r==e.length-2?null:r+2}return r+1},String.prototype.kmwPrevChar=function(r){var e=String(this);if(r==null||r<=0||r>e.length)return null;var t=e.charCodeAt(r-1);if(t>=56320&&t<=57343&&r>1){var n=e.charCodeAt(r-2);if(n>=55296&&n<=56319)return r-2}return r-1},String.prototype.kmwCodePointToCodeUnit=function(r){if(r===null)return null;var e=String(this),t=0;if(r<0){t=e.length;for(var n=0;n>r;n--)t=e.kmwPrevChar(t);return t}if(r==e.kmwLength())return e.length;for(var n=0;n=0?e.kmwSubstr(r,1):\\\"\\\"},String.prototype.kmwBMPNextChar=function(r){var e=String(this);return r<0||r>=e.length-1?null:r+1},String.prototype.kmwBMPPrevChar=function(r){var e=String(this);return r<=0||r>e.length?null:r-1},String.prototype.kmwBMPCodePointToCodeUnit=function(r){return r},String.prototype.kmwBMPCodeUnitToCodePoint=function(r){return r},String.prototype.kmwBMPLength=function(){var r=String(this);return r.length},String.prototype.kmwBMPSubstr=function(r,e){var t=String(this);return r>-1?t.substr(r,e):t.substr(t.length+r,-r)},String.kmwEnableSupplementaryPlane=function(r){var e=String.prototype;String._kmwFromCharCode=r?String.kmwFromCharCode:String.fromCharCode,e._kmwCharAt=r?e.kmwCharAt:e.charAt,e._kmwCharCodeAt=r?e.kmwCharCodeAt:e.charCodeAt,e._kmwIndexOf=r?e.kmwIndexOf:e.indexOf,e._kmwLastIndexOf=r?e.kmwLastIndexOf:e.lastIndexOf,e._kmwSlice=r?e.kmwSlice:e.slice,e._kmwSubstring=r?e.kmwSubstring:e.substring,e._kmwSubstr=r?e.kmwSubstr:e.kmwBMPSubstr,e._kmwLength=r?e.kmwLength:e.kmwBMPLength,e._kmwNextChar=r?e.kmwNextChar:e.kmwBMPNextChar,e._kmwPrevChar=r?e.kmwPrevChar:e.kmwBMPPrevChar,e._kmwCodePointToCodeUnit=r?e.kmwCodePointToCodeUnit:e.kmwBMPCodePointToCodeUnit,e._kmwCodeUnitToCodePoint=r?e.kmwCodeUnitToCodePoint:e.kmwBMPCodeUnitToCodePoint},String._kmwFromCharCode||String.kmwEnableSupplementaryPlane(!1)}v(extendString,\\\"extendString\\\"),extendString();var models_exports={};__export(models_exports,{DummyModel:function(){return dummy_model_default},PriorityQueue:function(){return priority_queue_default},QuoteBehavior:function(){return quote_behavior_default},SENTINEL_CODE_UNIT:function(){return SENTINEL_CODE_UNIT},TrieModel:function(){return trie_model_default},applyTransform:function(){return applyTransform},buildMergedTransform:function(){return buildMergedTransform},defaultApplyCasing:function(){return defaultApplyCasing},getLastPreCaretToken:function(){return getLastPreCaretToken},isHighSurrogate:function(){return isHighSurrogate},isLowSurrogate:function(){return isLowSurrogate},isSentinel:function(){return isSentinel},tokenize:function(){return tokenize},transformToSuggestion:function(){return transformToSuggestion},wordbreak:function(){return wordbreak}}),extendString();var SENTINEL_CODE_UNIT=\\\"\\\\uFDD0\\\";function applyTransform(r,e){var t,n,i=e.left||\\\"\\\",a=i.kmwLength(),u=a=55296&&r<=56319}v(isHighSurrogate,\\\"isHighSurrogate\\\");function isLowSurrogate(r){return typeof r==\\\"string\\\"&&(r=r.charCodeAt(0)),r>=56320&&r<=57343}v(isLowSurrogate,\\\"isLowSurrogate\\\");function isSentinel(r){return r==SENTINEL_CODE_UNIT}v(isSentinel,\\\"isSentinel\\\");function transformToSuggestion(r,e){var t={transform:r,transformId:r.id,displayAs:r.insert};return(e===0||e)&&(t.p=e),t}v(transformToSuggestion,\\\"transformToSuggestion\\\");function defaultApplyCasing(r,e){switch(r){case\\\"lower\\\":return e.toLowerCase();case\\\"upper\\\":return e.toUpperCase();case\\\"initial\\\":var t=1;return e.length>1&&isHighSurrogate(e.charAt(0))&&isLowSurrogate(e.charCodeAt(1))&&(t=2),e.substring(0,t).toUpperCase().concat(e.substring(t))}}v(defaultApplyCasing,\\\"defaultApplyCasing\\\");var PriorityQueue=function(){function r(e,t){t===void 0&&(t=[]),this.comparator=e,this.heap=Array.from(t),this.heapify()}return v(r,\\\"PriorityQueue2\\\"),r.leftChildIndex=function(e){return e*2+1},r.rightChildIndex=function(e){return e*2+2},r.parentIndex=function(e){return Math.floor((e-1)/2)},r.prototype.heapify=function(e,t){if(e==null||t==null){this.heapify(0,this.count-1);return}for(var n=[],i=-1,a=t;a>=e;a--){var u=r.parentIndex(a);this.siftDown(a)&&u0;){var o=n.shift(),u=r.parentIndex(o);this.siftDown(o)&&u>=0&&i!=u&&(n.push(u),i=u)}},Object.defineProperty(r.prototype,\\\"count\\\",{get:function(){return this.heap.length},enumerable:!1,configurable:!0}),r.prototype.peek=function(){return this.heap[0]},r.prototype.enqueue=function(e){var t=this.heap.length;this.heap.push(e);for(var n=r.parentIndex,i=n(t);t!==0&&this.comparator(this.heap[t],this.heap[i])<0;){var a=this.heap[t];this.heap[t]=this.heap[i],this.heap[i]=a,t=i,i=n(t)}},r.prototype.enqueueAll=function(e){if(e.length!=0){var t=this.count;this.heap=this.heap.concat(e);var n=r.parentIndex(t);this.heapify(n>=0?n:0,r.parentIndex(this.count-1))}},r.prototype.dequeue=function(){if(this.count!=0){var e=this.heap[0],t=this.heap.pop();return this.heap.length>0&&(this.heap[0]=t,this.siftDown(0)),e}},r.prototype.siftDown=function(e){var t=r.leftChildIndex(e),n=r.rightChildIndex(e),i=e;if(t0&&(i=t[t.length-1]),t.length>1){var a=t[t.length-2];if(a.end==i.start&&i.text==\\\"'\\\"){var u={text:a.text+i.text,start:a.start,end:i.end,length:a.length+i.length};t.pop(),t.pop(),t.push(u),i=u}}var o={left:t.map(function(c){return c.text}),right:n.map(function(c){return c.text}),caretSplitsToken:!1};if(t.length>0&&n.length>0){var l=n[0],s=i.end!=e.left.length,f=l.start!=0;if(s||f)return o;r(i.text+l.text).length==1&&(o.caretSplitsToken=!0)}return o}v(tokenize,\\\"tokenize\\\");function getLastPreCaretToken(r,e){var t=tokenize(r,e);return t.left.length>0?t.left.pop():\\\"\\\"}v(getLastPreCaretToken,\\\"getLastPreCaretToken\\\");function wordbreak(r,e){return getLastPreCaretToken(r,e)}v(wordbreak,\\\"wordbreak\\\");var obj_exports={};__export(obj_exports,{ascii:function(){return ascii},default:function(){return default_},defaultWordbreaker:function(){return default_},placeholder:function(){return placeholder}});function placeholder(r){var e=0;return r.split(/\\\\s+/).map(function(t){var n={start:e,end:e+t.length,text:t,length:t.length};return e=n.end,n})}v(placeholder,\\\"placeholder\\\");function ascii(r){for(var e=/[A-Za-z0-9']+/g,t=[],n;(n=e.exec(r))!==null;)t.push(new RegExpDerivedSpan(n[0],n.index));return t}v(ascii,\\\"ascii\\\");var RegExpDerivedSpan=function(){function r(e,t){this.text=e,this.start=t}return v(r,\\\"RegExpDerivedSpan2\\\"),Object.defineProperty(r.prototype,\\\"length\\\",{get:function(){return this.text.length},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,\\\"end\\\",{get:function(){return this.start+this.text.length},enumerable:!1,configurable:!0}),r}(),propertyMap=[\\\"Other\\\",\\\"LF\\\",\\\"Newline\\\",\\\"CR\\\",\\\"WSegSpace\\\",\\\"Double_Quote\\\",\\\"Single_Quote\\\",\\\"MidNum\\\",\\\"MidNumLet\\\",\\\"Numeric\\\",\\\"MidLetter\\\",\\\"ALetter\\\",\\\"ExtendNumLet\\\",\\\"Format\\\",\\\"Extend\\\",\\\"Hebrew_Letter\\\",\\\"ZWJ\\\",\\\"Katakana\\\",\\\"Regional_Indicator\\\",\\\"sot\\\",\\\"eot\\\"],WORD_BREAK_PROPERTY=[[0,0],[10,1],[11,2],[13,3],[14,0],[32,4],[33,0],[34,5],[35,0],[39,6],[40,0],[44,7],[45,0],[46,8],[47,0],[48,9],[58,10],[59,7],[60,0],[65,11],[91,0],[95,12],[96,0],[97,11],[123,0],[133,2],[134,0],[170,11],[171,0],[173,13],[174,0],[181,11],[182,0],[183,10],[184,0],[186,11],[187,0],[192,11],[215,0],[216,11],[247,0],[248,11],[728,0],[734,11],[768,14],[880,11],[885,0],[886,11],[888,0],[890,11],[894,7],[895,11],[896,0],[902,11],[903,10],[904,11],[907,0],[908,11],[909,0],[910,11],[930,0],[931,11],[1014,0],[1015,11],[1154,0],[1155,14],[1162,11],[1328,0],[1329,11],[1367,0],[1369,11],[1373,0],[1374,11],[1375,10],[1376,11],[1417,7],[1418,11],[1419,0],[1425,14],[1470,0],[1471,14],[1472,0],[1473,14],[1475,0],[1476,14],[1478,0],[1479,14],[1480,0],[1488,15],[1515,0],[1519,15],[1523,11],[1524,10],[1525,0],[1536,13],[1542,0],[1548,7],[1550,0],[1552,14],[1563,0],[1564,13],[1565,0],[1568,11],[1611,14],[1632,9],[1642,0],[1643,9],[1644,7],[1645,0],[1646,11],[1648,14],[1649,11],[1748,0],[1749,11],[1750,14],[1757,13],[1758,0],[1759,14],[1765,11],[1767,14],[1769,0],[1770,14],[1774,11],[1776,9],[1786,11],[1789,0],[1791,11],[1792,0],[1807,13],[1808,11],[1809,14],[1810,11],[1840,14],[1867,0],[1869,11],[1958,14],[1969,11],[1970,0],[1984,9],[1994,11],[2027,14],[2036,11],[2038,0],[2040,7],[2041,0],[2042,11],[2043,0],[2045,14],[2046,0],[2048,11],[2070,14],[2074,11],[2075,14],[2084,11],[2085,14],[2088,11],[2089,14],[2094,0],[2112,11],[2137,14],[2140,0],[2144,11],[2155,0],[2208,11],[2229,0],[2230,11],[2248,0],[2259,14],[2274,13],[2275,14],[2308,11],[2362,14],[2365,11],[2366,14],[2384,11],[2385,14],[2392,11],[2402,14],[2404,0],[2406,9],[2416,0],[2417,11],[2433,14],[2436,0],[2437,11],[2445,0],[2447,11],[2449,0],[2451,11],[2473,0],[2474,11],[2481,0],[2482,11],[2483,0],[2486,11],[2490,0],[2492,14],[2493,11],[2494,14],[2501,0],[2503,14],[2505,0],[2507,14],[2510,11],[2511,0],[2519,14],[2520,0],[2524,11],[2526,0],[2527,11],[2530,14],[2532,0],[2534,9],[2544,11],[2546,0],[2556,11],[2557,0],[2558,14],[2559,0],[2561,14],[2564,0],[2565,11],[2571,0],[2575,11],[2577,0],[2579,11],[2601,0],[2602,11],[2609,0],[2610,11],[2612,0],[2613,11],[2615,0],[2616,11],[2618,0],[2620,14],[2621,0],[2622,14],[2627,0],[2631,14],[2633,0],[2635,14],[2638,0],[2641,14],[2642,0],[2649,11],[2653,0],[2654,11],[2655,0],[2662,9],[2672,14],[2674,11],[2677,14],[2678,0],[2689,14],[2692,0],[2693,11],[2702,0],[2703,11],[2706,0],[2707,11],[2729,0],[2730,11],[2737,0],[2738,11],[2740,0],[2741,11],[2746,0],[2748,14],[2749,11],[2750,14],[2758,0],[2759,14],[2762,0],[2763,14],[2766,0],[2768,11],[2769,0],[2784,11],[2786,14],[2788,0],[2790,9],[2800,0],[2809,11],[2810,14],[2816,0],[2817,14],[2820,0],[2821,11],[2829,0],[2831,11],[2833,0],[2835,11],[2857,0],[2858,11],[2865,0],[2866,11],[2868,0],[2869,11],[2874,0],[2876,14],[2877,11],[2878,14],[2885,0],[2887,14],[2889,0],[2891,14],[2894,0],[2901,14],[2904,0],[2908,11],[2910,0],[2911,11],[2914,14],[2916,0],[2918,9],[2928,0],[2929,11],[2930,0],[2946,14],[2947,11],[2948,0],[2949,11],[2955,0],[2958,11],[2961,0],[2962,11],[2966,0],[2969,11],[2971,0],[2972,11],[2973,0],[2974,11],[2976,0],[2979,11],[2981,0],[2984,11],[2987,0],[2990,11],[3002,0],[3006,14],[3011,0],[3014,14],[3017,0],[3018,14],[3022,0],[3024,11],[3025,0],[3031,14],[3032,0],[3046,9],[3056,0],[3072,14],[3077,11],[3085,0],[3086,11],[3089,0],[3090,11],[3113,0],[3114,11],[3130,0],[3133,11],[3134,14],[3141,0],[3142,14],[3145,0],[3146,14],[3150,0],[3157,14],[3159,0],[3160,11],[3163,0],[3168,11],[3170,14],[3172,0],[3174,9],[3184,0],[3200,11],[3201,14],[3204,0],[3205,11],[3213,0],[3214,11],[3217,0],[3218,11],[3241,0],[3242,11],[3252,0],[3253,11],[3258,0],[3260,14],[3261,11],[3262,14],[3269,0],[3270,14],[3273,0],[3274,14],[3278,0],[3285,14],[3287,0],[3294,11],[3295,0],[3296,11],[3298,14],[3300,0],[3302,9],[3312,0],[3313,11],[3315,0],[3328,14],[3332,11],[3341,0],[3342,11],[3345,0],[3346,11],[3387,14],[3389,11],[3390,14],[3397,0],[3398,14],[3401,0],[3402,14],[3406,11],[3407,0],[3412,11],[3415,14],[3416,0],[3423,11],[3426,14],[3428,0],[3430,9],[3440,0],[3450,11],[3456,0],[3457,14],[3460,0],[3461,11],[3479,0],[3482,11],[3506,0],[3507,11],[3516,0],[3517,11],[3518,0],[3520,11],[3527,0],[3530,14],[3531,0],[3535,14],[3541,0],[3542,14],[3543,0],[3544,14],[3552,0],[3558,9],[3568,0],[3570,14],[3572,0],[3633,14],[3634,0],[3636,14],[3643,0],[3655,14],[3663,0],[3664,9],[3674,0],[3761,14],[3762,0],[3764,14],[3773,0],[3784,14],[3790,0],[3792,9],[3802,0],[3840,11],[3841,0],[3864,14],[3866,0],[3872,9],[3882,0],[3893,14],[3894,0],[3895,14],[3896,0],[3897,14],[3898,0],[3902,14],[3904,11],[3912,0],[3913,11],[3949,0],[3953,14],[3973,0],[3974,14],[3976,11],[3981,14],[3992,0],[3993,14],[4029,0],[4038,14],[4039,0],[4139,14],[4159,0],[4160,9],[4170,0],[4182,14],[4186,0],[4190,14],[4193,0],[4194,14],[4197,0],[4199,14],[4206,0],[4209,14],[4213,0],[4226,14],[4238,0],[4239,14],[4240,9],[4250,14],[4254,0],[4256,11],[4294,0],[4295,11],[4296,0],[4301,11],[4302,0],[4304,11],[4347,0],[4348,11],[4681,0],[4682,11],[4686,0],[4688,11],[4695,0],[4696,11],[4697,0],[4698,11],[4702,0],[4704,11],[4745,0],[4746,11],[4750,0],[4752,11],[4785,0],[4786,11],[4790,0],[4792,11],[4799,0],[4800,11],[4801,0],[4802,11],[4806,0],[4808,11],[4823,0],[4824,11],[4881,0],[4882,11],[4886,0],[4888,11],[4955,0],[4957,14],[4960,0],[4992,11],[5008,0],[5024,11],[5110,0],[5112,11],[5118,0],[5121,11],[5741,0],[5743,11],[5760,4],[5761,11],[5787,0],[5792,11],[5867,0],[5870,11],[5881,0],[5888,11],[5901,0],[5902,11],[5906,14],[5909,0],[5920,11],[5938,14],[5941,0],[5952,11],[5970,14],[5972,0],[5984,11],[5997,0],[5998,11],[6001,0],[6002,14],[6004,0],[6068,14],[6100,0],[6109,14],[6110,0],[6112,9],[6122,0],[6155,14],[6158,13],[6159,0],[6160,9],[6170,0],[6176,11],[6265,0],[6272,11],[6277,14],[6279,11],[6313,14],[6314,11],[6315,0],[6320,11],[6390,0],[6400,11],[6431,0],[6432,14],[6444,0],[6448,14],[6460,0],[6470,9],[6480,0],[6608,9],[6618,0],[6656,11],[6679,14],[6684,0],[6741,14],[6751,0],[6752,14],[6781,0],[6783,14],[6784,9],[6794,0],[6800,9],[6810,0],[6832,14],[6849,0],[6912,14],[6917,11],[6964,14],[6981,11],[6988,0],[6992,9],[7002,0],[7019,14],[7028,0],[7040,14],[7043,11],[7073,14],[7086,11],[7088,9],[7098,11],[7142,14],[7156,0],[7168,11],[7204,14],[7224,0],[7232,9],[7242,0],[7245,11],[7248,9],[7258,11],[7294,0],[7296,11],[7305,0],[7312,11],[7355,0],[7357,11],[7360,0],[7376,14],[7379,0],[7380,14],[7401,11],[7405,14],[7406,11],[7412,14],[7413,11],[7415,14],[7418,11],[7419,0],[7424,11],[7616,14],[7674,0],[7675,14],[7680,11],[7958,0],[7960,11],[7966,0],[7968,11],[8006,0],[8008,11],[8014,0],[8016,11],[8024,0],[8025,11],[8026,0],[8027,11],[8028,0],[8029,11],[8030,0],[8031,11],[8062,0],[8064,11],[8117,0],[8118,11],[8125,0],[8126,11],[8127,0],[8130,11],[8133,0],[8134,11],[8141,0],[8144,11],[8148,0],[8150,11],[8156,0],[8160,11],[8173,0],[8178,11],[8181,0],[8182,11],[8189,0],[8192,4],[8199,0],[8200,4],[8203,0],[8204,14],[8205,16],[8206,13],[8208,0],[8216,8],[8218,0],[8228,8],[8229,0],[8231,10],[8232,2],[8234,13],[8239,12],[8240,0],[8255,12],[8257,0],[8260,7],[8261,0],[8276,12],[8277,0],[8287,4],[8288,13],[8293,0],[8294,13],[8304,0],[8305,11],[8306,0],[8319,11],[8320,0],[8336,11],[8349,0],[8400,14],[8433,0],[8450,11],[8451,0],[8455,11],[8456,0],[8458,11],[8468,0],[8469,11],[8470,0],[8473,11],[8478,0],[8484,11],[8485,0],[8486,11],[8487,0],[8488,11],[8489,0],[8490,11],[8494,0],[8495,11],[8506,0],[8508,11],[8512,0],[8517,11],[8522,0],[8526,11],[8527,0],[8544,11],[8585,0],[9398,11],[9450,0],[11264,11],[11311,0],[11312,11],[11359,0],[11360,11],[11493,0],[11499,11],[11503,14],[11506,11],[11508,0],[11520,11],[11558,0],[11559,11],[11560,0],[11565,11],[11566,0],[11568,11],[11624,0],[11631,11],[11632,0],[11647,14],[11648,11],[11671,0],[11680,11],[11687,0],[11688,11],[11695,0],[11696,11],[11703,0],[11704,11],[11711,0],[11712,11],[11719,0],[11720,11],[11727,0],[11728,11],[11735,0],[11736,11],[11743,0],[11744,14],[11776,0],[11823,11],[11824,0],[12288,4],[12289,0],[12293,11],[12294,0],[12330,14],[12336,0],[12337,17],[12342,0],[12347,11],[12349,0],[12441,14],[12443,17],[12445,0],[12448,17],[12539,0],[12540,17],[12544,0],[12549,11],[12592,0],[12593,11],[12687,0],[12704,11],[12736,0],[12784,17],[12800,0],[13008,17],[13055,0],[13056,17],[13144,0],[40960,11],[42125,0],[42192,11],[42238,0],[42240,11],[42509,0],[42512,11],[42528,9],[42538,11],[42540,0],[42560,11],[42607,14],[42611,0],[42612,14],[42622,0],[42623,11],[42654,14],[42656,11],[42736,14],[42738,0],[42760,11],[42944,0],[42946,11],[42955,0],[42997,11],[43010,14],[43011,11],[43014,14],[43015,11],[43019,14],[43020,11],[43043,14],[43048,0],[43052,14],[43053,0],[43072,11],[43124,0],[43136,14],[43138,11],[43188,14],[43206,0],[43216,9],[43226,0],[43232,14],[43250,11],[43256,0],[43259,11],[43260,0],[43261,11],[43263,14],[43264,9],[43274,11],[43302,14],[43310,0],[43312,11],[43335,14],[43348,0],[43360,11],[43389,0],[43392,14],[43396,11],[43443,14],[43457,0],[43471,11],[43472,9],[43482,0],[43493,14],[43494,0],[43504,9],[43514,0],[43520,11],[43561,14],[43575,0],[43584,11],[43587,14],[43588,11],[43596,14],[43598,0],[43600,9],[43610,0],[43643,14],[43646,0],[43696,14],[43697,0],[43698,14],[43701,0],[43703,14],[43705,0],[43710,14],[43712,0],[43713,14],[43714,0],[43744,11],[43755,14],[43760,0],[43762,11],[43765,14],[43767,0],[43777,11],[43783,0],[43785,11],[43791,0],[43793,11],[43799,0],[43808,11],[43815,0],[43816,11],[43823,0],[43824,11],[43882,0],[43888,11],[44003,14],[44011,0],[44012,14],[44014,0],[44016,9],[44026,0],[44032,11],[55204,0],[55216,11],[55239,0],[55243,11],[55292,0],[64256,11],[64263,0],[64275,11],[64280,0],[64285,15],[64286,14],[64287,15],[64297,0],[64298,15],[64311,0],[64312,15],[64317,0],[64318,15],[64319,0],[64320,15],[64322,0],[64323,15],[64325,0],[64326,15],[64336,11],[64434,0],[64467,11],[64830,0],[64848,11],[64912,0],[64914,11],[64968,0],[65008,11],[65020,0],[65024,14],[65040,7],[65041,0],[65043,10],[65044,7],[65045,0],[65056,14],[65072,0],[65075,12],[65077,0],[65101,12],[65104,7],[65105,0],[65106,8],[65107,0],[65108,7],[65109,10],[65110,0],[65136,11],[65141,0],[65142,11],[65277,0],[65279,13],[65280,0],[65287,8],[65288,0],[65292,7],[65293,0],[65294,8],[65295,0],[65296,9],[65306,10],[65307,7],[65308,0],[65313,11],[65339,0],[65343,12],[65344,0],[65345,11],[65371,0],[65382,17],[65438,14],[65440,11],[65471,0],[65474,11],[65480,0],[65482,11],[65488,0],[65490,11],[65496,0],[65498,11],[65501,0],[65529,13],[65532,0],[65536,11],[65548,0],[65549,11],[65575,0],[65576,11],[65595,0],[65596,11],[65598,0],[65599,11],[65614,0],[65616,11],[65630,0],[65664,11],[65787,0],[65856,11],[65909,0],[66045,14],[66046,0],[66176,11],[66205,0],[66208,11],[66257,0],[66272,14],[66273,0],[66304,11],[66336,0],[66349,11],[66379,0],[66384,11],[66422,14],[66427,0],[66432,11],[66462,0],[66464,11],[66500,0],[66504,11],[66512,0],[66513,11],[66518,0],[66560,11],[66718,0],[66720,9],[66730,0],[66736,11],[66772,0],[66776,11],[66812,0],[66816,11],[66856,0],[66864,11],[66916,0],[67072,11],[67383,0],[67392,11],[67414,0],[67424,11],[67432,0],[67584,11],[67590,0],[67592,11],[67593,0],[67594,11],[67638,0],[67639,11],[67641,0],[67644,11],[67645,0],[67647,11],[67670,0],[67680,11],[67703,0],[67712,11],[67743,0],[67808,11],[67827,0],[67828,11],[67830,0],[67840,11],[67862,0],[67872,11],[67898,0],[67968,11],[68024,0],[68030,11],[68032,0],[68096,11],[68097,14],[68100,0],[68101,14],[68103,0],[68108,14],[68112,11],[68116,0],[68117,11],[68120,0],[68121,11],[68150,0],[68152,14],[68155,0],[68159,14],[68160,0],[68192,11],[68221,0],[68224,11],[68253,0],[68288,11],[68296,0],[68297,11],[68325,14],[68327,0],[68352,11],[68406,0],[68416,11],[68438,0],[68448,11],[68467,0],[68480,11],[68498,0],[68608,11],[68681,0],[68736,11],[68787,0],[68800,11],[68851,0],[68864,11],[68900,14],[68904,0],[68912,9],[68922,0],[69248,11],[69290,0],[69291,14],[69293,0],[69296,11],[69298,0],[69376,11],[69405,0],[69415,11],[69416,0],[69424,11],[69446,14],[69457,0],[69552,11],[69573,0],[69600,11],[69623,0],[69632,14],[69635,11],[69688,14],[69703,0],[69734,9],[69744,0],[69759,14],[69763,11],[69808,14],[69819,0],[69821,13],[69822,0],[69837,13],[69838,0],[69840,11],[69865,0],[69872,9],[69882,0],[69888,14],[69891,11],[69927,14],[69941,0],[69942,9],[69952,0],[69956,11],[69957,14],[69959,11],[69960,0],[69968,11],[70003,14],[70004,0],[70006,11],[70007,0],[70016,14],[70019,11],[70067,14],[70081,11],[70085,0],[70089,14],[70093,0],[70094,14],[70096,9],[70106,11],[70107,0],[70108,11],[70109,0],[70144,11],[70162,0],[70163,11],[70188,14],[70200,0],[70206,14],[70207,0],[70272,11],[70279,0],[70280,11],[70281,0],[70282,11],[70286,0],[70287,11],[70302,0],[70303,11],[70313,0],[70320,11],[70367,14],[70379,0],[70384,9],[70394,0],[70400,14],[70404,0],[70405,11],[70413,0],[70415,11],[70417,0],[70419,11],[70441,0],[70442,11],[70449,0],[70450,11],[70452,0],[70453,11],[70458,0],[70459,14],[70461,11],[70462,14],[70469,0],[70471,14],[70473,0],[70475,14],[70478,0],[70480,11],[70481,0],[70487,14],[70488,0],[70493,11],[70498,14],[70500,0],[70502,14],[70509,0],[70512,14],[70517,0],[70656,11],[70709,14],[70727,11],[70731,0],[70736,9],[70746,0],[70750,14],[70751,11],[70754,0],[70784,11],[70832,14],[70852,11],[70854,0],[70855,11],[70856,0],[70864,9],[70874,0],[71040,11],[71087,14],[71094,0],[71096,14],[71105,0],[71128,11],[71132,14],[71134,0],[71168,11],[71216,14],[71233,0],[71236,11],[71237,0],[71248,9],[71258,0],[71296,11],[71339,14],[71352,11],[71353,0],[71360,9],[71370,0],[71453,14],[71468,0],[71472,9],[71482,0],[71680,11],[71724,14],[71739,0],[71840,11],[71904,9],[71914,0],[71935,11],[71943,0],[71945,11],[71946,0],[71948,11],[71956,0],[71957,11],[71959,0],[71960,11],[71984,14],[71990,0],[71991,14],[71993,0],[71995,14],[71999,11],[72e3,14],[72001,11],[72002,14],[72004,0],[72016,9],[72026,0],[72096,11],[72104,0],[72106,11],[72145,14],[72152,0],[72154,14],[72161,11],[72162,0],[72163,11],[72164,14],[72165,0],[72192,11],[72193,14],[72203,11],[72243,14],[72250,11],[72251,14],[72255,0],[72263,14],[72264,0],[72272,11],[72273,14],[72284,11],[72330,14],[72346,0],[72349,11],[72350,0],[72384,11],[72441,0],[72704,11],[72713,0],[72714,11],[72751,14],[72759,0],[72760,14],[72768,11],[72769,0],[72784,9],[72794,0],[72818,11],[72848,0],[72850,14],[72872,0],[72873,14],[72887,0],[72960,11],[72967,0],[72968,11],[72970,0],[72971,11],[73009,14],[73015,0],[73018,14],[73019,0],[73020,14],[73022,0],[73023,14],[73030,11],[73031,14],[73032,0],[73040,9],[73050,0],[73056,11],[73062,0],[73063,11],[73065,0],[73066,11],[73098,14],[73103,0],[73104,14],[73106,0],[73107,14],[73112,11],[73113,0],[73120,9],[73130,0],[73440,11],[73459,14],[73463,0],[73648,11],[73649,0],[73728,11],[74650,0],[74752,11],[74863,0],[74880,11],[75076,0],[77824,11],[78895,0],[78896,13],[78905,0],[82944,11],[83527,0],[92160,11],[92729,0],[92736,11],[92767,0],[92768,9],[92778,0],[92880,11],[92910,0],[92912,14],[92917,0],[92928,11],[92976,14],[92983,0],[92992,11],[92996,0],[93008,9],[93018,0],[93027,11],[93048,0],[93053,11],[93072,0],[93760,11],[93824,0],[93952,11],[94027,0],[94031,14],[94032,11],[94033,14],[94088,0],[94095,14],[94099,11],[94112,0],[94176,11],[94178,0],[94179,11],[94180,14],[94181,0],[94192,14],[94194,0],[110592,17],[110593,0],[110948,17],[110952,0],[113664,11],[113771,0],[113776,11],[113789,0],[113792,11],[113801,0],[113808,11],[113818,0],[113821,14],[113823,0],[113824,13],[113828,0],[119141,14],[119146,0],[119149,14],[119155,13],[119163,14],[119171,0],[119173,14],[119180,0],[119210,14],[119214,0],[119362,14],[119365,0],[119808,11],[119893,0],[119894,11],[119965,0],[119966,11],[119968,0],[119970,11],[119971,0],[119973,11],[119975,0],[119977,11],[119981,0],[119982,11],[119994,0],[119995,11],[119996,0],[119997,11],[120004,0],[120005,11],[120070,0],[120071,11],[120075,0],[120077,11],[120085,0],[120086,11],[120093,0],[120094,11],[120122,0],[120123,11],[120127,0],[120128,11],[120133,0],[120134,11],[120135,0],[120138,11],[120145,0],[120146,11],[120486,0],[120488,11],[120513,0],[120514,11],[120539,0],[120540,11],[120571,0],[120572,11],[120597,0],[120598,11],[120629,0],[120630,11],[120655,0],[120656,11],[120687,0],[120688,11],[120713,0],[120714,11],[120745,0],[120746,11],[120771,0],[120772,11],[120780,0],[120782,9],[120832,0],[121344,14],[121399,0],[121403,14],[121453,0],[121461,14],[121462,0],[121476,14],[121477,0],[121499,14],[121504,0],[121505,14],[121520,0],[122880,14],[122887,0],[122888,14],[122905,0],[122907,14],[122914,0],[122915,14],[122917,0],[122918,14],[122923,0],[123136,11],[123181,0],[123184,14],[123191,11],[123198,0],[123200,9],[123210,0],[123214,11],[123215,0],[123584,11],[123628,14],[123632,9],[123642,0],[124928,11],[125125,0],[125136,14],[125143,0],[125184,11],[125252,14],[125259,11],[125260,0],[125264,9],[125274,0],[126464,11],[126468,0],[126469,11],[126496,0],[126497,11],[126499,0],[126500,11],[126501,0],[126503,11],[126504,0],[126505,11],[126515,0],[126516,11],[126520,0],[126521,11],[126522,0],[126523,11],[126524,0],[126530,11],[126531,0],[126535,11],[126536,0],[126537,11],[126538,0],[126539,11],[126540,0],[126541,11],[126544,0],[126545,11],[126547,0],[126548,11],[126549,0],[126551,11],[126552,0],[126553,11],[126554,0],[126555,11],[126556,0],[126557,11],[126558,0],[126559,11],[126560,0],[126561,11],[126563,0],[126564,11],[126565,0],[126567,11],[126571,0],[126572,11],[126579,0],[126580,11],[126584,0],[126585,11],[126589,0],[126590,11],[126591,0],[126592,11],[126602,0],[126603,11],[126620,0],[126625,11],[126628,0],[126629,11],[126634,0],[126635,11],[126652,0],[127280,11],[127306,0],[127312,11],[127338,0],[127344,11],[127370,0],[127462,18],[127488,0],[127995,14],[128e3,0],[130032,9],[130042,0],[917505,13],[917506,0],[917536,14],[917632,0],[917760,14],[918e3,0]];function default_(r,e){var t=findBoundaries(r,e);if(t.length==0)return[];for(var n=[],i=0;i=this.text.length?20:isStartOfSurrogatePair(this.text[e])?property(this.text[e]+this.text[e+1]):property(this.text[e],this.options)},r.prototype.match=function(e,t,n,i){var a,u,o,l,s=(a=e==null?void 0:e.includes(this.lookbehind))!==null&&a!==void 0?a:!0;return s=s&&((u=t==null?void 0:t.includes(this.left))!==null&&u!==void 0?u:!0),s=s&&((o=n==null?void 0:n.includes(this.right))!==null&&o!==void 0?o:!0),s&&((l=i==null?void 0:i.includes(this.lookahead))!==null&&l!==void 0?l:!0)},r.prototype.propertyMatch=function(e,t,n,i){var a=this,u=v(function(o){return propertyVal(o,a.options)},\\\"propMapper\\\");return this.match(e==null?void 0:e.map(u),t==null?void 0:t.map(u),n==null?void 0:n.map(u),i==null?void 0:i.map(u))},r}();function isNonSpace(r,e){return!Array.from(r).map(function(t){return property(t,e)}).every(function(t){return t===3||t===1||t===2||t===4})}v(isNonSpace,\\\"isNonSpace\\\");function findBoundaries(r,e){var t,n,i;if(r.length===0)return[];e&&!e.rules&&(e.rules=[]);var a=[],u,o=0,l=new BreakerContext(r,e,o),s=0;do{if(u=o,o=C(o),l=l.next(o),l.match(null,[19],null,null)){a.push(u);continue}if(l.match(null,null,[20],null)){a.push(u);break}if(!l.match(null,[3],[1],null)){var f=[2,3,1];if(l.match(null,f,null,null)){a.push(u);continue}if(l.match(null,null,f,null)){a.push(u);continue}if(!l.match(null,[4],[4],null)){for(var c=[13,14,16];l.match(null,null,c,null);)t=(0,build_exports.__read)([o,C(o)],2),u=t[0],o=t[1],l=l.ignoringRight(o);if(l.right===20){a.push(u);break}for(;l.match(null,null,null,c);)o=C(o),l=l.ignoringLookahead(o);var d=[11,15],p=[8,6];if(e!=null&&e.rules){var g=!1;try{for(var w=(n=void 0,(0,build_exports.__values)(e.rules)),b=w.next();!b.done;b=w.next()){var T=b.value;if(g=T.match(l),g){T.breakIfMatch&&a.push(u);break}}}catch(h){n={error:h}}finally{try{b&&!b.done&&(i=w.return)&&i.call(w)}finally{if(n)throw n.error}}if(g)continue}if(!l.match(null,d,d,null)){var S=[10].concat(p);if(!l.match(null,d,S,d)&&!l.match(d,S,d,null)&&!l.match(null,[15],[6],null)&&!l.match(null,[15],[5],[15])&&!l.match([15],[5],[15],null)&&!l.match(null,[9],[9],null)&&!l.match(null,d,[9],null)&&!l.match(null,[9],d,null)){var _=[7].concat(p);if(!l.match([9],_,[9],null)&&!l.match(null,[9],_,[9])&&!l.match(null,[17],[17],null)){var y=[17,9].concat(d);if(!l.match(null,y,[12],null)&&!l.match(null,[12],[12],null)&&!l.match(null,[12],y,null)){if(l.right===18){if(s+=1,s%2==1)continue}else s=0;a.push(u)}}}}}}}while(u=r.length?r.length:isStartOfSurrogatePair(r[h])?h+2:h+1}}v(findBoundaries,\\\"findBoundaries\\\");function isStartOfSurrogatePair(r){var e=r.charCodeAt(0);return e>=55296&&e<=56319}v(isStartOfSurrogatePair,\\\"isStartOfSurrogatePair\\\");function property(r,e){if(e!=null&&e.propertyMapping){var t=e.propertyMapping(r);if(t)return propertyVal(t,e)}var n=r.codePointAt(0);return searchForProperty(n,0,WORD_BREAK_PROPERTY.length-1)}v(property,\\\"property\\\");function propertyVal(r,e){var t,n,i=v(function(u){return u.toLowerCase()==r.toLowerCase()},\\\"matcher\\\"),a=(n=(t=e==null?void 0:e.customProperties)===null||t===void 0?void 0:t.findIndex(i))!==null&&n!==void 0?n:-1;return a!=-1?-a-1:propertyMap.findIndex(i)}v(propertyVal,\\\"propertyVal\\\");function searchForProperty(r,e,t){if(t=u?searchForProperty(r,n+1,t):i[1]}v(searchForProperty,\\\"searchForProperty\\\");var MAX_SUGGESTIONS=12,TrieModel=function(){function r(e,t){t===void 0&&(t={}),this.languageUsesCasing=t.languageUsesCasing,this.applyCasing=t.applyCasing,this._trie=new Trie(e.root,e.totalWeight,t.searchTermToKey||defaultSearchTermToKey),this.breakWords=t.wordBreaker||default_,this.punctuation=t.punctuation}return v(r,\\\"TrieModel2\\\"),r.prototype.configure=function(e){var t;return this.configuration={leftContextCodePoints:e.maxLeftContextCodePoints,rightContextCodePoints:(t=e.maxRightContextCodePoints)!==null&&t!==void 0?t:0}},r.prototype.toKey=function(e){return this._trie.toKey(e)},r.prototype.predict=function(e,t){if(!e.insert&&!t.left&&!t.right&&t.startOfBuffer&&t.endOfBuffer)return u(this._trie.firstN(MAX_SUGGESTIONS).map(function(o){var l=o.text,s=o.p;return{transform:{insert:l,deleteLeft:0},displayAs:l,p:s}}));var n=applyTransform(e,t),i=e.deleteLeft-e.insert.kmwLength(),a=getLastPreCaretToken(this.breakWords,n);return u(this._trie.lookup(a).map(function(o){var l=o.text,s=o.p;return transformToSuggestion({insert:l,deleteLeft:i+a.kmwLength()},s)}));function u(o){var l,s,f=[];try{for(var c=(0,build_exports.__values)(o),d=c.next();!d.done;d=c.next()){var p=d.value;f.push({sample:p,p:p.p})}}catch(g){l={error:g}}finally{try{d&&!d.done&&(s=c.return)&&s.call(c)}finally{if(l)throw l.error}}return f}},Object.defineProperty(r.prototype,\\\"wordbreaker\\\",{get:function(){return this.breakWords},enumerable:!1,configurable:!0}),r.prototype.traverseFromRoot=function(){return new r.Traversal(this._trie.root,\\\"\\\")},r.Traversal=function(){function e(t,n){this.root=t,this.prefix=n}return v(e,\\\"class_1\\\"),e.prototype.children=function(){var t,n,i,a,u,o,l,s,f,c,d,p,g,w,b,T,S,_;return(0,build_exports.__generator)(this,function(y){switch(y.label){case 0:if(t=this.root,t.type!=\\\"internal\\\")return[3,9];n=v(function(C){var h,m,O,k,A,I,E,D,F,q,R,U;return(0,build_exports.__generator)(this,function(M){switch(M.label){case 0:if(h=t.children[C],!isHighSurrogate(C))return[3,12];if(h.type!=\\\"internal\\\")return[3,9];m=h,O=v(function(N){var j;return(0,build_exports.__generator)(this,function(V){switch(V.label){case 0:return j=i.prefix+C+N,[4,{char:C+N,traversal:function(){return new r.Traversal(m.children[N],j)}}];case 1:return V.sent(),[2]}})},\\\"_loop_3\\\"),M.label=1;case 1:M.trys.push([1,6,7,8]),k=(R=void 0,(0,build_exports.__values)(m.values)),A=k.next(),M.label=2;case 2:return A.done?[3,5]:(I=A.value,[5,O(I)]);case 3:M.sent(),M.label=4;case 4:return A=k.next(),[3,2];case 5:return[3,8];case 6:return E=M.sent(),R={error:E},[3,8];case 7:try{A&&!A.done&&(U=k.return)&&U.call(k)}finally{if(R)throw R.error}return[7];case 8:return[3,11];case 9:return D=h.entries[0].key,C=C+D[i.prefix.length+1],F=i.prefix+C,[4,{char:C,traversal:function(){return new r.Traversal(h,F)}}];case 10:M.sent(),M.label=11;case 11:return[3,16];case 12:return isSentinel(C)?[2,\\\"continue\\\"]:[3,13];case 13:return C?[3,14]:[2,\\\"continue\\\"];case 14:return q=i.prefix+C,[4,{char:C,traversal:function(){return new r.Traversal(h,q)}}];case 15:M.sent(),M.label=16;case 16:return[2]}})},\\\"_loop_1\\\"),i=this,y.label=1;case 1:y.trys.push([1,6,7,8]),a=(0,build_exports.__values)(t.values),u=a.next(),y.label=2;case 2:return u.done?[3,5]:(o=u.value,[5,n(o)]);case 3:y.sent(),y.label=4;case 4:return u=a.next(),[3,2];case 5:return[3,8];case 6:return l=y.sent(),b={error:l},[3,8];case 7:try{u&&!u.done&&(T=a.return)&&T.call(a)}finally{if(b)throw b.error}return[7];case 8:return[2];case 9:s=this.prefix,f=t.entries.filter(function(C){return C.key!=s&&s.length=n)return o}}}catch(b){i={error:b}}finally{try{s&&!s.done&&(a=l.return)&&a.call(l)}finally{if(i)throw i.error}}else{u.enqueue(r);for(var p=void 0,g=v(function(){if(isNode(p))if(p.type===\\\"leaf\\\")u.enqueueAll(p.entries);else{var b=p;u.enqueueAll(p.values.map(function(T){return b.children[T]}))}else if(o.push({text:p.content,p:p.weight/t}),o.length>=n)return{value:o}},\\\"_loop_4\\\");p=u.dequeue();){var w=g();if(typeof w==\\\"object\\\")return w.value}}return o}v(getSortedResults,\\\"getSortedResults\\\");function isNode(r){return\\\"type\\\"in r}v(isNode,\\\"isNode\\\");function defaultSearchTermToKey(r){return r.normalize(\\\"NFD\\\").replace(/[\\\\u0300-\\\\u036f]/g,\\\"\\\").toLowerCase()}v(defaultSearchTermToKey,\\\"defaultSearchTermToKey\\\"),extendString();var DummyModel=function(){function r(e){e=e||{},this._futureSuggestions=e.futureSuggestions?e.futureSuggestions.slice():[],e.punctuation&&(this.punctuation=e.punctuation)}return v(r,\\\"DummyModel2\\\"),r.prototype.configure=function(e){return this.configuration={leftContextCodePoints:e.maxLeftContextCodePoints,rightContextCodePoints:e.maxRightContextCodePoints},this.configuration},r.prototype.predict=function(e,t,n){var i=v(function(u){var o,l,s=[],f=u.length;try{for(var c=(0,build_exports.__values)(u),d=c.next();!d.done;d=c.next()){var p=d.value;s.push({sample:p,p:1})}}catch(g){o={error:g}}finally{try{d&&!d.done&&(l=c.return)&&l.call(c)}finally{if(o)throw o.error}}return s},\\\"makeUniformDistribution\\\");if(n)return i(n);var a=this._futureSuggestions.shift();return a?i(a):[]},r}(),dummy_model_default=DummyModel,correction_exports={};__export(correction_exports,{ClassicalDistanceCalculation:function(){return ClassicalDistanceCalculation},ContextTracker:function(){return ContextTracker},QUEUE_NODE_COMPARATOR:function(){return QUEUE_NODE_COMPARATOR},SearchNode:function(){return SearchNode},SearchResult:function(){return SearchResult},SearchSpace:function(){return SearchSpace},TrackedContextState:function(){return TrackedContextState},TrackedContextSuggestion:function(){return TrackedContextSuggestion},TrackedContextToken:function(){return TrackedContextToken}});var ClassicalDistanceCalculation=function(){function r(e){if(this.diagonalWidth=2,this.inputSequence=[],this.matchSequence=[],e){var t=e.resolvedDistances.length;this.resolvedDistances=Array(t);for(var n=0;n2*n)&&(i.sparse=!0),i},r.prototype.getCostAt=function(e,t,n){if(n===void 0&&(n=this.diagonalWidth),e<0||t<0)return e==-1&&t>=-1?t+1:t==-1&&e>=-1?e+1:Number.MAX_VALUE;var i=this.getTrueIndex(e,t,n);return i.sparse?Number.MAX_VALUE:this.resolvedDistances[i.row][i.col]},r.prototype.getFinalCost=function(){for(var e=this,t=e.getHeuristicFinalCost();t>e.diagonalWidth;)e=e.increaseMaxDistance(),t=e.getHeuristicFinalCost();return t},r.prototype.getHeuristicFinalCost=function(){return this.getCostAt(this.inputSequence.length-1,this.matchSequence.length-1)},r.prototype.hasFinalCostWithin=function(e){var t=this,n=t.getHeuristicFinalCost(),i=this.diagonalWidth;do{if(n<=e)return!0;if(i=0&&c>=0){var d=1;if(i=[\\\"transpose-start\\\"],f!=e-1){var p=e-f-1;i=i.concat(Array(p).fill(\\\"transpose-delete\\\")),d+=p}else{var p=t-c-1;i=i.concat(Array(p).fill(\\\"transpose-insert\\\")),d+=p}i.push(\\\"transpose-end\\\"),this.getCostAt(f-1,c-1)!=n-d&&(i=null),a=[f-1,c-1]}return i||(l==n-1?(i=[\\\"substitute\\\"],a=[e-1,t-1]):u==n-1?(i=[\\\"insert\\\"],a=[e,t-1]):o==n-1?(i=[\\\"delete\\\"],a=[e-1,t]):(i=[\\\"match\\\"],a=[e-1,t-1])),a[0]>=0&&a[1]>=0?this.editPath(a[0],a[1]).concat(i):a[0]>-1?Array(a[0]+1).fill(\\\"delete\\\").concat(i):a[1]>-1?Array(a[1]+1).fill(\\\"insert\\\").concat(i):i},r.getTransposeParent=function(e,t,n){if(t<0||n<0||e.inputSequence[t].key==e.matchSequence[n].key)return[-1,-1];for(var i=-1,a=t-1;a>=0;a--)if(e.inputSequence[a].key==e.matchSequence[n].key){i=a;break}for(var u=-1,a=n-1;a>=0;a--)if(e.matchSequence[a].key==e.inputSequence[t].key){u=a;break}return[i,u]},r.initialCostAt=function(e,t,n,i,a){var u=e.inputSequence[t].key==e.matchSequence[n].key?0:1,o=e.getCostAt(t-1,n-1)+u,l=i||e.getCostAt(t,n-1)+1,s=a||e.getCostAt(t-1,n)+1,f=Number.MAX_VALUE;if(t>0&&n>0){var c=(0,build_exports.__read)(r.getTransposeParent(e,t,n),2),d=c[0],p=c[1];f=e.getCostAt(d-1,p-1)+(t-d-1)+1+(n-p-1)}return Math.min(o,s,l,f)},r.prototype.getSubset=function(e,t){var n=new r(this);if(e>this.inputSequence.length||t>this.matchSequence.length)throw\\\"Invalid dimensions specified for trim operation\\\";n.inputSequence.splice(e),n.matchSequence.splice(t),n.resolvedDistances.splice(e);for(var i=this.getTrueIndex(e-1,t-1,this.diagonalWidth),a=i.col;a<=2*this.diagonalWidth;a++){var u=i.row-(a-i.col);if(u<0)break;if(a<0)n.resolvedDistances[u]=Array(2*n.diagonalWidth+1).fill(Number.MAX_VALUE);else{var o=2*this.diagonalWidth-a,l=n.resolvedDistances[u].splice(0,a+1),s=Array(o).fill(Number.MAX_VALUE);n.resolvedDistances[u]=l.concat(s)}}return n},r.forDiagonalOfAxis=function(e,t,n,i){for(var a=n-t=0){var f=s==0?o+2:Number.MAX_VALUE;l=r.initialCostAt(e,o,s,f,void 0);var c=l;if(s0&&u){var l=i+1;this.propagateUpdateFrom(e,t+1,n,l,a-1)}if(u&&o){var l=i+(e.inputSequence[t+1].key==e.matchSequence[n+1].key?0:1);this.propagateUpdateFrom(e,t+1,n+1,l,a);for(var s=-1,f=t+2;f0&&c>0){var d=i+(s-t-2)+1+(c-n-2);this.propagateUpdateFrom(e,s,c,d,e.diagonalWidth-1+c-s)}}},Object.defineProperty(r.prototype,\\\"mapKey\\\",{get:function(){var e=this.inputSequence.map(function(n){return n.key}).join(\\\"\\\"),t=this.matchSequence.map(function(n){return n.key}).join(\\\"\\\");return e+SENTINEL_CODE_UNIT+t+SENTINEL_CODE_UNIT+this.diagonalWidth},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,\\\"lastInputEntry\\\",{get:function(){return this.inputSequence[this.inputSequence.length-1]},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,\\\"lastMatchEntry\\\",{get:function(){return this.matchSequence[this.matchSequence.length-1]},enumerable:!1,configurable:!0}),r.computeDistance=function(e,t,n){n===void 0&&(n=1);var i=new r;n=n||1,i.diagonalWidth=n;for(var a=0;ae?t.p:e}).reduce(function(t,n){return t-Math.log(n)},0),this._inputCost},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,\\\"currentCost\\\",{get:function(){return SearchSpace.EDIT_DISTANCE_COST_SCALE*this.knownCost+this.inputSamplingCost},enumerable:!1,configurable:!0}),r.prototype.buildInsertionEdges=function(){var e,t,n=[];try{for(var i=(0,build_exports.__values)(this.currentTraversal.children()),a=i.next();!a.done;a=i.next()){var u=a.value,o=u.traversal(),l={key:u.char,traversal:o},s=this.calculation.addMatchChar(l),f=new r(this);f.calculation=s,f.priorInput=this.priorInput,f.currentTraversal=o,n.push(f)}}catch(c){e={error:c}}finally{try{a&&!a.done&&(t=i.return)&&t.call(i)}finally{if(e)throw e.error}}return n},r.prototype.buildDeletionEdges=function(e){var t,n,i=[];try{for(var a=(0,build_exports.__values)(e),u=a.next();!u.done;u=a.next()){var o=u.value;if(o.p0:!1},r.prototype.handleNextNode=function(){if(!this.hasNextMatchEntry())return{type:\\\"none\\\"};var e=this.selectionQueue.dequeue(),t=e.correctionQueue.dequeue(),n={type:\\\"intermediate\\\",cost:t.currentCost};if(this.processedEdgeSet[t.mapKey])return this.selectionQueue.enqueue(e),n;this.processedEdgeSet[t.mapKey]=!0;var i=!1;if(t.knownCost>2)return n;t.knownCost==2&&(i=!0);for(var a=0,u=0;u<=e.index;u++)a+=this.minInputCost[u];if(t.currentCost>a+2.5*r.EDIT_DISTANCE_COST_SCALE)return n;if(!i){var o=t.buildInsertionEdges();e.correctionQueue.enqueueAll(o)}if(e.index==this.tierOrdering.length-1)return this.completedPaths.push(t),this.selectionQueue.enqueue(e),{type:\\\"complete\\\",cost:t.currentCost,finalNode:t};var l=this.tierOrdering[e.index+1],s=l.index,f=[];i||(f=t.buildDeletionEdges(this.inputSequence[s-1]));var c=t.buildSubstitutionEdges(this.inputSequence[s-1]);return l.correctionQueue.enqueueAll(f.concat(c)),this.selectionQueue=new priority_queue_default(this.QUEUE_SPACE_COMPARATOR,this.tierOrdering),n},r.prototype.getBestMatches=function(e){var t,n,i,a,u,o,l,s,f,c,d,p,g,w,b,T;return(0,build_exports.__generator)(this,function(S){switch(S.label){case 0:if(t=this,n={},e==0?i=1/0:e==null||Number.isNaN(e)?i=r.DEFAULT_ALLOTTED_CORRECTION_TIME_INTERVAL:i=e,a=function(){function _(y,C){this.largestIntervals=[0],this.loopStart=this.start=Date.now(),this.maxExecutionTime=y,this.maxTrueTime=C}return v(_,\\\"ExecutionTimer2\\\"),_.prototype.startLoop=function(){this.loopStart=Date.now()},_.prototype.markIteration=function(){var y=Date.now(),C=y-this.loopStart;this.executionTime+=C,C&&(this.largestIntervals.length>2&&C>this.largestIntervals[0]?this.largestIntervals[0]=C:this.largestIntervals.push(C),this.largestIntervals.sort(),this.updateOutliers())},_.prototype.updateOutliers=function(){this.largestIntervals.length>2&&this.largestIntervals[2]>=2*(this.largestIntervals[0]+this.largestIntervals[1])&&(this.executionTime-=this.largestIntervals[2],this.largestIntervals.pop())},_.prototype.shouldTimeout=function(){var y=Date.now();return y-this.start>this.maxTrueTime?!0:this.executionTime>this.maxExecutionTime},_.prototype.resetOutlierCheck=function(){this.largestIntervals=[]},_}(),u=function(){function _(){this.currentCost=Number.MIN_SAFE_INTEGER,this.entries=[]}return v(_,\\\"BatchingAssistant2\\\"),_.prototype.checkAndAdd=function(y){var C=null;y.currentCost>this.currentCost&&(C=this.tryFinalize(),this.currentCost=y.currentCost);var h=y.calculation.matchSequence.map(function(m){return m.key}).join(\\\"\\\");return t.returnedValues[h]||(t.returnedValues[h]=y),n[h]||(this.entries.push(new SearchResult(y)),n[h]=y),C},_.prototype.tryFinalize=function(){var y=null;return this.entries.length>0&&(y=this.entries,this.entries=[]),y},_}(),o=new u,l=new a(i*1.5,i),s=Object.values(this.returnedValues),!(s.length>0))return[3,6];f=new priority_queue_default(QUEUE_NODE_COMPARATOR,s),l.startLoop(),S.label=1;case 1:return f.count>0?(c=f.dequeue(),c.isFullReplacement?[3,1]:(d=o.checkAndAdd(c),l.markIteration(),d?[4,d]:[3,3])):[3,4];case 2:S.sent(),S.label=3;case 3:return[3,1];case 4:return p=o.tryFinalize(),p?[4,p]:[3,6];case 5:S.sent(),S.label=6;case 6:l.resetOutlierCheck(),l.startLoop(),g=!1,S.label=7;case 7:w=void 0;do w=this.handleNextNode(),l.markIteration(),l.shouldTimeout()&&(g=!0);while(!g&&w.type==\\\"intermediate\\\");if(b=void 0,w.type==\\\"none\\\")return[3,10];if(w.type==\\\"complete\\\"){if(w.finalNode.isFullReplacement)return[3,10];b=o.checkAndAdd(w.finalNode)}return b?[4,b]:[3,9];case 8:S.sent(),S.label=9;case 9:if(!g&&this.hasNextMatchEntry())return[3,7];S.label=10;case 10:return T=o.tryFinalize(),T?[4,T]:[3,12];case 11:S.sent(),S.label=12;case 12:return[2,null]}})},r.EDIT_DISTANCE_COST_SCALE=5,r.MIN_KEYSTROKE_PROBABILITY=1e-4,r.DEFAULT_ALLOTTED_CORRECTION_TIME_INTERVAL=33,r}(),TransformUtils=function(){function r(){}return v(r,\\\"TransformUtils2\\\"),r.isWhitespace=function(e){var t=/^[\\\\u0009\\\\u000A\\\\u000D\\\\u0020\\\\u00a0\\\\u1680\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u200b\\\\u2028\\\\u2029\\\\u202f\\\\u205f\\\\u3000]+$/i;return e.insert.match(t)!=null},r.isBackspace=function(e){return e.insert==\\\"\\\"&&e.deleteLeft>0&&!e.deleteRight},r.isEmpty=function(e){return e.insert==\\\"\\\"&&e.deleteLeft==0&&!e.deleteRight},r}(),transformUtils_default=TransformUtils;function textToCharTransforms(r,e){for(var t=[],n=0;n0&&e.transformDistributions.forEach(function(n){return t.searchSpace[0].addInput(n)})},r.prototype.pushWhitespaceToTail=function(e){e===void 0&&(e=null);var t=new TrackedContextToken;t.transformDistributions=e?[e]:[],t.raw=null,this.tokens.push(t)},r.prototype.replaceTailForBackspace=function(e,t){this.tokens.pop();var n=textToCharTransforms(e,t).map(function(a){return[{sample:a,p:1}]}),i=new TrackedContextToken;i.raw=e,i.transformDistributions=n,this.pushTail(i)},r.prototype.updateTail=function(e,t){var n=this.tail;t=t||(t===\\\"\\\"?\\\"\\\":n.raw),e&&e.length>0&&(n.transformDistributions.push(e),this.searchSpace&&this.searchSpace.forEach(function(i){return i.addInput(e)})),n.raw=t},r.prototype.toRawTokenization=function(){var e,t,n=[];try{for(var i=(0,build_exports.__values)(this.tokens),a=i.next();!a.done;a=i.next()){var u=a.value;u.currentText!==null&&n.push(u.currentText)}}catch(o){e={error:o}}finally{try{a&&!a.done&&(t=i.return)&&t.call(i)}finally{if(e)throw e.error}}return n},r}(),CircularArray=function(){function r(e){e===void 0&&(e=r.DEFAULT_ARRAY_SIZE),this.currentHead=0,this.currentTail=0,this.circle=Array(e)}return v(r,\\\"CircularArray2\\\"),Object.defineProperty(r.prototype,\\\"count\\\",{get:function(){var e=this.currentHead-this.currentTail;return e<0&&(e=e+this.circle.length),e},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,\\\"maxCount\\\",{get:function(){return this.circle.length},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,\\\"oldest\\\",{get:function(){if(this.count!=0)return this.item(0)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,\\\"newest\\\",{get:function(){if(this.count!=0)return this.item(this.count-1)},enumerable:!1,configurable:!0}),r.prototype.enqueue=function(e){var t=null,n=(this.currentHead+1)%this.maxCount;return n==this.currentTail&&(t=this.circle[this.currentTail],this.currentTail=(this.currentTail+1)%this.maxCount),this.circle[this.currentHead]=e,this.currentHead=n,t},r.prototype.dequeue=function(){if(this.currentTail==this.currentHead)return null;var e=this.circle[this.currentTail];return this.currentTail=(this.currentTail+1)%this.maxCount,e},r.prototype.popNewest=function(){if(this.currentTail==this.currentHead)return null;var e=this.circle[this.currentHead];return this.currentHead=(this.currentHead-1+this.maxCount)%this.maxCount,e},r.prototype.item=function(e){if(e>=this.count)throw\\\"Invalid array index\\\";var t=(this.currentTail+e)%this.maxCount;return this.circle[t]},r.DEFAULT_ARRAY_SIZE=5,r}(),ContextTracker=function(r){(0,build_exports.__extends)(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return v(e,\\\"ContextTracker2\\\"),e.attemptMatchContext=function(t,n,i){var a=n.toRawTokenization(),u=ClassicalDistanceCalculation.computeDistance(a.map(function(h){return{key:h}}),t.map(function(h){return{key:h}}),1),o=u.editPath(),l=!1,s=!1;if(o.length>1){if(o[0]==\\\"insert\\\"&&!(o[1]==\\\"substitute\\\"&&o.length==2)||o[0].indexOf(\\\"transpose\\\")>=0)return null;o[0]==\\\"delete\\\"&&(l=!0)}var f=o.length-1,c=!1;if(o[f]==\\\"delete\\\"||o[0].indexOf(\\\"transpose\\\")>=0||(o[f]==\\\"insert\\\"?s=!0:f>0&&o[f-1]==\\\"insert\\\"&&o[f]==\\\"substitute\\\"&&(s=!0,c=!0),f>0&&o[f-1]==\\\"delete\\\"&&o[f]==\\\"substitute\\\"))return null;for(var d=1;d1)if(l&&p.popHead(),s){var _=t[t.length-1],y=new TrackedContextToken;y.raw=_,b||!w?(p.pushWhitespaceToTail(i!=null?i:[]),y.transformDistributions=[]):(p.pushWhitespaceToTail(),y.transformDistributions=i?[i]:[]),p.pushTail(y)}else T?p.replaceTailForBackspace(S,w.id):p.updateTail(w?i:null,S);else if(o[f]==\\\"insert\\\"){var C=new TrackedContextToken;C.raw=t[0],C.transformDistributions=[i],p.pushTail(C)}else T?p.replaceTailForBackspace(S,w.id):p.updateTail(w?i:null,S);return p},e.modelContextState=function(t,n,i){var a=t.map(function(l){var s=new TrackedContextToken;return s.raw=l,s.raw?s.transformDistributions=textToCharTransforms(s.raw).map(function(f){return[{sample:f,p:1}]}):s.transformDistributions=[],s}),u=new TrackedContextState(i);for(a.length>0&&u.pushTail(a.splice(0,1)[0]);a.length>0;)u.pushWhitespaceToTail(),u.pushTail(a.splice(0,1)[0]);if(u.tokens.length==0){var o=new TrackedContextToken;o.raw=\\\"\\\",u.pushTail(o)}return u},e.prototype.analyzeState=function(t,n,i){if(!t.traverseFromRoot)throw\\\"This lexical model does not provide adequate data for correction algorithms and context reuse\\\";var a=tokenize(t.wordbreaker||default_,n);if(a.left.length>0)for(var u=this.count-1;u>=0;u--){var o=e.attemptMatchContext(a.left,this.item(u),i);if(o)return o.taggedContext=n,o!=this.item(u)&&this.enqueue(o),o}var l=e.modelContextState(a.left,i,t);return l.taggedContext=n,this.enqueue(l),l},e}(CircularArray),ModelCompositor=function(){function r(e,t){this.SUGGESTION_ID_SEED=0,this.testMode=!1,this.lexicalModel=e,e.traverseFromRoot&&(this.contextTracker=new ContextTracker),this.punctuation=r.determinePunctuationFromModel(e),this.testMode=!!t}return v(r,\\\"ModelCompositor2\\\"),r.prototype.predictFromCorrections=function(e,t){var n,i,a=[],u=v(function(c){var d=o.lexicalModel.predict(c.sample,t),p=d.map(function(g){var w=c.sample,b=c.p;w.id!==void 0&&(g.sample.transformId=w.id);var T={sample:g.sample,p:g.p*b};return T},o);a=a.concat(p)},\\\"_loop_1\\\"),o=this;try{for(var l=(0,build_exports.__values)(e),s=l.next();!s.done;s=l.next()){var f=s.value;u(f)}}catch(c){n={error:c}}finally{try{s&&!s.done&&(i=l.return)&&i.call(l)}finally{if(n)throw n.error}}return a},r.prototype.predict=function(e,t){var n,i,a,u,o=[],l=this.lexicalModel,s=this.punctuation;e instanceof Array?e.length==0&&e.push({sample:{insert:\\\"\\\",deleteLeft:0},p:1}):e=[{sample:e,p:1}];var f=e.sort(function(x,P){return P.p-x.p})[0].sample,c=transformUtils_default.isWhitespace(f),d=transformUtils_default.isBackspace(f),p=applyTransform(f,t),g=this.wordbreak(p),w=null,b=[],T,S=null;if(this.contextTracker){var y=this.contextTracker.analyzeState(this.lexicalModel,t,null);S=this.contextTracker.analyzeState(this.lexicalModel,p,transformUtils_default.isEmpty(f)?null:e);var C=S.searchSpace[0],h=0,m=S.tokens,O=m.length,k=m.length-y.tokens.length;O==0||k>0?(h=0,transformUtils_default.isWhitespace(f)&&(T=f,t=p,y=S)):k<0?h=this.wordbreak(p).kmwLength()+f.deleteLeft:h=this.wordbreak(t).kmwLength();var A=m[m.length-1],I=A.transformDistributions.length<=1,E=void 0,D=this.testMode?0:SearchSpace.DEFAULT_ALLOTTED_CORRECTION_TIME_INTERVAL;try{for(var F=(0,build_exports.__values)(C.getBestMatches(D)),q=F.next();!q.done;q=F.next()){var R=q.value,_=R.map(function(P){var W=P.matchString,H;P.inputSequence.length>0?H=P.inputSequence[P.inputSequence.length-1].sample:H=f;var ie={insert:W,deleteLeft:h,id:f.id},ee=P.totalCost;return I&&(ee*=r.SINGLE_CHAR_KEY_PROB_EXPONENT),{sample:ie,p:Math.exp(-ee)}},this),U=this.predictFromCorrections(_,t);U.length>0&&E===void 0&&(E=-Math.log(_[0].p)),b=b.concat(U);var M=R[0].totalCost;if(M>=E+8)break;if(b.length>=r.MAX_SUGGESTIONS){if(M>=E+4)break;if(b.sort(function(P,W){return W.p-P.p}),b[r.MAX_SUGGESTIONS-1].p>Math.exp(-M))break}}}catch(x){n={error:x}}finally{try{q&&!q.done&&(i=F.return)&&i.call(F)}finally{if(n)throw n.error}}}else{var _=void 0;c?(_=[{sample:f,p:1}],T=f):_=e.map(function(x){var P=x.sample;return transformUtils_default.isWhitespace(P)&&!c||transformUtils_default.isBackspace(P)&&!d?null:x}),_=_.filter(function(x){return!!x}),b=this.predictFromCorrections(_,t)}var N={},j=null;l.languageUsesCasing&&(j=this.detectCurrentCasing(p));var V=this.wordbreak(t);try{for(var G=(0,build_exports.__values)(b),B=G.next();!B.done;B=G.next()){var L=B.value,Q=L.sample.displayAs,X=Q==g;if(this.lexicalModel.languageUsesCasing&&(X=X||Q==this.lexicalModel.applyCasing(\\\"lower\\\",g)),X)if(w)w.p&&L.p&&(w.p+=L.p);else{var z=L.sample.transform,Y={insert:g,deleteLeft:z.deleteLeft,deleteRight:z.deleteRight,id:z.id},te=transformToSuggestion(Y,L.p);w=this.toAnnotatedSuggestion(te,\\\"keep\\\",quote_behavior_default.noQuotes),w.matchesModel=!0,w.transformId=L.sample.transformId}else{j&&j!=\\\"lower\\\"&&(this.applySuggestionCasing(L.sample,V,j),Q=L.sample.displayAs);var J=N[Q];J?J.p+=L.p:N[Q]=L}}}catch(x){a={error:x}}finally{try{B&&!B.done&&(u=G.return)&&u.call(G)}finally{if(a)throw a.error}}if(!w&&g!=\\\"\\\"){var Y=(0,build_exports.__assign)({},f),$=transformToSuggestion(Y,1);$.displayAs=g,w=this.toAnnotatedSuggestion($,\\\"keep\\\"),w.matchesModel=!1}for(var re in N){var ne=N[re];o.push(ne)}o=o.sort(function(x,P){return P.p-x.p});var K=o.splice(0,r.MAX_SUGGESTIONS).map(function(x){return x.sample.p&&(x.sample[\\\"lexical-p\\\"]=x.sample.p,x.sample[\\\"correction-p\\\"]=x.p/x.sample.p,x.sample.p=x.p),x.sample});w&&(K=[w].concat(K));var Z=this;return K.forEach(function(x){if(!t.right)x.transform.insert+=s.insertAfterWord;else{var P=Z.tokenize(t);P&&P.caretSplitsToken&&(x.transform.insert+=s.insertAfterWord)}if(T){var W=buildMergedTransform(T,x.transform);W.id=x.transformId;var H=x;H.transform=W}x.id=Z.SUGGESTION_ID_SEED,Z.SUGGESTION_ID_SEED++}),S&&(S.tail.replacements=K.map(function(x){return{suggestion:x,tokenWidth:1}})),K},r.prototype.applySuggestionCasing=function(e,t,n){var i=t.kmwLength()-e.transform.deleteLeft;i>0&&(e.transform.deleteLeft+=i,e.transform.insert=t.kmwSubstr(0,i)+e.transform.insert),e.transform.insert=this.lexicalModel.applyCasing(n,e.transform.insert),e.displayAs=this.lexicalModel.applyCasing(n,e.displayAs)},r.prototype.toAnnotatedSuggestion=function(e,t,n){n===void 0&&(n=quote_behavior_default.default);var i=quote_behavior_default,a=i.noQuotes;return(t==\\\"keep\\\"||t==\\\"revert\\\")&&(a=i.useQuotes),{transform:e.transform,transformId:e.transformId,displayAs:i.apply(n,e.displayAs,this.punctuation,a),tag:t,p:e.p}},r.determinePunctuationFromModel=function(e){var t=DEFAULT_PUNCTUATION;if(!e.punctuation)return t;var n=e.punctuation,i=n.insertAfterWord;i!==\\\"\\\"&&!i&&(i=t.insertAfterWord);var a=n.quotesForKeepSuggestion;a||(a=t.quotesForKeepSuggestion);var u=n.isRTL;return{insertAfterWord:i,quotesForKeepSuggestion:a,isRTL:u}},r.prototype.acceptSuggestion=function(e,t,n){var i=e.transform,a=t.left.kmwSubstr(-i.deleteLeft,i.deleteLeft),u=i.insert.kmwLength(),o={insert:a,deleteLeft:u},l=t;n&&(o=buildMergedTransform(o,n),l=applyTransform(n,l));var s,f=this.tokenize(l);f?(f.left.length>0?s=f.left[f.left.length-1]:s=\\\"\\\",s+=f.caretSplitsToken?f.right[0]:\\\"\\\"):s=this.wordbreak(l);var c=transformToSuggestion(o);c.displayAs=s;var d=this.toAnnotatedSuggestion(c,\\\"revert\\\");if(e.transformId!=null&&(d.transformId=-e.transformId),e.id!=null?d.id=-e.id:(d.id=-this.SUGGESTION_ID_SEED,this.SUGGESTION_ID_SEED++),this.contextTracker){var p=this.contextTracker.newest;p||(p=this.contextTracker.analyzeState(this.lexicalModel,t)),p.tail.activeReplacementId=e.id;var g=applyTransform(e.transform,t);this.contextTracker.analyzeState(this.lexicalModel,g)}return d},r.prototype.applyReversion=function(e,t){var n=this,i=v(function(){var s=applyTransform(e.transform,t),f=n.predict({insert:\\\"\\\",deleteLeft:0},s);return f.forEach(function(c){c.transformId=-e.transformId}),f},\\\"fallbackSuggestions\\\");if(!this.contextTracker)return i();for(var a=!1,u=this.contextTracker.count-1;u>=0;u--){var o=this.contextTracker.item(u);if(o.tail.activeReplacementId==-e.id){a=!0;break}}if(!a)return i();for(;this.contextTracker.newest.tail.activeReplacementId!=-e.id;)this.contextTracker.popNewest();this.contextTracker.newest.tail.revert();var l=this.contextTracker.newest.tail.replacements.map(function(s){return s.suggestion});return l.forEach(function(s){s.transformId=-e.transformId}),l},r.prototype.wordbreak=function(e){var t=this.lexicalModel;if(t.wordbreaker||!t.wordbreak){var n=t.wordbreaker||default_;return wordbreak(n,e)}else return t.wordbreak(e)},r.prototype.tokenize=function(e){var t=this.lexicalModel;return t.wordbreaker?tokenize(t.wordbreaker,e):null},r.prototype.resetContext=function(e){if(this.contextTracker){var t=tokenize(this.lexicalModel.wordbreaker||default_,e),n=ContextTracker.modelContextState(t.left,null,this.lexicalModel);this.contextTracker.enqueue(n)}},r.prototype.detectCurrentCasing=function(e){var t,n=this.lexicalModel,i=this.wordbreak(e);if(!n.languageUsesCasing)throw\\\"Invalid attempt to detect casing: languageUsesCasing is set to false\\\";if(!n.applyCasing)throw\\\"Invalid LMLayer state: languageUsesCasing is set to true, but no applyCasing function exists\\\";return e.casingForm==\\\"upper\\\"||e.casingForm==\\\"initial\\\"?e.casingForm:n.applyCasing(\\\"lower\\\",i)==i?\\\"lower\\\":n.applyCasing(\\\"upper\\\",i)==i?i.kmwLength()>1?\\\"upper\\\":\\\"initial\\\":n.applyCasing(\\\"initial\\\",i)==i?\\\"initial\\\":(t=e.casingForm)!==null&&t!==void 0?t:null},r.MAX_SUGGESTIONS=12,r.SINGLE_CHAR_KEY_PROB_EXPONENT=16,r}(),model_compositor_default=ModelCompositor,DEFAULT_PUNCTUATION={quotesForKeepSuggestion:{open:\\\"\\\\u201C\\\",close:\\\"\\\\u201D\\\"},insertAfterWord:\\\" \\\"};extendString();var LMLayerWorker=function(){function r(e){e===void 0&&(e={importScripts:null,postMessage:null}),this._testMode=!1,this._postMessage=e.postMessage||postMessage,this._importScripts=e.importScripts||importScripts,this.setupConfigState()}return v(r,\\\"LMLayerWorker2\\\"),r.prototype.error=function(e,t){this.cast(\\\"error\\\",{log:e,error:t&&t.stack?t.stack:void 0})},r.prototype.onMessage=function(e){var t=e.data.message;if(!t)throw new Error(\\\"Missing required 'message' property: \\\".concat(e.data));var n=e.data;if(n.message==\\\"load\\\"){var i=n,a=!1;if(this._currentModelSource&&i.source.type==this._currentModelSource.type&&(i.source.type==\\\"file\\\"&&i.source.file==this._currentModelSource.file||i.source.type==\\\"raw\\\"&&i.source.code==this._currentModelSource.code)&&(a=!0),a){typeof console!=\\\"undefined\\\"&&console.warn(\\\"Duplicate model load message detected - squashing!\\\");return}else this._currentModelSource=i.source}else n.message==\\\"unload\\\"&&(this._currentModelSource=null);this.state.handleMessage(n)},r.prototype.cast=function(e,t){var n=this._postMessage;n((0,build_exports.__assign)({message:e},t))},r.prototype.loadModel=function(e){try{var t=e.configure(this._platformCapabilities);t.leftContextCodePoints||(t.leftContextCodePoints=t.leftContextCodeUnits),t.rightContextCodePoints||(t.rightContextCodePoints=t.rightContextCodeUnits),t.leftContextCodePoints||(t.leftContextCodePoints=this._platformCapabilities.maxLeftContextCodePoints),t.rightContextCodePoints||(t.rightContextCodePoints=this._platformCapabilities.maxRightContextCodePoints||0),e.languageUsesCasing&&!e.applyCasing&&(e.applyCasing=defaultApplyCasing);var n=this.transitionToReadyState(e);t.wordbreaksAfterSuggestions===void 0&&(t.wordbreaksAfterSuggestions=n.punctuation.insertAfterWord!=\\\"\\\"),this.cast(\\\"ready\\\",{configuration:t})}catch(i){this.error(\\\"loadModel failed!\\\",i)}},r.prototype.loadModelFile=function(e){try{this._importScripts(e)}catch(t){this.error(\\\"Error occurred when attempting to load dictionary\\\",t)}},r.prototype.unloadModel=function(){this.transitionToLoadingState()},r.prototype.setupConfigState=function(){var e=this;this.state={name:\\\"unconfigured\\\",handleMessage:function(t){if(t.message!==\\\"config\\\")throw new Error(\\\"invalid message; expected 'config' but got \\\".concat(t.message));e._platformCapabilities=t.capabilities,e._testMode=!!t.testMode,e.transitionToLoadingState()}}},r.prototype.transitionToLoadingState=function(){var e=this;this.state={name:\\\"modelless\\\",handleMessage:function(t){if(t.message!==\\\"load\\\")throw new Error(\\\"invalid message; expected 'load' but got \\\".concat(t.message));if(t.source.type==\\\"file\\\")e.loadModelFile(t.source.file);else{var n=t.source.code,i=new Function(\\\"LMLayerWorker\\\",\\\"models\\\",\\\"correction\\\",\\\"wordBreakers\\\",n);i(e,models_exports,correction_exports,obj_exports)}}}},r.prototype.transitionToReadyState=function(e){var t=this,n=new model_compositor_default(e,this._testMode);return this.state={name:\\\"ready\\\",handleMessage:function(i){switch(i.message){case\\\"predict\\\":var a=i.transform,c=i.context,f=n.predict(a,c);t.cast(\\\"suggestions\\\",{token:i.token,suggestions:f});break;case\\\"wordbreak\\\":var u=wordbreak(e.wordbreaker||default_,i.context);t.cast(\\\"currentword\\\",{token:i.token,word:u});break;case\\\"unload\\\":t.unloadModel();break;case\\\"accept\\\":var o=i.suggestion,c=i.context,l=i.postTransform,s=n.acceptSuggestion(o,c,l);t.cast(\\\"postaccept\\\",{token:i.token,reversion:s});break;case\\\"revert\\\":var s=i.reversion,c=i.context,f=n.applyReversion(s,c);t.cast(\\\"postrevert\\\",{token:i.token,suggestions:f});break;case\\\"reset-context\\\":var c=i.context;n.resetContext(c);break;default:throw new Error(\\\"invalid message; expected one of {'predict', 'wordbreak', 'accept', 'revert', 'reset-context', 'unload'} but got \\\".concat(i.message))}},compositor:n},n},r.install=function(e){var t=new r({postMessage:e.postMessage,importScripts:e.importScripts.bind(e)});return e.onmessage=t.onMessage.bind(t),t.self=e,e.LMLayerWorker=t,e.models=models_exports,e.correction=correction_exports,e.wordBreakers=obj_exports,t},r}(),obj_default=LMLayerWorker;typeof self!=\\\"undefined\\\"&&\\\"postMessage\\\"in self&&\\\"importScripts\\\"in self?obj_default.install(self):window.LMLayerWorker=obj_default;\\n\";\n\n// Sourcemaps have been omitted for this release build.\nexport var LMLayerWorkerSourcemapComment = \"\";\n\n// --END:LMLayerWorkerCode\n", + "import unwrap from '../unwrap.js';\r\nimport { LMLayerWorkerCode, LMLayerWorkerSourcemapComment } from \"@keymanapp/lm-worker/worker-main.wrapped.min.js\";\r\n\r\nexport default class DefaultWorker {\r\n static constructInstance(): Worker {\r\n return new Worker(this.asBlobURI(LMLayerWorkerCode));\r\n }\r\n\r\n /**\r\n * Converts the INSIDE of a function into a blob URI that can\r\n * be passed as a valid URI for a Worker.\r\n * @param fn Function whose body will be referenced by a URI.\r\n *\r\n * This function makes the following possible:\r\n *\r\n * let worker = new Worker(LMLayer.asBlobURI(function myWorkerCode () {\r\n * postMessage('inside Web Worker')\r\n * function onmessage(event) {\r\n * // handle message inside Web Worker.\r\n * }\r\n * }));\r\n */\r\n static asBlobURI(encodedSrc: string): string {\r\n let code = unwrap(encodedSrc);\r\n\r\n // If this is definitively set to either true or false, tree-shaking can take effect.\r\n // An imported const variable doesn't seem to do it, though.\r\n // if(false) {\r\n code += '\\n' + LMLayerWorkerSourcemapComment;\r\n // }\r\n let blob = new Blob([code], { type: 'text/javascript' });\r\n return URL.createObjectURL(blob);\r\n }\r\n}", + "// Defines a 'polyfill' of sorts for NPM's events module\r\n\r\n/// \r\n\r\nimport ContextWindow from \"./contextWindow.js\";\r\nimport LanguageProcessor from \"./prediction/languageProcessor.js\";\r\nimport type ModelSpec from \"./prediction/modelSpec.js\";\r\nimport { globalObject, DeviceSpec } from \"@keymanapp/web-utils\";\r\n\r\nimport {\r\n type Alternate,\r\n Codes,\r\n isEmptyTransform,\r\n type Keyboard,\r\n KeyboardInterface,\r\n KeyboardProcessor,\r\n type KeyEvent,\r\n Mock,\r\n type OutputTarget,\r\n type ProcessorInitOptions,\r\n RuleBehavior,\r\n SystemStoreIDs,\r\n type TextTransform\r\n} from \"@keymanapp/keyboard-processor\";\r\n\r\nexport default class InputProcessor {\r\n public static readonly DEFAULT_OPTIONS: ProcessorInitOptions = {\r\n baseLayout: 'us'\r\n }\r\n\r\n /**\r\n * Indicates the device (platform) to be used for non-keystroke events,\r\n * such as those sent to `begin postkeystroke` and `begin newcontext`\r\n * entry points.\r\n */\r\n private contextDevice: DeviceSpec;\r\n private kbdProcessor: KeyboardProcessor;\r\n private lngProcessor: LanguageProcessor;\r\n\r\n constructor(device: DeviceSpec, predictiveTextWorker: Worker, options?: ProcessorInitOptions) {\r\n if(!device) {\r\n throw new Error('device must be defined');\r\n }\r\n\r\n if(!options) {\r\n options = InputProcessor.DEFAULT_OPTIONS;\r\n }\r\n\r\n this.contextDevice = device;\r\n this.kbdProcessor = new KeyboardProcessor(device, options);\r\n this.lngProcessor = new LanguageProcessor(predictiveTextWorker);\r\n }\r\n\r\n public get languageProcessor(): LanguageProcessor {\r\n return this.lngProcessor;\r\n }\r\n\r\n public get keyboardProcessor(): KeyboardProcessor {\r\n return this.kbdProcessor;\r\n }\r\n\r\n public get keyboardInterface(): KeyboardInterface {\r\n return this.keyboardProcessor.keyboardInterface;\r\n }\r\n\r\n public get activeKeyboard(): Keyboard {\r\n return this.keyboardInterface.activeKeyboard;\r\n }\r\n\r\n public set activeKeyboard(keyboard: Keyboard) {\r\n this.keyboardInterface.activeKeyboard = keyboard;\r\n\r\n // All old deadkeys and keyboard-specific cache should immediately be invalidated\r\n // on a keyboard change.\r\n this.resetContext();\r\n }\r\n\r\n public get activeModel(): ModelSpec {\r\n return this.languageProcessor.activeModel;\r\n }\r\n\r\n /**\r\n * Simulate a keystroke according to the touched keyboard button element\r\n *\r\n * Handles default output and keyboard processing for both OSK and physical keystrokes.\r\n *\r\n * @param {Object} keyEvent The abstracted KeyEvent to use for keystroke processing\r\n * @param {Object} outputTarget The OutputTarget receiving the KeyEvent\r\n * @returns {Object} A RuleBehavior object describing the cumulative effects of\r\n * all matched keyboard rules.\r\n */\r\n processKeyEvent(keyEvent: KeyEvent, outputTarget: OutputTarget): RuleBehavior {\r\n const kbdMismatch = keyEvent.srcKeyboard && this.activeKeyboard != keyEvent.srcKeyboard;\r\n const trueActiveKeyboard = this.activeKeyboard;\r\n\r\n try {\r\n if(kbdMismatch) {\r\n // Avoid force-reset of context per our setter above.\r\n this.keyboardInterface.activeKeyboard = keyEvent.srcKeyboard;\r\n }\r\n\r\n return this._processKeyEvent(keyEvent, outputTarget);\r\n } finally {\r\n if(kbdMismatch) {\r\n // Restore our \"current\" activeKeyboard to its setting before the mismatching KeyEvent.\r\n this.keyboardInterface.activeKeyboard = trueActiveKeyboard;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Acts as the core of `processKeyEvent` once we're comfortable asserting that the incoming\r\n * keystroke matches the current `activeKeyboard`.\r\n * @param keyEvent\r\n * @param outputTarget\r\n * @returns\r\n */\r\n private _processKeyEvent(keyEvent: KeyEvent, outputTarget: OutputTarget): RuleBehavior {\r\n let formFactor = keyEvent.device.formFactor;\r\n let fromOSK = keyEvent.isSynthetic;\r\n\r\n // The default OSK layout for desktop devices does not include nextlayer info, relying on modifier detection here.\r\n // It's the OSK equivalent to doModifierPress on 'desktop' form factors.\r\n if((formFactor == DeviceSpec.FormFactor.Desktop || !this.activeKeyboard || this.activeKeyboard.usesDesktopLayoutOnDevice(keyEvent.device)) && fromOSK) {\r\n // If it's a desktop OSK style and this triggers a layer change,\r\n // a modifier key was clicked. No output expected, so it's safe to instantly exit.\r\n if(this.keyboardProcessor.selectLayer(keyEvent)) {\r\n return new RuleBehavior();\r\n }\r\n }\r\n\r\n // Will handle keystroke-based non-layer change modifier & state keys, mapping them through the physical keyboard's version\r\n // of state management. `doModifierPress` must always run.\r\n if(this.keyboardProcessor.doModifierPress(keyEvent, outputTarget, !fromOSK)) {\r\n // If run on a desktop platform, we know that modifier & state key presses may not\r\n // produce output, so we may make an immediate return safely.\r\n if(!fromOSK) {\r\n return new RuleBehavior();\r\n }\r\n }\r\n\r\n // If suggestions exist AND space is pressed, accept the suggestion and do not process the keystroke.\r\n // If a suggestion was just accepted AND backspace is pressed, revert the change and do not process the backspace.\r\n // We check the first condition here, while the prediction UI handles the second through the try__() methods below.\r\n if(this.languageProcessor.isActive) {\r\n // The following code relies on JS's logical operator \"short-circuit\" properties to prevent unwanted triggering of the second condition.\r\n\r\n // Can the suggestion UI revert a recent suggestion? If so, do that and swallow the backspace.\r\n if((keyEvent.kName == \"K_BKSP\" || keyEvent.Lcode == Codes.keyCodes[\"K_BKSP\"]) && this.languageProcessor.tryRevertSuggestion()) {\r\n return new RuleBehavior();\r\n // Can the suggestion UI accept an existing suggestion? If so, do that and swallow the space character.\r\n } else if((keyEvent.kName == \"K_SPACE\" || keyEvent.Lcode == Codes.keyCodes[\"K_SPACE\"]) && this.languageProcessor.tryAcceptSuggestion('space')) {\r\n return new RuleBehavior();\r\n }\r\n }\r\n\r\n // // ...end I3363 (Build 301)\r\n\r\n // Create a \"mock\" backup of the current outputTarget in its pre-input state.\r\n // Current, long-existing assumption - it's DOM-backed.\r\n let preInputMock = Mock.from(outputTarget, true);\r\n\r\n const startingLayerId = this.keyboardProcessor.layerId;\r\n\r\n // We presently need the true keystroke to run on the FULL context. That index is still\r\n // needed for some indexing operations when comparing two different output targets.\r\n let ruleBehavior = this.keyboardProcessor.processKeystroke(keyEvent, outputTarget);\r\n\r\n // Swap layer as appropriate.\r\n if(keyEvent.kNextLayer) {\r\n this.keyboardProcessor.selectLayer(keyEvent);\r\n }\r\n\r\n // If it's a key that we 'optimize out' of our fat-finger correction algorithm,\r\n // we MUST NOT trigger it for this keystroke.\r\n let isOnlyLayerSwitchKey = Codes.isKnownOSKModifierKey(keyEvent.kName);\r\n\r\n // Best-guess stopgap for possible custom modifier keys.\r\n // If a key (1) does not affect the context and (2) shifts the active layer,\r\n // we assume it's a modifier key. (Touch keyboards may define custom modifier keys.)\r\n //\r\n // Note: this will mean we won't generate alternates in the niche scenario where:\r\n // 1. Keypress does not alter the actual context\r\n // 2. It DOES emit a deadkey with an earlier processing rule.\r\n // 3. The FINAL processing rule does not match.\r\n // 4. The key ALSO signals a layer shift.\r\n // If any of the four above conditions aren't met - no problem!\r\n // So it's a pretty niche scenario.\r\n\r\n if(isEmptyTransform(ruleBehavior?.transcription?.transform) && keyEvent.kNextLayer) {\r\n isOnlyLayerSwitchKey = true;\r\n }\r\n\r\n const keepRuleBehavior = ruleBehavior != null;\r\n // Should we swallow any further processing of keystroke events for this keydown-keypress sequence?\r\n if(keepRuleBehavior) {\r\n // alternates are our fat-finger alternate outputs. We don't build these for keys we detect as\r\n // layer switch keys\r\n let alternates = isOnlyLayerSwitchKey ? null : this.buildAlternates(ruleBehavior, keyEvent, preInputMock);\r\n\r\n // Now that we've done all the keystroke processing needed, ensure any extra effects triggered\r\n // by the actual keystroke occur.\r\n ruleBehavior.finalize(this.keyboardProcessor, outputTarget, false);\r\n\r\n // -- All keystroke (and 'alternate') processing is now complete. Time to finalize everything! --\r\n\r\n // Notify the ModelManager of new input - it's predictive text time!\r\n if(alternates && alternates.length > 0) {\r\n ruleBehavior.transcription.alternates = alternates;\r\n }\r\n } else {\r\n // We need a dummy RuleBehavior for keys which have no output (e.g. Shift)\r\n ruleBehavior = new RuleBehavior();\r\n ruleBehavior.transcription = outputTarget.buildTranscriptionFrom(outputTarget, null, false);\r\n ruleBehavior.triggersDefaultCommand = true;\r\n }\r\n\r\n // The keyboard may want to take an action after all other keystroke processing is\r\n // finished, for example to switch layers. This action may not have any output\r\n // but may change system store or variable store values. Given this, we don't need to\r\n // save anything about the post behavior, after finalizing it\r\n\r\n // We need to tell the keyboard if the layer has been changed, either by a keyboard rule itself,\r\n // or by the touch layout 'nextlayer' control.\r\n const hasLayerChanged = ruleBehavior.setStore[SystemStoreIDs.TSS_LAYER] || keyEvent.kNextLayer;\r\n this.keyboardProcessor.newLayerStore.set(hasLayerChanged ? this.keyboardProcessor.layerId : '');\r\n this.keyboardProcessor.oldLayerStore.set(hasLayerChanged ? startingLayerId : '');\r\n\r\n let postRuleBehavior = this.keyboardProcessor.processPostKeystroke(this.contextDevice, outputTarget);\r\n if(postRuleBehavior) {\r\n postRuleBehavior.finalize(this.keyboardProcessor, outputTarget, true);\r\n }\r\n\r\n // Yes, even for ruleBehavior.triggersDefaultCommand. Those tend to change the context.\r\n ruleBehavior.predictionPromise = this.languageProcessor.predict(ruleBehavior.transcription, this.keyboardProcessor.layerId);\r\n\r\n // Text did not change (thus, no text \"input\") if we tabbed or merely moved the caret.\r\n if(!ruleBehavior.triggersDefaultCommand) {\r\n // For DOM-aware targets, this will trigger a DOM event page designers may listen for.\r\n outputTarget.doInputEvent();\r\n }\r\n\r\n return keepRuleBehavior ? ruleBehavior : null;\r\n }\r\n\r\n private buildAlternates(ruleBehavior: RuleBehavior, keyEvent: KeyEvent, preInputMock: Mock): Alternate[] {\r\n let alternates: Alternate[];\r\n\r\n // If we're performing a 'default command', it's not a standard 'typing' event - don't do fat-finger stuff.\r\n // Also, don't do fat-finger stuff if predictive text isn't enabled.\r\n if(this.languageProcessor.isActive && !ruleBehavior.triggersDefaultCommand) {\r\n let keyDistribution = keyEvent.keyDistribution;\r\n\r\n // We don't need to track absolute indexing during alternate-generation;\r\n // only position-relative, so it's better to use a sliding window for context\r\n // when making alternates. (Slightly worse for short text, matters greatly\r\n // for long text.)\r\n let contextWindow = new ContextWindow(preInputMock, ContextWindow.ENGINE_RULE_WINDOW, this.keyboardProcessor.layerId);\r\n let windowedMock = contextWindow.toMock();\r\n\r\n // Note - we don't yet do fat-fingering with longpress keys.\r\n if(this.languageProcessor.isActive && keyDistribution && keyEvent.kbdLayer) {\r\n // Tracks a 'deadline' for fat-finger ops, just in case both context is long enough\r\n // and device is slow enough that the calculation takes too long.\r\n //\r\n // Consider use of https://developer.mozilla.org/en-US/docs/Web/API/Performance/now instead?\r\n // Would allow finer-tuned control.\r\n let TIMEOUT_THRESHOLD: number = Number.MAX_VALUE;\r\n let _globalThis = globalObject();\r\n let timer: () => number;\r\n\r\n // Available by default on `window` in browsers, but _not_ on `global` in Node,\r\n // surprisingly. Since we can't use code dependent on `require` statements\r\n // at present, we have to condition upon it actually existing.\r\n if(_globalThis['performance'] && _globalThis['performance']['now']) {\r\n timer = function() {\r\n return _globalThis['performance']['now']();\r\n };\r\n\r\n TIMEOUT_THRESHOLD = timer() + 16; // + 16ms.\r\n } // else {\r\n // We _could_ just use Date.now() as a backup... but that (probably) only matters\r\n // when unit testing. So... we actually don't _need_ time thresholding when in\r\n // a Node environment.\r\n // }\r\n\r\n // Tracks a minimum probability for keystroke probability. Anything less will not be\r\n // included in alternate calculations.\r\n //\r\n // Seek to match SearchSpace.EDIT_DISTANCE_COST_SCALE from the predictive-text engine.\r\n // Reasoning for the selected value may be seen there. Short version - keystrokes\r\n // that _appear_ very precise may otherwise not even consider directly-neighboring keys.\r\n let KEYSTROKE_EPSILON = Math.exp(-5);\r\n\r\n // Sort the distribution into probability-descending order.\r\n keyDistribution.sort((a, b) => b.p - a.p);\r\n\r\n let activeLayout = this.activeKeyboard.layout(keyEvent.device.formFactor);\r\n alternates = [];\r\n\r\n let totalMass = 0; // Tracks sum of non-error probabilities.\r\n for(let pair of keyDistribution) {\r\n if(pair.p < KEYSTROKE_EPSILON) {\r\n totalMass += pair.p;\r\n break;\r\n } else if(timer && timer() >= TIMEOUT_THRESHOLD) {\r\n // Note: it's always possible that the thread _executing_ our JS\r\n // got paused by the OS, even if JS itself is single-threaded.\r\n //\r\n // The case where `alternates` is initialized (line 167) but empty\r\n // (because of net-zero loop iterations) MUST be handled.\r\n break;\r\n }\r\n\r\n let mock = Mock.from(windowedMock, false);\r\n\r\n let altKey = activeLayout.getLayer(keyEvent.kbdLayer).getKey(pair.keyId);\r\n if(!altKey) {\r\n console.warn(\"Potential fat-finger key could not be found in layer!\");\r\n continue;\r\n }\r\n\r\n let altEvent = this.keyboardProcessor.activeKeyboard.constructKeyEvent(altKey, keyEvent.device, this.keyboardProcessor.stateKeys);\r\n let alternateBehavior = this.keyboardProcessor.processKeystroke(altEvent, mock);\r\n\r\n // If alternateBehavior.beep == true, ignore it. It's a disallowed key sequence,\r\n // so we expect users to never intend their use.\r\n //\r\n // Also possible that this set of conditions fail for all evaluated alternates.\r\n if(alternateBehavior && !alternateBehavior.beep && pair.p > 0) {\r\n let transform: Transform = alternateBehavior.transcription.transform;\r\n\r\n // Ensure that the alternate's token id matches that of the current keystroke, as we only\r\n // record the matched rule's context (since they match)\r\n transform.id = ruleBehavior.transcription.token;\r\n alternates.push({sample: transform, 'p': pair.p});\r\n totalMass += pair.p;\r\n }\r\n }\r\n\r\n // Renormalizes the distribution, as any error (beep) results\r\n // will result in a distribution that doesn't sum to 1 otherwise.\r\n // All `.p` values are strictly positive, so totalMass is\r\n // guaranteed to be > 0 if the array has entries.\r\n alternates.forEach(function(alt) {\r\n alt.p /= totalMass;\r\n });\r\n }\r\n }\r\n return alternates;\r\n }\r\n\r\n public resetContext(outputTarget?: OutputTarget) {\r\n // Also handles new-context events, which may modify the layer\r\n this.keyboardProcessor.resetContext(outputTarget);\r\n // With the layer now set, we trigger new predictions.\r\n this.languageProcessor.invalidateContext(outputTarget, this.keyboardProcessor.layerId);\r\n }\r\n}", + "import EventEmitter from \"eventemitter3\";\r\nimport type LanguageProcessor from \"./languageProcessor.js\";\r\nimport { type ReadySuggestions, type InvalidateSourceEnum, StateChangeEnum, StateChangeHandler } from './languageProcessor.js';\r\nimport { type KeyboardProcessor, type OutputTarget } from \"@keymanapp/keyboard-processor\";\r\n\r\ninterface PredictionContextEventMap {\r\n update: (suggestions: Suggestion[]) => void;\r\n}\r\n\r\n/**\r\n * Maintains predictive-text state information corresponding to the current context.\r\n */\r\nexport default class PredictionContext extends EventEmitter {\r\n // Historical note: before 17.0, this code was intertwined with /web/source/osk/banner.ts's\r\n // SuggestionBanner class. This class serves as the main implementation of the banner's core logic.\r\n\r\n // Designed for use with auto-correct behavior\r\n private selected: Suggestion;\r\n\r\n private initNewContext: boolean = true;\r\n\r\n private _currentSuggestions: Suggestion[] = [];\r\n private keepSuggestion: Keep;\r\n private revertSuggestion: Reversion;\r\n\r\n private recentAccept: boolean = false;\r\n private revertAcceptancePromise: Promise;\r\n\r\n private swallowPrediction: boolean = false;\r\n\r\n private doRevert: boolean = false;\r\n private recentRevert: boolean = false;\r\n\r\n private langProcessor: LanguageProcessor;\r\n private kbdProcessor: KeyboardProcessor;\r\n\r\n /**\r\n * Represents the active context used when requesting and applying predictive-text operations.\r\n */\r\n private _currentTarget: OutputTarget;\r\n\r\n public get currentTarget(): OutputTarget {\r\n return this._currentTarget;\r\n }\r\n\r\n public setCurrentTarget(target: OutputTarget): Promise {\r\n const originalTarget = this._currentTarget;\r\n this._currentTarget = target;\r\n\r\n if(originalTarget != target) {\r\n // Note: should be triggered after the corresponding new-context event rule has been processed,\r\n // as that may affect the value of layerId here.\r\n return this.resetContext();\r\n } else {\r\n return Promise.resolve([]);\r\n }\r\n }\r\n\r\n private readonly suggestionApplier: (suggestion: Suggestion) => Promise;\r\n private readonly suggestionReverter: (reversion: Reversion) => void;\r\n\r\n /**\r\n * Handler for post-processing once a suggestion has been applied: calls\r\n * into the active keyboard's `begin postKeystroke` entry point.\r\n *\r\n * Called after the suggestion is applied but _before_ new predictions are\r\n * requested based on the resulting context.\r\n */\r\n private readonly postApplicationHandler: () => void;\r\n\r\n public constructor(langProcessor: LanguageProcessor, kbdProcessor: KeyboardProcessor) {\r\n super();\r\n\r\n this.langProcessor = langProcessor;\r\n this.kbdProcessor = kbdProcessor;\r\n\r\n const validSuggestionState: () => boolean = () =>\r\n this.currentTarget && langProcessor.state == 'configured';\r\n\r\n this.suggestionApplier = (suggestion) => {\r\n if(validSuggestionState()) {\r\n return langProcessor.applySuggestion(suggestion, this.currentTarget, () => kbdProcessor.layerId);\r\n }\r\n }\r\n\r\n this.suggestionReverter = (reversion) => {\r\n if(validSuggestionState()) {\r\n langProcessor.applyReversion(reversion, this.currentTarget);\r\n }\r\n }\r\n\r\n // As it's called synchronously via event-callback during `this.suggestionApplier`,\r\n // `this.currentTarget` is guaranteed to remain unchanged.\r\n this.postApplicationHandler = () => {\r\n // Tell the keyboard that the current layer has not changed\r\n kbdProcessor.newLayerStore.set('');\r\n kbdProcessor.oldLayerStore.set('');\r\n // Call the keyboard's entry point.\r\n kbdProcessor.processPostKeystroke(kbdProcessor.contextDevice, this.currentTarget)\r\n // If we have a RuleBehavior as a result, run it on the target. This should\r\n // only change system store and variable store values.\r\n ?.finalize(kbdProcessor, this.currentTarget, true);\r\n };\r\n\r\n this.connect();\r\n }\r\n\r\n private connect() {\r\n this.langProcessor.addListener('invalidatesuggestions', this.invalidateSuggestions);\r\n this.langProcessor.addListener('suggestionsready', this.updateSuggestions);\r\n this.langProcessor.addListener('tryaccept', this.doTryAccept);\r\n this.langProcessor.addListener('tryrevert', this.doTryRevert);\r\n this.langProcessor.addListener('statechange', this.onModelStateChange);\r\n\r\n this.langProcessor.addListener('suggestionapplied', this.postApplicationHandler);\r\n }\r\n\r\n public disconnect() {\r\n this.langProcessor.removeListener('invalidatesuggestions', this.invalidateSuggestions);\r\n this.langProcessor.removeListener('suggestionsready', this.updateSuggestions);\r\n this.langProcessor.removeListener('tryaccept', this.doTryAccept);\r\n this.langProcessor.removeListener('tryrevert', this.doTryRevert);\r\n this.langProcessor.removeListener('statechange', this.onModelStateChange);\r\n\r\n this.langProcessor.removeListener('suggestionapplied', this.postApplicationHandler);\r\n this.clearSuggestions();\r\n }\r\n\r\n public get currentSuggestions(): Suggestion[] {\r\n let suggestions = [];\r\n // Insert 'current text' if/when valid as the leading option.\r\n // Since we don't yet do auto-corrections, we only show 'keep' whenever it's\r\n // a valid word (according to the model).\r\n\r\n if(this.activateKeep() && this.keepSuggestion && this.keepSuggestion.matchesModel) {\r\n suggestions.push(this.keepSuggestion);\r\n } else if(this.doRevert) {\r\n suggestions.push(this.revertSuggestion);\r\n }\r\n\r\n return suggestions.concat(this._currentSuggestions);\r\n }\r\n\r\n /**\r\n * Function apply\r\n * Description Applies the predictive `Suggestion` represented by this `BannerSuggestion`.\r\n */\r\n private acceptInternal(suggestion: Suggestion): Promise {\r\n if(!suggestion) {\r\n return null;\r\n }\r\n\r\n // Should be safe to convert into an event handled externally.\r\n // layerID can be obtained by whoever/whatever holds the InputProcessor instance.\r\n if(suggestion.tag == 'revert') {\r\n this.suggestionReverter(suggestion as Reversion);\r\n return null;\r\n } else {\r\n return this.suggestionApplier(suggestion);\r\n }\r\n }\r\n\r\n /**\r\n * Applies predictive-text suggestions and post-acceptance reversions to the current\r\n * prediction context.\r\n *\r\n * Note that both cases will additionally trigger a new asynchronous `predict` operation,\r\n * though no corresponding Promise is returned by this function. As such, the current\r\n * suggestions should be considered outdated after calling this method, pending replacement\r\n * upon the completed async `predict`.\r\n *\r\n * @param suggestion Either a `Suggestion` or `Reversion`.\r\n * @returns if `suggestion` is a `Suggestion`, will return a `Promise`; else, `null`.\r\n */\r\n public accept(suggestion: Suggestion): Promise | null {\r\n let _this = this;\r\n\r\n // Selecting a suggestion or a reversion should both clear selection\r\n // and clear the reversion-displaying state of the banner.\r\n this.selected = null;\r\n this.doRevert = false;\r\n\r\n this.revertAcceptancePromise = this.acceptInternal(suggestion);\r\n if(!this.revertAcceptancePromise) {\r\n // We get here either if suggestion acceptance fails or if it was a reversion.\r\n if(suggestion && suggestion.tag == 'revert') {\r\n // Reversion state management\r\n this.recentAccept = false;\r\n this.recentRevert = true;\r\n }\r\n return null;\r\n }\r\n\r\n this.revertAcceptancePromise.then(function(suggestion) {\r\n // Always null-check!\r\n if(suggestion) {\r\n _this.revertSuggestion = suggestion;\r\n }\r\n });\r\n\r\n this.recentAccept = true;\r\n this.recentRevert = false;\r\n\r\n this.swallowPrediction = true;\r\n\r\n return this.revertAcceptancePromise;\r\n }\r\n\r\n private showRevert() {\r\n // Construct a 'revert suggestion' to facilitate a reversion UI component.\r\n this.doRevert = true;\r\n this.sendUpdateEvent();\r\n }\r\n\r\n /**\r\n * Receives messages from the keyboard that the 'accept' keystroke has been entered.\r\n * Should return 'false' if the current state allows accepting a suggestion and act accordingly.\r\n * Otherwise, return true.\r\n */\r\n private doTryAccept = (source: string /*, returnObj: {shouldSwallow: boolean}*/): void => {\r\n //let keyman = com.keyman.singleton;\r\n\r\n if(!this.recentAccept && this.selected) {\r\n this.accept(this.selected);\r\n // returnObj.shouldSwallow = true;\r\n } else if(this.recentAccept && source == 'space') {\r\n this.recentAccept = false;\r\n // // If the model doesn't insert wordbreaks, don't swallow the space. If it does,\r\n // // we consider that insertion to be the results of the first post-accept space.\r\n // returnObj.shouldSwallow = !!keyman.core.languageProcessor.wordbreaksAfterSuggestions; // can be handed outside\r\n } else {\r\n // returnObj.shouldSwallow = false;\r\n }\r\n }\r\n\r\n /**\r\n * Receives messages from the keyboard that the 'revert' keystroke has been entered.\r\n * Should return 'false' if the current state allows reverting a recently-applied suggestion and act accordingly.\r\n * Otherwise, return true.\r\n */\r\n private doTryRevert = (/*returnObj: {shouldSwallow: boolean}*/): boolean => {\r\n // Has the revert keystroke (BKSP) already been sent once since the last accept?\r\n if(this.doRevert) {\r\n // If so, clear the 'revert' option and start doing normal predictions again.\r\n this.doRevert = false;\r\n this.recentAccept = false;\r\n // Otherwise, did we just accept something before the revert signal was received?\r\n } else if(this.recentAccept) {\r\n this.showRevert();\r\n this.swallowPrediction = true;\r\n }\r\n\r\n // // We don't yet actually do key-based reversions.\r\n // returnObj.shouldSwallow = false;\r\n return;\r\n }\r\n\r\n /**\r\n * Function invalidateSuggestions\r\n * Scope Public\r\n * Description Clears the suggestions in the suggestion banner\r\n */\r\n private invalidateSuggestions = (source: InvalidateSourceEnum): void => {\r\n // By default, we assume that the context is the same until we notice otherwise.\r\n this.initNewContext = false;\r\n\r\n if(!this.swallowPrediction || source == 'context') {\r\n this.recentAccept = false;\r\n this.doRevert = false;\r\n this.recentRevert = false;\r\n\r\n if(source == 'context') {\r\n this.swallowPrediction = false;\r\n this.initNewContext = true;\r\n }\r\n }\r\n\r\n // Not checking this can result in a perceptible 'flash' of sorts due to the suggestion-update delay.\r\n if(source != 'new') {\r\n this.clearSuggestions();\r\n // this.options.forEach((option: BannerSuggestion) => {\r\n // option.update(null);\r\n // });\r\n }\r\n }\r\n\r\n private clearSuggestions() {\r\n this.updateSuggestions({\r\n suggestions: [],\r\n transcriptionID: 0\r\n });\r\n }\r\n\r\n private activateKeep(): boolean {\r\n return !this.recentAccept && !this.recentRevert && !this.initNewContext;\r\n }\r\n\r\n /**\r\n * Function updateSuggestions\r\n * Scope Public\r\n * @param {Suggestion[]} suggestions Array of suggestions from the lexical model.\r\n * Description Update the displayed suggestions in the SuggestionBanner\r\n */\r\n private updateSuggestions = (prediction: ReadySuggestions): void => {\r\n let suggestions = prediction.suggestions;\r\n\r\n this._currentSuggestions = suggestions;\r\n\r\n // Do we have a keep suggestion? If so, remove it from the list so that we can control its display position\r\n // and prevent it from being hidden after reversion operations.\r\n this.keepSuggestion = null;\r\n for(let s of suggestions) {\r\n if(s.tag == 'keep') {\r\n this.keepSuggestion = s as Keep;\r\n }\r\n }\r\n\r\n if(this.keepSuggestion) {\r\n this._currentSuggestions.splice(this._currentSuggestions.indexOf(this.keepSuggestion), 1);\r\n }\r\n\r\n // If we've gotten an update request like this, it's almost always user-triggered and means the context has shifted.\r\n if(!this.swallowPrediction) {\r\n this.recentAccept = false;\r\n this.doRevert = false;\r\n this.recentRevert = false;\r\n } else { // This prediction was triggered by a recent 'accept.' Now that it's fulfilled, we clear the flag.\r\n this.swallowPrediction = false;\r\n }\r\n\r\n // The rest is the same, whether from input or from \"self-updating\" after a reversion to provide new suggestions.\r\n this.sendUpdateEvent();\r\n }\r\n\r\n public sendUpdateEvent() {\r\n this.emit('update', this.currentSuggestions);\r\n }\r\n\r\n public resetContext(): Promise {\r\n const target = this.currentTarget;\r\n\r\n if(target) {\r\n // Note: should be triggered after the corresponding new-context event rule has been processed,\r\n // as that may affect the value of layerId here.\r\n return this.langProcessor.invalidateContext(target, this.kbdProcessor.layerId);\r\n } else {\r\n return Promise.resolve([]);\r\n }\r\n }\r\n\r\n private onModelStateChange: StateChangeHandler = (state) => {\r\n // Either way, the model has changed; either state marks the completion of such a transition.\r\n // The 'active' state displays the banner while a model loads... but its predictions are\r\n // only possible once fully 'configured'. They may appear to 'blink on' after a small delay\r\n // as a result.\r\n if(state == 'configured' || state == 'inactive') {\r\n this.resetContext();\r\n }\r\n }\r\n}", + "class DomEventTracking {\r\n Pelem: EventTarget;\r\n Peventname: string;\r\n Phandler: (Object) => boolean;\r\n PuseCapture?: boolean\r\n\r\n constructor(Pelem: EventTarget, Peventname: string, Phandler: (Object) => boolean, PuseCapture?: boolean) {\r\n this.Pelem = Pelem;\r\n this.Peventname = Peventname.toLowerCase();\r\n this.Phandler = Phandler;\r\n this.PuseCapture = PuseCapture;\r\n }\r\n\r\n equals(other: DomEventTracking): boolean {\r\n return this.Pelem == other.Pelem && this.Peventname == other.Peventname &&\r\n this.Phandler == other.Phandler && this.PuseCapture == other.PuseCapture;\r\n }\r\n};\r\n\r\n/**\r\n * Facilitates adding and removing event listeners to and from DOM elements in a manner\r\n * that allows widespread removal/cleanup of the listeners at a future time if and when needed.\r\n *\r\n * Said \"widespread removal\" helps to prevent separate instances of KeymanWeb from stomping on\r\n * each other during unit tests.\r\n */\r\nexport class DomEventTracker {\r\n private domEvents: DomEventTracking[] = [];\r\n\r\n /**\r\n * Function attachDOMEvent: Note for most browsers, adds an event to a chain, doesn't stop existing events\r\n * Scope Public\r\n * @param {Object} Pelem Element (or IFrame-internal Document) to which event is being attached\r\n * @param {string} Peventname Name of event without 'on' prefix\r\n * @param {function(Object)} Phandler Event handler for event\r\n * @param {boolean=} PuseCapture True only if event to be handled on way to target element\r\n * Description Attaches event handler to element DOM event\r\n */\r\n attachDOMEvent(\r\n Pelem: Window,\r\n Peventname: K,\r\n Phandler: (ev: WindowEventMap[K]) => any,\r\n PuseCapture?: boolean\r\n ): void;\r\n attachDOMEvent(\r\n Pelem: Document,\r\n Peventname: K,\r\n Phandler: (ev: DocumentEventMap[K]) => any,\r\n PuseCapture?: boolean\r\n ): void;\r\n attachDOMEvent(\r\n Pelem: HTMLElement,\r\n Peventname: K,\r\n Phandler: (ev: HTMLElementEventMap[K]) => any,\r\n PuseCapture?: boolean\r\n ): void;\r\n attachDOMEvent(Pelem: EventTarget, Peventname: string, Phandler: (Object) => boolean, PuseCapture?: boolean): void {\r\n // @ts-ignore // Since the trickery unfortunately don't also clear things up for anything we call within.\r\n // It's possible to fix, but that gets way more complex to spec out completely.\r\n this.detachDOMEvent(Pelem, Peventname, Phandler, PuseCapture);\r\n Pelem.addEventListener(Peventname, Phandler, PuseCapture ? true : false);\r\n\r\n // Since we're attaching to the DOM, these events should be tracked for detachment during shutdown.\r\n var event = new DomEventTracking(Pelem, Peventname, Phandler, PuseCapture);\r\n this.domEvents.push(event);\r\n }\r\n\r\n /**\r\n * Function detachDOMEvent\r\n * Scope Public\r\n * @param {Object} Pelem Element from which event is being detached\r\n * @param {string} Peventname Name of event without 'on' prefix\r\n * @param {function(Object)} Phandler Event handler for event\r\n * @param {boolean=} PuseCapture True if event was being handled on way to target element\r\n * Description Detaches event handler from element [to prevent memory leaks]\r\n */\r\n detachDOMEvent(\r\n Pelem: Window,\r\n Peventname: K,\r\n Phandler: (ev: WindowEventMap[K]) => any,\r\n PuseCapture?: boolean\r\n ): void;\r\n detachDOMEvent(\r\n Pelem: Document,\r\n Peventname: K,\r\n Phandler: (ev: DocumentEventMap[K]) => any,\r\n PuseCapture?: boolean\r\n ): void;\r\n detachDOMEvent(\r\n Pelem: HTMLElement,\r\n Peventname: K,\r\n Phandler: (ev: HTMLElementEventMap[K]) => any,\r\n PuseCapture?: boolean\r\n ): void;\r\n detachDOMEvent(Pelem: EventTarget, Peventname: string, Phandler: (Object) => boolean, PuseCapture?: boolean): void {\r\n Pelem.removeEventListener(Peventname, Phandler, PuseCapture);\r\n\r\n // Since we're detaching, we should drop the tracking data from the old event.\r\n var event = new DomEventTracking(Pelem, Peventname, Phandler, PuseCapture);\r\n for(var i = 0; i < this.domEvents.length; i++) {\r\n if(this.domEvents[i].equals(event)) {\r\n this.domEvents.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n shutdown() {\r\n // Remove all events linking to elements of the original, unaltered page.\r\n // This should sever any still-existing page ties to this instance of KMW,\r\n // allowing browser GC to do its thing.\r\n for(let event of this.domEvents) {\r\n // @ts-ignore // since it's simpler this way and doesn't earn us much to re-check types.\r\n this.detachDOMEvent(event.Pelem, event.Peventname, event.Phandler, event.PuseCapture);\r\n }\r\n }\r\n}", + "import EventEmitter, { EventNames, EventListener } from \"eventemitter3\";\r\nimport { LegacyEventEmitter } from \"./legacyEventEmitter.js\";\r\n\r\ninterface EventMap {\r\n // Provides IntelliSense suggestions in conditionals based on the parameters!\r\n\r\n /**\r\n * Indicates that a listener for the named event has been registered for the\r\n * EventEmitter being spied upon.\r\n * @param eventName\r\n */\r\n listeneradded(eventName: EventNames);\r\n\r\n /**\r\n * Indicates that a listener for the named event has been unregistered from the\r\n * EventEmitter being spied upon.\r\n * @param eventName\r\n */\r\n listenerremoved(eventName: EventNames);\r\n}\r\n\r\ntype Emitter = EventEmitter | LegacyEventEmitter;\r\n\r\n/**\r\n * A spy-object that wraps event-emitters in order to listen in on listener addition methods and\r\n * raise events when new listeners are attached.\r\n */\r\nexport class EmitterListenerSpy extends EventEmitter> {\r\n constructor(emitter: Emitter) {\r\n super();\r\n\r\n if(emitter instanceof EventEmitter) {\r\n emitter.on = this.listenerRegistrationSpy('listeneradded', emitter, emitter.on);\r\n emitter.addListener = this.listenerRegistrationSpy('listeneradded', emitter, emitter.addListener);\r\n emitter.off = this.listenerRegistrationSpy('listenerremoved', emitter, emitter.off);\r\n emitter.removeListener = this.listenerRegistrationSpy('listenerremoved', emitter, emitter.off);\r\n } else {\r\n // TS gets really fussy about how the legacy event typing is a bit more\r\n // restrictive (due to less-restricted event name types in EventEmitter)\r\n // It's not worth the effort to make this 100% perfect at the moment.\r\n //\r\n // @ts-ignore\r\n emitter.addEventListener = this.listenerRegistrationSpy('listeneradded', emitter, emitter.addEventListener);\r\n // @ts-ignore\r\n emitter.removeEventListener = this.listenerRegistrationSpy('listenerremoved', emitter, emitter.removeEventListener);\r\n }\r\n }\r\n\r\n /**\r\n * Given an event emitter and one of its methods used to register or unregister associated events,\r\n * this method will construct a replacement method that calls the original AND raises the specified\r\n * corresponding listener event provided by this class afterward. The replacement method\r\n * should be assigned to the emitter afterward, overwriting the original version.\r\n *\r\n * Refer to https://stackoverflow.com/a/10057969.\r\n */\r\n private listenerRegistrationSpy(\r\n spyEventName: EventNames>,\r\n emitter: Emitter,\r\n method: (\r\n eventName: EventNames,\r\n listener: EventListener>,\r\n ) => any\r\n ): ( // returns a method of the same signature as the original implementation.\r\n eventName: EventNames,\r\n listener: EventListener>,\r\n ) => any {\r\n return (eventName, listener) => {\r\n const retVal = method.apply(emitter, [eventName, listener]);\r\n this.emit(spyEventName, eventName);\r\n return retVal;\r\n }\r\n }\r\n}\r\n\r\n/**** A code block for verifying that typing, etc checks out: ****/\r\n\r\n// interface TestMap {\r\n// 'a': (str: string) => void;\r\n// 'b': (num: number, str: string) => void;\r\n// }\r\n\r\n// const emitter = new LegacyEventEmitter; // or `new EventEmitter`.\r\n// const emitterSpy = new EmitterListenerSpy(emitter);\r\n// emitterSpy.on('listeneradded', (eventName) => {\r\n// // eventName = 'c'; // will error; there is no event 'c' in the event map.\r\n// if(eventName == 'a') {\r\n// // stuff\r\n// }\r\n// })", + "// Most of the typing below is derived from that of EventEmitter, but customized for\r\n// modeling legacy KMW events. Including the heavy typing gets us event Intellisense\r\n// and compile-time errors if and when types don't match expectations.\r\n\r\n/**\r\n * Can define the set of events as follows:\r\n * ```\r\n * interface Test extends EventMap {\r\n * 'event': (param: {'prop': any}) => boolean;\r\n * }\r\n * ```\r\n *\r\n * Each event may have either no parameters or a single parameter of type object.\r\n * The type definition of the parameter will be utilized by TS's type-inference engine\r\n * for type checking on handlers and for raising the event.\r\n *\r\n * Note: the `extends EventMap` part is actually important for TS type inference here.\r\n */\r\nexport type LegacyEventMap = object;\r\n\r\n/**\r\n * Matches the name of any single event defined within the specified event-map definition.\r\n */\r\nexport type EventNames = Exclude;\r\n\r\n/**\r\n * Builds a type-array of the arguments for each named event, indexed by that name.\r\n */\r\ntype ArgumentMap = {\r\n [K in Exclude]: T[K] extends (arg: any) => boolean\r\n ? Parameters[0]\r\n : (\r\n T[K] extends Function\r\n ? never\r\n : T[K]\r\n );\r\n};\r\n\r\n/**\r\n * Provides the type signature of event listeners able to handle defined events.\r\n */\r\nexport type EventListener<\r\n T extends LegacyEventMap,\r\n K extends EventNames\r\n > = ( // argumentMap[eventName] - retrieves the specific parameter typing for the event.\r\n args: ArgumentMap[Extract]\r\n ) => any;\r\n\r\n/**\r\n * Provides fairly strong typing for all legacy KMW events. Note that all events\r\n * assume a handler receiving up to one object, though that object's properties will\r\n * vary from event to event.\r\n *\r\n * Note that the behavior differs from EventEmitter events on a few points:\r\n * 1. Event functions are expected to return a boolean value - generally, `true`.\r\n * If 'false' or `undefined` is returned, no further listeners will receive the event.\r\n * 2. These events receive up to one parameter, always of an object type.\r\n * 3. These events proactively prevent accidental event-handler recursion. Should an event's\r\n * handler retrigger the event, the newly-triggered event will be prevented entirely.\r\n */\r\nexport class LegacyEventEmitter {\r\n // An object mapping event names to individual event lists. Maps strings to arrays.\r\n private events: { [name: string]: ((Object) => boolean)[];} = {};\r\n private currentEvents: string[] = []; // The event messaging call stack.\r\n\r\n /**\r\n * Function addEventListener\r\n * Scope Private\r\n * @param {string} event name of event prefixed by module, e.g. osk.touchmove\r\n * @param {function(Object)} func event handler\r\n * @return {boolean}\r\n * Description Add (or replace) an event listener for this component\r\n */\r\n addEventListener> (\r\n event: T,\r\n func: EventListener\r\n ): boolean {\r\n this._removeEventListener(event, func);\r\n this.events[event].push(func);\r\n return true;\r\n }\r\n\r\n /**\r\n * Function removeEventListener\r\n * Scope Private\r\n * @param {string} event name of event prefixed by module, e.g. osk.touchmove\r\n * @param {function(Object)} func event handler\r\n * @return {boolean}\r\n * Description Remove the specified function from the listeners for this event\r\n */\r\n public removeEventListener> (\r\n event: T,\r\n func: EventListener\r\n ): boolean {\r\n return this._removeEventListener(event, func);\r\n }\r\n\r\n // Separate, in order to prevent `addEventListener` from sending 'listenerremoved' events with\r\n // EmitterListenerSpy.\r\n private _removeEventListener> (\r\n event: T,\r\n func: EventListener\r\n ): boolean {\r\n if(typeof this.events[event] == 'undefined') {\r\n this.events[event] = [];\r\n }\r\n\r\n for(var i=0; i> (\r\n event: T,\r\n params: ArgumentMap[T]\r\n ): boolean {\r\n if(typeof this.events[event] == 'undefined') {\r\n return true;\r\n }\r\n\r\n if(this.currentEvents.indexOf(event) != -1) {\r\n return false; // Avoid event messaging recursion!\r\n }\r\n\r\n this.currentEvents.push(event);\r\n\r\n for(var i=0; i, result=false;\r\n try {\r\n result=func(params as any);\r\n } catch(strExcept) {\r\n console.error(strExcept);\r\n result=false;\r\n } //don't know whether to use true or false here\r\n if(result === false) {\r\n this.currentEvents.pop();\r\n return false;\r\n }\r\n }\r\n this.currentEvents.pop();\r\n return true;\r\n }\r\n\r\n listenerCount>(event: T) {\r\n const listeners = this.events[event];\r\n return listeners ? listeners.length : 0;\r\n }\r\n\r\n shutdown() {\r\n // Remove all event-handler references rooted in KMW events.\r\n this.events = {};\r\n }\r\n}\r\n", + "import { ManagedPromise } from '@keymanapp/keyboard-processor';\r\nimport CloudRequesterInterface from './cloud/requesterInterface.js';\r\nimport { CLOUD_MALFORMED_OBJECT_ERR, CLOUD_TIMEOUT_ERR, CLOUD_STUB_REGISTRATION_ERR } from './cloud/queryEngine.js';\r\n\r\nexport default class DOMCloudRequester implements CloudRequesterInterface {\r\n private readonly fileLocal: boolean;\r\n\r\n constructor(fileLocal: boolean = false) {\r\n this.fileLocal = fileLocal;\r\n }\r\n\r\n request(query: string) {\r\n let promise = new ManagedPromise();\r\n\r\n // Set callback timer\r\n const timeoutID = window.setTimeout(() => {\r\n promise.reject(new Error(CLOUD_TIMEOUT_ERR));\r\n }, 10000);\r\n\r\n const tFlag='&timerid='+ timeoutID;\r\n const fullRef = query + tFlag;\r\n\r\n const Lscript: HTMLScriptElement = document.createElement('script');\r\n Lscript.onload = (event: Event) => {\r\n window.clearTimeout(timeoutID);\r\n\r\n // This case should only happen if a returned, otherwise-valid keyboard\r\n // script does not ever call `register`. Also provides default handling\r\n // should `register` fail to report results/failure correctly.\r\n if(!promise.hasFinalized) {\r\n promise.reject(new Error(CLOUD_STUB_REGISTRATION_ERR));\r\n }\r\n };\r\n\r\n // Note: at this time (24 May 2021), this is also happens for \"successful\"\r\n // API calls where there is no matching keyboard ID.\r\n //\r\n // The returned 'error' JSON object is sent with an HTML error code (404)\r\n // and does not call `keyman.register`. Even if it did the latter, the\r\n // 404 code would likely prevent the returned script's call.\r\n Lscript.onerror = (event: string | Event, source?: string,\r\n lineno?: number, colno?: number, error?: Error) => {\r\n window.clearTimeout(timeoutID);\r\n\r\n let msg = CLOUD_MALFORMED_OBJECT_ERR;\r\n if(error) {\r\n msg = msg + \": \" + error.message;\r\n }\r\n\r\n promise.reject(new Error(msg));\r\n }\r\n\r\n if(this.fileLocal) {\r\n Lscript.src = query;\r\n } else {\r\n Lscript.src = fullRef;\r\n }\r\n\r\n try {\r\n document.body.appendChild(Lscript);\r\n } catch(ex) {\r\n document.getElementsByTagName('head')[0].appendChild(Lscript);\r\n }\r\n\r\n promise.finally(() => {\r\n clearTimeout(timeoutID);\r\n });\r\n\r\n return {\r\n promise: promise,\r\n queryId: timeoutID\r\n };\r\n }\r\n}", + "import { type Keyboard, KeyboardKeymanGlobal, ProcessorInitOptions } from \"@keymanapp/keyboard-processor\";\r\nimport { DOMKeyboardLoader as KeyboardLoader } from \"@keymanapp/keyboard-processor/dom-keyboard-loader\";\r\nimport { InputProcessor, PredictionContext } from \"@keymanapp/input-processor\";\r\nimport { OSKView } from \"keyman/engine/osk\";\r\nimport { KeyboardRequisitioner, ModelCache, ModelSpec, toUnprefixedKeyboardId as unprefixed } from \"keyman/engine/package-cache\";\r\n\r\nimport { EngineConfiguration, InitOptionSpec } from \"./engineConfiguration.js\";\r\nimport KeyboardInterface from \"./keyboardInterface.js\";\r\nimport { ContextManagerBase } from \"./contextManagerBase.js\";\r\nimport { KeyEventHandler } from './keyEventSource.interface.js';\r\nimport HardKeyboardBase from \"./hardKeyboard.js\";\r\nimport { LegacyAPIEvents } from \"./legacyAPIEvents.js\";\r\nimport { EventNames, EventListener, LegacyEventEmitter } from \"keyman/engine/events\";\r\nimport DOMCloudRequester from \"keyman/engine/package-cache/dom-requester\";\r\nimport KEYMAN_VERSION from \"@keymanapp/keyman-version\";\r\n\r\n// From https://stackoverflow.com/a/69328045\r\ntype WithRequired = T & { [P in K]-?: T[P] };\r\n// Sets two parts non-optional at this level, while they were at lower levels.\r\ntype ProcessorConfiguration = WithRequired, 'defaultOutputRules'>;\r\n\r\nfunction determineBaseLayout(): string {\r\n if(typeof(window['KeymanWeb_BaseLayout']) !== 'undefined') {\r\n return window['KeymanWeb_BaseLayout'];\r\n } else {\r\n return 'us';\r\n }\r\n}\r\n\r\nexport default class KeymanEngine<\r\n Configuration extends EngineConfiguration,\r\n ContextManager extends ContextManagerBase,\r\n HardKeyboard extends HardKeyboardBase\r\n> implements KeyboardKeymanGlobal {\r\n readonly config: Configuration;\r\n contextManager: ContextManager;\r\n interface: KeyboardInterface;\r\n readonly core: InputProcessor;\r\n keyboardRequisitioner: KeyboardRequisitioner;\r\n modelCache: ModelCache;\r\n\r\n protected legacyAPIEvents = new LegacyEventEmitter();\r\n private _hardKeyboard: HardKeyboard;\r\n private _osk: OSKView;\r\n\r\n protected keyEventRefocus?: () => void;\r\n\r\n private keyEventListener: KeyEventHandler = (event, callback) => {\r\n const outputTarget = this.contextManager.activeTarget;\r\n\r\n if(!this.contextManager.activeKeyboard || !outputTarget) {\r\n if(callback) {\r\n callback(null, null);\r\n }\r\n }\r\n\r\n //... probably only applies for physical keystrokes.\r\n if(!event.isSynthetic) {\r\n if(this.osk?.vkbd?.keyPending) {\r\n this.osk.vkbd.keyPending = null;\r\n }\r\n } else if(this.keyEventRefocus) { // && event.isSynthetic // as in, is from the OSK.\r\n // Do anything needed to guarantee that the outputTarget stays active (`app/browser`: maintains focus).\r\n // (Interaction with the OSK may have de-focused the element providing active context;\r\n // we want to restore it in case the user swaps back to the hardware keyboard afterward.)\r\n this.keyEventRefocus();\r\n }\r\n\r\n // Clear any cached codepoint data; we can rebuild it if it's unchanged.\r\n outputTarget.invalidateSelection();\r\n // Deadkey matching continues to be troublesome.\r\n // Deleting matched deadkeys here seems to correct some of the issues. (JD 6/6/14)\r\n outputTarget.deadkeys().deleteMatched(); // Delete any matched deadkeys before continuing\r\n\r\n const result = this.core.processKeyEvent(event, outputTarget);\r\n\r\n if(result && result.transcription?.transform) {\r\n this.config.onRuleFinalization(result, this.contextManager.activeTarget);\r\n }\r\n\r\n if(callback) {\r\n callback(result, null);\r\n }\r\n\r\n // No try-catch here because we don't want to mask any errors that occur during keystroke\r\n // processing - silent failures are far harder to diagnose.\r\n };\r\n\r\n /**\r\n * @param worker A configured WebWorker to serve as the predictive-text engine's main thread.\r\n * Available in the following variants:\r\n * - sourcemapped, unminified (debug)\r\n * - non-sourcemapped + minified (release)\r\n * @param config\r\n * @param contextManager\r\n * @param processorConfigInitializer A one-time use closure used to initialize certain critical components reliant\r\n * upon the class instance, configured by the derived class, but needed during\r\n * the superclass constructor.\r\n */\r\n constructor(\r\n worker: Worker,\r\n config: Configuration,\r\n contextManager: ContextManager,\r\n processorConfigInitializer: (engine: KeymanEngine) => ProcessorConfiguration\r\n ) {\r\n this.config = config;\r\n this.contextManager = contextManager;\r\n\r\n const processorConfiguration = processorConfigInitializer(this);\r\n processorConfiguration.baseLayout = determineBaseLayout();\r\n this.interface = processorConfiguration.keyboardInterface as KeyboardInterface;\r\n this.core = new InputProcessor(config.hostDevice, worker, processorConfiguration);\r\n\r\n this.core.languageProcessor.on('statechange', (state) => {\r\n // The banner controller cannot directly trigger a layout-refresh at this time,\r\n // so we handle that here.\r\n this.osk?.bannerController.selectBanner(state);\r\n this.osk?.refreshLayout();\r\n });\r\n\r\n // The OSK does not possess a direct connection to the KeyboardProcessor's state-key\r\n // management object; this event + handler allow us to keep the OSK's related states\r\n // in sync.\r\n this.core.keyboardProcessor.on('statekeychange', (stateKeys) => {\r\n this.osk?.vkbd?.updateStateKeys(stateKeys);\r\n })\r\n\r\n this.contextManager.on('beforekeyboardchange', (metadata) => {\r\n this.legacyAPIEvents.callEvent('beforekeyboardchange', {\r\n internalName: metadata?.id,\r\n languageCode: metadata?.langId\r\n });\r\n });\r\n\r\n this.contextManager.on('keyboardchange', (kbd) => {\r\n this.refreshModel();\r\n this.core.activeKeyboard = kbd?.keyboard;\r\n\r\n this.legacyAPIEvents.callEvent('keyboardchange', {\r\n internalName: kbd?.metadata.id ?? '',\r\n languageCode: kbd?.metadata.langId ?? ''\r\n });\r\n\r\n // Hide OSK and do not update keyboard list if using internal keyboard (desktops).\r\n // Condition will not be met for touch form-factors; they force selection of a\r\n // default keyboard.\r\n if(!kbd) {\r\n this.osk.startHide(false);\r\n }\r\n\r\n if(this.osk) {\r\n this.osk.setNeedsLayout();\r\n this.osk.activeKeyboard = kbd;\r\n this.osk.present();\r\n }\r\n });\r\n\r\n this.contextManager.on('keyboardasyncload', (metadata) => {\r\n /* Original implementation pre-modularization:\r\n *\r\n * > Force OSK display for CJK keyboards (keyboards using a pick list)\r\n *\r\n * A matching subcondition in the block below will ensure that the OSK activates pre-load\r\n * for CJK keyboards. Yes, even before a CJK picker could ever show. We should be fine\r\n * without the CJK check so long as a picker keyboard's OSK is kept activated post-load,\r\n * when the picker actually needs to be kept persistently-active.\r\n * `metadata` would be relevant a the CJK-check, which was based on language codes.\r\n *\r\n * Of course, as mobile devices don't have guaranteed physical keyboards... we need to\r\n * keep the OSK visible for them, hence the actual block below.\r\n */\r\n if(this.config.hostDevice.touchable && this.osk?.activationModel) {\r\n this.osk.activationModel.enabled = true;\r\n // Also note: the OSKView.mayDisable method returns false when hostDevice.touchable = false.\r\n // The .startHide() call below will check that method before actually starting an OSK hide.\r\n }\r\n\r\n // Always (temporarily) hide the OSK when loading a new keyboard, to ensure\r\n // that a failure to load doesn't leave the current OSK displayed\r\n this.osk?.startHide(false);\r\n });\r\n }\r\n\r\n public async init(optionSpec: Required){\r\n // There may be some valid mutations possible even on repeated calls?\r\n // The original seems to allow it.\r\n\r\n const config = this.config;\r\n if(config.deferForInitialization.hasFinalized) {\r\n // abort! Maybe throw an error, too.\r\n return Promise.resolve();\r\n }\r\n\r\n config.initialize(optionSpec);\r\n\r\n // Since we're not sandboxing keyboard loads yet, we just use `window` as the jsGlobal object.\r\n // All components initialized below require a properly-configured `config.paths` or similar.\r\n const keyboardLoader = new KeyboardLoader(this.interface, config.applyCacheBusting);\r\n this.keyboardRequisitioner = new KeyboardRequisitioner(keyboardLoader, new DOMCloudRequester(), this.config.paths);\r\n this.modelCache = new ModelCache();\r\n const kbdCache = this.keyboardRequisitioner.cache;\r\n\r\n this.contextManager.configure({\r\n resetContext: (target) => {\r\n this.core.resetContext(target);\r\n },\r\n predictionContext: new PredictionContext(this.core.languageProcessor, this.core.keyboardProcessor),\r\n keyboardCache: this.keyboardRequisitioner.cache\r\n });\r\n\r\n // #region Event handler wiring\r\n this.config.on('spacebartext', () => {\r\n // On change of spacebar-text mode, we currently need a layout refresh to update the\r\n // spacebar's text.\r\n this.osk?.refreshLayout();\r\n });\r\n\r\n kbdCache.on('stubadded', (stub) => {\r\n let eventRaiser = () => {\r\n // The corresponding event is needed in order to update UI modules as new keyboard stubs \"come online\".\r\n this.legacyAPIEvents.callEvent('keyboardregistered', {\r\n internalName: stub.KI,\r\n language: stub.KL,\r\n keyboardName: stub.KN,\r\n languageCode: stub.KLC,\r\n package: stub.KP\r\n });\r\n\r\n // If this is the first stub loaded, set it as active.\r\n if(this.config.activateFirstKeyboard && this.keyboardRequisitioner.cache.defaultStub == stub) {\r\n // Note: leaving this out is super-useful for debugging issues that occur when no keyboard is active.\r\n this.contextManager.activateKeyboard(stub.id, stub.langId, true);\r\n }\r\n }\r\n\r\n if(this.config.deferForInitialization.hasFinalized) {\r\n eventRaiser();\r\n } else {\r\n this.config.deferForInitialization.then(eventRaiser);\r\n }\r\n });\r\n\r\n kbdCache.on('keyboardadded', (keyboard) => {\r\n let eventRaiser = () => {\r\n // Execute any external (UI) code needed after loading keyboard\r\n this.legacyAPIEvents.callEvent('keyboardloaded', {\r\n keyboardName: keyboard.id\r\n });\r\n }\r\n\r\n if(this.config.deferForInitialization.hasFinalized) {\r\n eventRaiser();\r\n } else {\r\n this.config.deferForInitialization.then(eventRaiser);\r\n }\r\n });\r\n\r\n this.keyboardRequisitioner.cache.on('keyboardadded', (keyboard) => {\r\n this.legacyAPIEvents.callEvent('keyboardloaded', { keyboardName: keyboard.id });\r\n });\r\n //\r\n // #endregion\r\n }\r\n\r\n /**\r\n * Public API: Denotes the 'patch' component of the version of the current engine.\r\n *\r\n * https://help.keyman.com/developer/engine/web/current-version/reference/core/build\r\n */\r\n public get build(): number {\r\n return Number.parseInt(KEYMAN_VERSION.VERSION_PATCH, 10);\r\n }\r\n\r\n /**\r\n * Public API: Denotes the major & minor components of the version of the current engine.\r\n *\r\n * https://help.keyman.com/developer/engine/web/current-version/reference/core/version\r\n */\r\n public get version(): string {\r\n return KEYMAN_VERSION.VERSION_RELEASE;\r\n }\r\n\r\n public get hardKeyboard(): HardKeyboard {\r\n return this._hardKeyboard;\r\n }\r\n\r\n protected set hardKeyboard(keyboard: HardKeyboard) {\r\n if(this._hardKeyboard) {\r\n this._hardKeyboard.off('keyevent', this.keyEventListener);\r\n }\r\n this._hardKeyboard = keyboard;\r\n keyboard.on('keyevent', this.keyEventListener);\r\n }\r\n\r\n public get osk(): OSKView {\r\n return this._osk;\r\n }\r\n\r\n public set osk(value: OSKView) {\r\n if(this._osk) {\r\n this._osk.off('keyevent', this.keyEventListener);\r\n this.core.keyboardProcessor.layerStore.handler = this.osk.layerChangeHandler;\r\n }\r\n this._osk = value;\r\n if(value) {\r\n value.activeKeyboard = this.contextManager.activeKeyboard;\r\n value.on('keyevent', this.keyEventListener);\r\n this.core.keyboardProcessor.layerStore.handler = value.layerChangeHandler;\r\n }\r\n }\r\n\r\n public getDebugInfo(): Record {\r\n const activeKbd = this.contextManager?.activeKeyboard;\r\n\r\n const report = {\r\n configReport: this.config?.debugReport(),\r\n keyboard: {\r\n id: unprefixed(activeKbd?.metadata?.id ?? ''),\r\n langId: activeKbd?.metadata?.langId || '',\r\n version: activeKbd?.keyboard?.version ?? ''\r\n },\r\n model: {\r\n id: this.core?.activeModel?.id || ''\r\n },\r\n osk: {\r\n banner: this.osk?.bannerController?.activeType ?? '',\r\n layer: this.osk?.vkbd?.layerId || ''\r\n }\r\n };\r\n\r\n return report;\r\n }\r\n\r\n // Returned Promise: gives the model-spec object. Only resolves when any model loading or unloading\r\n // is fully complete.\r\n private refreshModel(): Promise {\r\n const kbd = this.contextManager.activeKeyboard;\r\n const model = this.modelCache.modelForLanguage(kbd?.metadata.langId);\r\n\r\n if(this.core.activeModel != model) {\r\n if(this.core.activeModel) {\r\n this.core.languageProcessor.unloadModel();\r\n }\r\n\r\n // Semi-hacky management of banner display state.\r\n if(model) {\r\n return this.core.languageProcessor.loadModel(model).then(() => {\r\n return model;\r\n });\r\n }\r\n }\r\n\r\n return Promise.resolve(model);\r\n }\r\n\r\n /**\r\n * Subscribe to Keyman Engine events documented at\r\n * https://help.keyman.com/developer/engine/web/current-version/reference/events. Note that any OSK-related\r\n * events should instead register on `keyman.osk.addEventListener`, not on this method.\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/core/addEventListener\r\n */\r\n public addEventListener>(event: Name, listener: EventListener) {\r\n this.legacyAPIEvents.addEventListener(event, listener);\r\n }\r\n\r\n /**\r\n * Public API: Unsubscribe from Keyman Engine events documented at\r\n * https://help.keyman.com/developer/engine/web/current-version/reference/events.\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/core/removeEventListener\r\n */\r\n public removeEventListener>(event: Name, listener: EventListener) {\r\n this.legacyAPIEvents.removeEventListener(event, listener);\r\n }\r\n\r\n shutdown() {\r\n this.legacyAPIEvents.shutdown();\r\n this.osk?.shutdown();\r\n }\r\n\r\n // API methods\r\n\r\n // 17.0: new! Only used by apps utilizing app/webview and one app/browser test page.\r\n // Is not part of our 'published' API.\r\n\r\n /**\r\n * Registers the specified lexical model within Keyman Engine. If a keyboard with a\r\n * matching language code is currently activated, it will also activate the model.\r\n *\r\n * @param model An object defining model ID, associated language IDs, and either the\r\n * model's definition or a path to a file containing it.\r\n */\r\n addModel(model: ModelSpec): Promise {\r\n this.modelCache.register(model);\r\n\r\n const activeStub = this.contextManager.activeKeyboard?.metadata;\r\n if(activeStub && model.languages.indexOf(activeStub.langId) != -1) {\r\n return this.refreshModel().then(() => { return; });\r\n } else {\r\n return Promise.resolve();\r\n }\r\n }\r\n\r\n // 17.0: new! Only used by apps utilizing app/webview and one app/browser test page.\r\n\r\n /**\r\n * Unregisters any previously-registered lexical model with a matching ID from Keyman Engine.\r\n * If a keyboard with a matching language code is currently activated, it will also\r\n * deactivate the model.\r\n *\r\n * @param modelId The ID for the model to be deregistered and forgotten by Keyman Engine.\r\n */\r\n removeModel(modelId: string) {\r\n this.modelCache.unregister(modelId);\r\n\r\n // Is it the active model?\r\n if(this.core.activeModel && this.core.activeModel.id == modelId) {\r\n this.core.languageProcessor.unloadModel();\r\n }\r\n }\r\n\r\n /**\r\n * Allow to change active keyboard by (internal) keyboard name\r\n *\r\n * @param {string} PInternalName Internal name\r\n * @param {string} PLgCode Language code\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/core/setActiveKeyboard\r\n */\r\n public async setActiveKeyboard(keyboardId: string, languageCode?: string): Promise {\r\n return this.contextManager.activateKeyboard(keyboardId, languageCode, true);\r\n }\r\n\r\n /**\r\n * Function getActiveKeyboard\r\n * Scope Public\r\n * @return {string} Name of active keyboard\r\n * Description Return internal name of currently active keyboard\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/core/getActiveKeyboard\r\n */\r\n public getActiveKeyboard(): string {\r\n return this.contextManager.activeKeyboard?.metadata.id ?? '';\r\n }\r\n\r\n /**\r\n * Function getActiveLanguage\r\n * Scope Public\r\n * @param {boolean=} true to retrieve full language name, false/undefined to retrieve code.\r\n * @return {string} language code\r\n * Description Return language code for currently selected language\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/core/getActiveLanguage\r\n */\r\n public getActiveLanguage(fullName?: boolean): string {\r\n // In short... the activeStub.\r\n const metadata = this.contextManager.activeKeyboard?.metadata;\r\n\r\n if(!fullName) {\r\n return metadata?.langId ?? '';\r\n } else {\r\n return metadata?.langName ?? '';\r\n }\r\n }\r\n\r\n /**\r\n * Function isChiral\r\n * Scope Public\r\n * @param {string|Object=} k0\r\n * @return {boolean}\r\n * Description Tests if the active keyboard (or optional argument) uses chiral modifiers.\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/core/isChiral\r\n */\r\n public isChiral(k0?: string | Keyboard) {\r\n let kbd: Keyboard;\r\n if(k0) {\r\n if(typeof k0 == 'string') {\r\n const kbdObj = this.keyboardRequisitioner.cache.getKeyboard(k0);\r\n if(!kbdObj) {\r\n throw new Error(`Keyboard '${k0}' has not been loaded.`);\r\n } else {\r\n k0 = kbdObj;\r\n }\r\n }\r\n\r\n kbd = k0;\r\n } else {\r\n kbd = this.core.activeKeyboard;\r\n }\r\n return kbd.isChiral;\r\n }\r\n\r\n /**\r\n * Function resetContext\r\n * Scope Public\r\n * Description Reverts the OSK to the default layer, clears any processing caches and modifier states,\r\n * and clears deadkeys and prediction-processing states on the active element (if it exists)\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/core/resetContext\r\n */\r\n public resetContext() {\r\n this.contextManager.resetContext();\r\n };\r\n\r\n /**\r\n * Function setNumericLayer\r\n * Scope Public\r\n * Description Set OSK to numeric layer if it exists\r\n */\r\n setNumericLayer() {\r\n this.core.keyboardProcessor.setNumericLayer(this.config.softDevice);\r\n };\r\n}\r\n\r\n// Intent: define common behaviors for both primary app types; each then subclasses & extends where needed.", + "import EventEmitter from 'eventemitter3';\r\n\r\nimport BannerView, { BannerController } from '../banner/bannerView.js';\r\nimport OSKViewComponent from '../components/oskViewComponent.interface.js';\r\nimport EmptyView from '../components/emptyView.js';\r\nimport HelpPageView from '../components/helpPageView.js';\r\nimport KeyboardView from '../components/keyboardView.interface.js';\r\nimport VisualKeyboard from '../visualKeyboard.js';\r\nimport { LengthStyle, ParsedLengthStyle } from '../lengthStyle.js';\r\nimport { type KeyElement } from '../keyElement.js';\r\n\r\nimport {\r\n Codes,\r\n DeviceSpec,\r\n Keyboard,\r\n KeyEvent,\r\n KeyboardProperties,\r\n ManagedPromise,\r\n type MinimalCodesInterface,\r\n type MutableSystemStore,\r\n type SystemStoreMutationHandler\r\n} from '@keymanapp/keyboard-processor';\r\nimport { createUnselectableElement, getAbsoluteX, getAbsoluteY, StylesheetManager } from 'keyman/engine/dom-utils';\r\nimport { EventListener, EventNames, LegacyEventEmitter } from 'keyman/engine/events';\r\n\r\nimport Configuration from '../config/viewConfiguration.js';\r\nimport Activator, { StaticActivator } from './activator.js';\r\nimport TouchEventPromiseMap from './touchEventPromiseMap.js';\r\n\r\n// These will likely be eliminated from THIS file at some point.\\\r\n\r\nexport type OSKPos = {'left'?: number, 'top'?: number};\r\n\r\nexport type OSKRect = {\r\n 'left'?: number,\r\n 'top'?: number,\r\n 'width'?: number,\r\n 'height'?: number,\r\n 'nosize'?: boolean,\r\n 'nomove'?: boolean\r\n};\r\n\r\n/**\r\n * Definition for OSK events documented at\r\n * https://help.keyman.com/DEVELOPER/ENGINE/WEB/16.0/reference/events/.\r\n */\r\nexport interface LegacyOSKEventMap {\r\n 'configclick'(obj: {});\r\n 'helpclick'(obj: {});\r\n 'resizemove'(obj: {});\r\n 'show'(obj: {});\r\n 'hide'(obj: {\r\n HiddenByUser: boolean\r\n });\r\n}\r\n\r\n/**\r\n * For now, these will serve as undocumented, internal events. We need a proper\r\n * design round and discussion before we consider promoting them to long-term,\r\n * documented official API events.\r\n */\r\nexport interface EventMap {\r\n /**\r\n * Designed to pass key events off to any consuming modules/libraries.\r\n *\r\n * Note: the following code block was originally used to integrate with the keyboard & input\r\n * processors, but it requires entanglement with components external to this OSK module.\r\n */\r\n 'keyevent': (event: KeyEvent) => void,\r\n\r\n /**\r\n * Indicates that the globe key has either been pressed (`on` == `true`)\r\n * or released (`on` == `false`).\r\n */\r\n globekey: (e: KeyElement, on: boolean) => void;\r\n\r\n /**\r\n * A virtual keystroke corresponding to a \"hide\" command has been received.\r\n */\r\n hiderequested: (key: KeyElement) => void;\r\n\r\n /**\r\n * Signals the special command to display the engine's version + build number.\r\n */\r\n showbuild: () => void;\r\n\r\n // While the next two are near-duplicates of the legacy event `resizemove`, these\r\n // have the advantage of providing a Promise for the end of the ongoing user\r\n // interaction. We need that Promise for focus-management.\r\n\r\n /**\r\n * Signals that the OSK is being moved by the user via a drag operation.\r\n *\r\n * The provided Promise will resolve once the drag operation is complete.\r\n *\r\n * Note that position-restoration (unpinning the OSK) is treated as a drag-move\r\n * event. It resolves near-instantly.\r\n */\r\n dragmove: (promise: Promise) => void;\r\n\r\n /**\r\n * Signals that the OSK is being resized via a drag operation (on a resize 'handle').\r\n *\r\n * The provided Promise will resolve once the resize operation is complete.\r\n */\r\n resizemove: (promise: Promise) => void;\r\n\r\n /**\r\n * Signals that either the mouse or an active touchpoint is interacting with the OSK.\r\n *\r\n * The provided `Promise` will resolve once the corresponding interaction is complete.\r\n * Note that for touch events, more than one touchpoint may coexist, each with its own\r\n * corresponding call of this event and corresponding `Promise`.\r\n */\r\n pointerinteraction: (promise: Promise) => void;\r\n}\r\n\r\nexport default abstract class OSKView extends EventEmitter implements MinimalCodesInterface {\r\n _Box: HTMLDivElement;\r\n readonly legacyEvents = new LegacyEventEmitter();\r\n\r\n // #region Key code definition aliases for legacy keyboards (that expect window['keyman']['osk'].___)\r\n get keyCodes() {\r\n return Codes.keyCodes;\r\n }\r\n\r\n get modifierCodes() {\r\n return Codes.modifierCodes;\r\n }\r\n\r\n get modifierBitmasks() {\r\n return Codes.modifierBitmasks;\r\n }\r\n\r\n get stateBitmasks() {\r\n return Codes.stateBitmasks;\r\n }\r\n // #endregion\r\n\r\n headerView: OSKViewComponent;\r\n bannerView: BannerView; // Which implements OSKViewComponent\r\n keyboardView: KeyboardView; // Which implements OSKViewComponent\r\n footerView: OSKViewComponent;\r\n\r\n private _bannerController: BannerController;\r\n\r\n private kbdStyleSheetManager: StylesheetManager;\r\n private uiStyleSheetManager: StylesheetManager;\r\n\r\n private config: Configuration;\r\n\r\n private _boxBaseMouseDown: (e: MouseEvent) => boolean;\r\n private _boxBaseTouchStart: (e: TouchEvent) => boolean;\r\n private _boxBaseTouchEventCancel: (e: TouchEvent) => boolean;\r\n\r\n private keyboardData: {\r\n keyboard: Keyboard,\r\n metadata: KeyboardProperties\r\n };\r\n\r\n /**\r\n * The configured width for this OSKManager. May be `undefined` or `null`\r\n * to allow automatic width scaling.\r\n */\r\n private _width: ParsedLengthStyle;\r\n\r\n /**\r\n * The configured height for this OSKManager. May be `undefined` or `null`\r\n * to allow automatic height scaling.\r\n */\r\n private _height: ParsedLengthStyle;\r\n\r\n /**\r\n * The computed width for this OSKManager. May be null if auto sizing\r\n * is allowed and the OSKManager is not currently in the DOM hierarchy.\r\n */\r\n private _computedWidth: number;\r\n\r\n /**\r\n * The computed height for this OSKManager. May be null if auto sizing\r\n * is allowed and the OSKManager is not currently in the DOM hierarchy.\r\n */\r\n private _computedHeight: number;\r\n\r\n /**\r\n * The base font size to use for hosted `Banner`s and `VisualKeyboard`\r\n * instances.\r\n */\r\n private _baseFontSize: ParsedLengthStyle;\r\n\r\n private needsLayout: boolean = true;\r\n\r\n private _animatedHideTimeout: number;\r\n\r\n private mouseEnterPromise?: ManagedPromise;\r\n private touchEventPromiseManager = new TouchEventPromiseMap();\r\n\r\n private static readonly STYLESHEET_FILES = ['kmwosk.css', 'globe-hint.css'];\r\n\r\n constructor(configuration: Configuration) {\r\n super();\r\n\r\n // Clone the config; do not allow object references to be altered later.\r\n this.config = configuration = {...configuration};\r\n\r\n // `undefined` is falsy, but we want a `true` default behavior for this config property.\r\n if(this.config.allowHideAnimations === undefined) {\r\n this.config.allowHideAnimations = true;\r\n }\r\n\r\n this.config.device = configuration.device || configuration.hostDevice;\r\n\r\n this.config.isEmbedded = configuration.isEmbedded || false;\r\n this.config.embeddedGestureConfig = configuration.embeddedGestureConfig || {};\r\n this.config.activator.on('activate', this.activationListener);\r\n\r\n // OSK initialization - create DIV and set default styles\r\n this._Box = createUnselectableElement('div'); // Container for OSK (Help DIV, displayed when user clicks Help icon)\r\n this.kbdStyleSheetManager = new StylesheetManager(this._Box, this.config.doCacheBusting || false);\r\n this.uiStyleSheetManager = new StylesheetManager(this._Box);\r\n\r\n // Initializes the two constant OSKComponentView fields.\r\n this.bannerView = new BannerView();\r\n this.bannerView.events.on('bannerchange', () => this.refreshLayout());\r\n\r\n this._bannerController = new BannerController(this.bannerView, this.hostDevice, this.config.predictionContextManager);\r\n\r\n this.keyboardView = null;\r\n\r\n this.setBaseMouseEventListeners();\r\n if(this.hostDevice.touchable) {\r\n this.setBaseTouchEventListeners();\r\n }\r\n }\r\n\r\n protected get configuration(): Configuration {\r\n return this.config;\r\n }\r\n\r\n public get bannerController(): BannerController {\r\n return this._bannerController;\r\n }\r\n\r\n public get hostDevice(): DeviceSpec {\r\n return this.config.hostDevice;\r\n }\r\n\r\n public get fontRootPath(): string {\r\n return this.config.pathConfig.fonts;\r\n }\r\n\r\n public get isEmbedded(): boolean {\r\n return this.config.isEmbedded;\r\n }\r\n\r\n /**\r\n * Function _VKbdMouseEnter\r\n * Scope Private\r\n * @param {Object} e event\r\n * Description Activate the KMW UI when mouse enters the OSK element hierarchy\r\n */\r\n private _VKbdMouseEnter: (e: MouseEvent) => void;\r\n\r\n /**\r\n * Function _VKbdMouseLeave\r\n * Scope Private\r\n * @param {Object} e event\r\n * Description Cancel activation of KMW UI when mouse leaves the OSK element hierarchy\r\n */\r\n private _VKbdMouseLeave: (e: MouseEvent) => void;\r\n\r\n private setBaseMouseEventListeners() {\r\n this._Box.onmouseenter = this._VKbdMouseEnter = (e) => {\r\n if(this.mouseEnterPromise) {\r\n // The chain was somehow interrupted, with the mouseleave never occurring!\r\n this.mouseEnterPromise.resolve();\r\n }\r\n\r\n this.mouseEnterPromise = new ManagedPromise();\r\n this.emit('pointerinteraction', this.mouseEnterPromise.corePromise);\r\n };\r\n\r\n this._Box.onmouseleave = this._VKbdMouseLeave = (e) => {\r\n this.mouseEnterPromise.resolve();\r\n this.mouseEnterPromise = null;\r\n // focusAssistant.setMaintainingFocus(false);\r\n };\r\n }\r\n\r\n private removeBaseMouseEventListeners() {\r\n this._Box.onmouseenter = null;\r\n this._Box.onmouseleave = null;\r\n }\r\n\r\n private setBaseTouchEventListeners() {\r\n // To prevent touch event default behaviour on mobile devices\r\n let commonPrevention = function(e: TouchEvent) {\r\n if(e.cancelable) {\r\n e.preventDefault();\r\n }\r\n e.stopPropagation();\r\n return false;\r\n }\r\n\r\n this._boxBaseTouchEventCancel = (e) => {\r\n this.touchEventPromiseManager.maintainTouches(e.touches);\r\n return commonPrevention(e);\r\n };\r\n\r\n this._boxBaseTouchStart = (e) => {\r\n for(let i = 0; i < e.changedTouches.length; i++) {\r\n let promise = this.touchEventPromiseManager.promiseForTouchpoint(e.changedTouches[i].identifier);\r\n this.emit('pointerinteraction', promise.corePromise);\r\n }\r\n\r\n this.touchEventPromiseManager.maintainTouches(e.touches);\r\n return commonPrevention(e);\r\n }\r\n\r\n this._Box.addEventListener('touchstart', this._boxBaseTouchStart, false);\r\n this._Box.addEventListener('touchmove', this._boxBaseTouchEventCancel, false);\r\n this._Box.addEventListener('touchend', this._boxBaseTouchEventCancel, false);\r\n this._Box.addEventListener('touchcancel', this._boxBaseTouchEventCancel, false);\r\n }\r\n\r\n private removeBaseTouchEventListeners() {\r\n if(!this._boxBaseTouchEventCancel) {\r\n return;\r\n }\r\n\r\n this._Box.removeEventListener('touchstart', this._boxBaseTouchStart, false);\r\n this._Box.removeEventListener('touchmove', this._boxBaseTouchEventCancel, false);\r\n this._Box.removeEventListener('touchend', this._boxBaseTouchEventCancel, false);\r\n this._Box.removeEventListener('touchcancel', this._boxBaseTouchEventCancel, false);\r\n\r\n this._boxBaseTouchEventCancel = null;\r\n this._boxBaseTouchStart = null;\r\n }\r\n\r\n // TODO: activeTarget has been 'moved' to activationModel.activationCondition (for TwoStateActivation instances).\r\n // Loosely speaking, anyway.\r\n\r\n\r\n\r\n public get targetDevice(): DeviceSpec {\r\n return this.config.device;\r\n }\r\n\r\n public set targetDevice(spec: DeviceSpec) {\r\n if(this.allowsDeviceChange(spec)) {\r\n this.config.device = spec;\r\n this.loadActiveKeyboard();\r\n } else {\r\n console.error(\"May not change target device for this OSKView type.\");\r\n }\r\n }\r\n\r\n protected allowsDeviceChange(newSpec: DeviceSpec): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * Gets and sets the activation state model used to control presentation of the OSK.\r\n */\r\n get activationModel(): Activator {\r\n return this.config.activator;\r\n }\r\n\r\n set activationModel(model: Activator) {\r\n if(!model) {\r\n throw new Error(\"The activation model may not be set to null or undefined!\");\r\n }\r\n\r\n this.config.activator.off('activate', this.activationListener);\r\n model.on('activate', this.activationListener);\r\n\r\n this.config.activator = model;\r\n\r\n this.commonCheckAndDisplay();\r\n }\r\n\r\n public get mayDisable(): boolean {\r\n if(this.hostDevice.touchable) {\r\n return false;\r\n }\r\n\r\n if(this.activeKeyboard?.keyboard.isCJK) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private readonly activationListener = (flag: boolean) => {\r\n // CJK override: may not be disabled, as the CJK elements are required.\r\n if(!this.mayDisable && !this.activationModel.enabled) {\r\n this.activationModel.off('activate', this.activationListener);\r\n try {\r\n this.activationModel.enabled = true;\r\n } finally {\r\n this.activationModel.on('activate', this.activationListener);\r\n }\r\n }\r\n this.commonCheckAndDisplay();\r\n };\r\n\r\n /**\r\n * A property denoting whether or not the OSK will be presented when it meets all\r\n * other activation conditions.\r\n *\r\n * Is equivalent to `.activationModel.enabled`.\r\n */\r\n get displayIfActive(): boolean {\r\n return this.activationModel.enabled;\r\n }\r\n\r\n /**\r\n * Used by the activation model's event listenerss and properties as a common helper;\r\n * they rely on this function to manage presentation (showing / hiding) of the OSK.\r\n */\r\n private commonCheckAndDisplay() {\r\n if(this.activationModel.activate && this.activeKeyboard) {\r\n this.present();\r\n } else {\r\n this.startHide(false);\r\n }\r\n }\r\n\r\n public get vkbd(): VisualKeyboard {\r\n if(this.keyboardView instanceof VisualKeyboard) {\r\n return this.keyboardView;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n public get banner(): BannerView { // Maintains old reference point used by embedding apps.\r\n return this.bannerView;\r\n }\r\n\r\n /**\r\n * The configured width for this VisualKeyboard. May be `undefined` or `null`\r\n * to allow automatic width scaling.\r\n */\r\n get width(): ParsedLengthStyle {\r\n return this._width;\r\n }\r\n\r\n /**\r\n * The configured height for this VisualKeyboard. May be `undefined` or `null`\r\n * to allow automatic height scaling.\r\n */\r\n get height(): ParsedLengthStyle {\r\n return this._height;\r\n }\r\n\r\n /**\r\n * The computed width for this VisualKeyboard. May be null if auto sizing\r\n * is allowed and the VisualKeyboard is not currently in the DOM hierarchy.\r\n */\r\n get computedWidth(): number {\r\n // Computed during layout operations; allows caching instead of continuous recomputation.\r\n if(this.needsLayout) {\r\n this.refreshLayout();\r\n }\r\n return this._computedWidth;\r\n }\r\n\r\n /**\r\n * The computed height for this VisualKeyboard. May be null if auto sizing\r\n * is allowed and the VisualKeyboard is not currently in the DOM hierarchy.\r\n */\r\n get computedHeight(): number {\r\n // Computed during layout operations; allows caching instead of continuous recomputation.\r\n if(this.needsLayout) {\r\n this.refreshLayout();\r\n }\r\n return this._computedHeight;\r\n }\r\n\r\n /**\r\n * The top-level style string for the font size used by the predictive banner\r\n * and the primary keyboard visualization elements.\r\n */\r\n get baseFontSize(): string {\r\n return this.parsedBaseFontSize?.styleString || '';\r\n }\r\n\r\n protected get parsedBaseFontSize(): ParsedLengthStyle {\r\n if(!this._baseFontSize) {\r\n this._baseFontSize = OSKView.defaultFontSize(this.targetDevice, this.computedHeight, this.isEmbedded);\r\n }\r\n\r\n return this._baseFontSize;\r\n }\r\n\r\n public static defaultFontSize(device: DeviceSpec, computedHeight: number, isEmbedded: boolean): ParsedLengthStyle {\r\n if(device.touchable) {\r\n const fontScale = device.formFactor == 'phone'\r\n ? 1.6 * (isEmbedded ? 0.65 : 0.6) * 1.2 // Combines original scaling factor with one previously applied to the layer group.\r\n : 2; // iPad or Android tablet\r\n return ParsedLengthStyle.special(fontScale, 'em');\r\n } else {\r\n return computedHeight ? ParsedLengthStyle.inPixels(computedHeight / 8) : undefined;\r\n }\r\n }\r\n\r\n public get activeKeyboard(): {\r\n keyboard: Keyboard,\r\n metadata: KeyboardProperties\r\n } {\r\n return this.keyboardData;\r\n }\r\n\r\n public set activeKeyboard(keyboardData: {\r\n keyboard: Keyboard,\r\n metadata: KeyboardProperties\r\n }) {\r\n this.keyboardData = keyboardData;\r\n this.loadActiveKeyboard();\r\n\r\n if(this.keyboardData?.keyboard.isCJK) {\r\n this.activationModel.enabled = true;\r\n }\r\n }\r\n\r\n private computeFrameHeight(): number {\r\n return (this.headerView?.layoutHeight.val || 0) + (this.footerView?.layoutHeight.val || 0);\r\n }\r\n\r\n setSize(width?: number | LengthStyle, height?: number | LengthStyle, pending?: boolean) {\r\n let mutatedFlag = false;\r\n\r\n let parsedWidth: ParsedLengthStyle;\r\n let parsedHeight: ParsedLengthStyle;\r\n\r\n if(!width && width !== 0) {\r\n return;\r\n }\r\n\r\n if(!height && height !== 0) {\r\n return;\r\n }\r\n\r\n if(Number.isFinite(width as number)) {\r\n parsedWidth = ParsedLengthStyle.inPixels(width as number);\r\n } else {\r\n parsedWidth = new ParsedLengthStyle(width as LengthStyle);\r\n }\r\n\r\n if(Number.isFinite(height as number)) {\r\n parsedHeight = ParsedLengthStyle.inPixels(height as number);\r\n } else {\r\n parsedHeight = new ParsedLengthStyle(height as LengthStyle);\r\n }\r\n\r\n if(width && height) {\r\n mutatedFlag = !this._width || !this._height;\r\n\r\n mutatedFlag = mutatedFlag || parsedWidth.styleString != this._width.styleString;\r\n mutatedFlag = mutatedFlag || parsedHeight.styleString != this._height.styleString;\r\n\r\n this._width = parsedWidth;\r\n this._height = parsedHeight;\r\n }\r\n\r\n this.needsLayout = this.needsLayout || mutatedFlag;\r\n this.refreshLayoutIfNeeded(pending);\r\n }\r\n\r\n public setNeedsLayout() {\r\n this.needsLayout = true;\r\n }\r\n\r\n public refreshLayout(pending?: boolean): void {\r\n if(!this.keyboardView) {\r\n return;\r\n }\r\n\r\n // Step 1: have the necessary conditions been met?\r\n const hasDimensions = this.width && this.height;\r\n\r\n if(!hasDimensions) {\r\n // If dimensions haven't been set yet, we have no basis for layout calculations.\r\n // We do not emit a warning here; if we did, at the time of writing this, we'd\r\n // consistently get Sentry events from the Keyman mobile apps.\r\n //\r\n // See #9206 & https://github.com/keymanapp/keyman/pull/9206#issuecomment-1627917615\r\n // for context and history.\r\n return;\r\n }\r\n\r\n const fixedSize = this.width.absolute && this.height.absolute;\r\n const computedStyle = getComputedStyle(this._Box);\r\n const isInDOM = computedStyle.height != '' && computedStyle.height != 'auto';\r\n\r\n // Step 2: determine basic layout geometry\r\n if(fixedSize) {\r\n this._computedWidth = this.width.val;\r\n this._computedHeight = this.height.val;\r\n } else if(isInDOM) {\r\n // Note: %-based auto-detect for dimensions currently has some issues; the stylesheets load\r\n // asynchronously, causing the format to be VERY off before the stylesheets fully load.\r\n //\r\n // Depending on initial effects, changes to the OSK size could cause changes to the _parent_ size,\r\n // too... so this potential bit likely needs something of a redesign.\r\n const parent = this._Box.parentElement as HTMLElement;\r\n this._computedWidth = this.width.val * (this.width.absolute ? 1 : parent.offsetWidth);\r\n this._computedHeight = this.height.val * (this.height.absolute ? 1 : parent.offsetHeight);\r\n } else {\r\n console.warn(\"Unable to properly perform layout - specification uses a relative spec, thus relies upon insertion into the DOM for layout.\");\r\n return;\r\n }\r\n\r\n // Must be set before any references to the .computedWidth and .computedHeight properties!\r\n this.needsLayout = false;\r\n\r\n // Step 3: perform layout operations.\r\n this.banner.element.style.fontSize = this.baseFontSize;\r\n if(this.vkbd) {\r\n this.vkbd.fontSize = this.parsedBaseFontSize;\r\n }\r\n\r\n if(!pending) {\r\n this.headerView?.refreshLayout();\r\n this.bannerView.refreshLayout();\r\n this.footerView?.refreshLayout();\r\n }\r\n\r\n if(this.vkbd) {\r\n let availableHeight = this.computedHeight - this.computeFrameHeight();\r\n\r\n // +5: from kmw-banner-bar's 'top' attribute when active\r\n if(this.bannerView.height > 0) {\r\n availableHeight -= this.bannerView.height + 5;\r\n }\r\n this.vkbd.setSize(this.computedWidth, availableHeight, pending);\r\n\r\n const bs = this._Box.style;\r\n // OSK size settings can only be reliably applied to standard VisualKeyboard\r\n // visualizations, not to help text or empty views.\r\n bs.width = bs.maxWidth = this.computedWidth + 'px';\r\n bs.height = bs.maxHeight = this.computedHeight + 'px';\r\n\r\n // Ensure that the layer's spacebar is properly captioned.\r\n this.vkbd.showLanguage();\r\n } else {\r\n const bs = this._Box.style;\r\n bs.width = 'auto';\r\n bs.height = 'auto';\r\n bs.maxWidth = bs.maxHeight = '';\r\n }\r\n }\r\n\r\n public refreshLayoutIfNeeded(pending?: boolean) {\r\n if(this.needsLayout) {\r\n this.refreshLayout(pending);\r\n }\r\n }\r\n\r\n public abstract getDefaultWidth(): number;\r\n public abstract getDefaultKeyboardHeight(): number;\r\n\r\n // /**\r\n // * Function _Load\r\n // * Scope Private\r\n // * Description OSK initialization when keyboard selected\r\n // */\r\n // _Load() { // Load Help - maintained only temporarily.\r\n // let keymanweb = com.keyman.singleton;\r\n // this.activeKeyboard = keymanweb.core.activeKeyboard;\r\n // }\r\n\r\n public postKeyboardLoad() {\r\n this._Visible = false; // I3363 (Build 301)\r\n\r\n // Perform any needed restructuring and/or layout tweaks (depending on the OSKView type).\r\n this.postKeyboardAdjustments();\r\n\r\n if(this.displayIfActive) {\r\n this.present();\r\n }\r\n }\r\n\r\n protected abstract postKeyboardAdjustments(): void;\r\n\r\n protected abstract setBoxStyling(): void;\r\n\r\n private loadActiveKeyboard() {\r\n this.setBoxStyling();\r\n\r\n if(this.vkbd) {\r\n this.vkbd.shutdown();\r\n }\r\n this.keyboardView = null;\r\n this.needsLayout = true;\r\n\r\n // Instantly resets the OSK container, erasing / delinking the previously-loaded keyboard.\r\n this._Box.innerHTML = '';\r\n\r\n // Temp-hack: embedded products prefer their stylesheet, etc linkages without the /osk path component.\r\n let subpath = 'osk/';\r\n if(this.config.isEmbedded) {\r\n subpath = '';\r\n }\r\n\r\n // Install the default OSK stylesheet - but don't have it managed by the keyboard-specific stylesheet manager.\r\n // We wish to maintain kmwosk.css whenever keyboard-specific styles are reset/removed.\r\n for(let sheetFile of OSKView.STYLESHEET_FILES) {\r\n const sheetHref = `${this.config.pathConfig.resources}/${subpath}${sheetFile}`;\r\n this.uiStyleSheetManager.linkExternalSheet(sheetHref);\r\n }\r\n\r\n // Any event-cancelers would go here, after the innerHTML reset.\r\n\r\n // Add header element to OSK only for desktop browsers\r\n if(this.headerView) {\r\n this._Box.appendChild(this.headerView.element);\r\n }\r\n\r\n // Add suggestion banner bar to OSK\r\n this._Box.appendChild(this.banner.element);\r\n\r\n if(this.bannerView.banner) {\r\n this.banner.banner.configureForKeyboard(this.keyboardData?.keyboard, this.keyboardData?.metadata);\r\n }\r\n\r\n let kbdView: KeyboardView = this.keyboardView = this._GenerateKeyboardView(this.keyboardData?.keyboard, this.keyboardData?.metadata);\r\n this._Box.appendChild(kbdView.element);\r\n kbdView.postInsert();\r\n\r\n // Add footer element to OSK only for desktop browsers\r\n if(this.footerView) {\r\n this._Box.appendChild(this.footerView.element);\r\n }\r\n // END: construction of the actual internal layout for the overall OSK\r\n\r\n this.banner.appendStyles();\r\n\r\n if(this.vkbd) {\r\n // Create the key preview (for phones)\r\n this.vkbd.createKeyTip();\r\n\r\n // Create the globe hint (for embedded contexts; has a stub for other contexts)\r\n const globeHint = this.vkbd.createGlobeHint();\r\n if(globeHint) {\r\n this._Box.appendChild(globeHint.element);\r\n }\r\n\r\n // Append a stylesheet for this keyboard for keyboard specific styles\r\n // or if needed to specify an embedded font\r\n this.vkbd.appendStyleSheet();\r\n }\r\n\r\n this.postKeyboardLoad();\r\n }\r\n\r\n private _GenerateKeyboardView(keyboard: Keyboard, keyboardMetadata: KeyboardProperties): KeyboardView {\r\n let device = this.targetDevice;\r\n\r\n if(this.vkbd) {\r\n this.vkbd.shutdown();\r\n }\r\n\r\n this._Box.className = \"\";\r\n\r\n // Case 1: since we hide the system keyboard on touch devices, we need\r\n // to display SOMETHING that can accept input.\r\n if(keyboard == null && !device.touchable) {\r\n // We do not (currently) allow selecting the default system keyboard on\r\n // touch form-factors. Likely b/c mnemonic difficulties.\r\n return new EmptyView();\r\n } else {\r\n // Generate a visual keyboard from the layout (or layout default)\r\n // Condition is false if no key definitions exist, formFactor == desktop, AND help text exists. All three.\r\n if(keyboard && keyboard.layout(device.formFactor as DeviceSpec.FormFactor)) {\r\n return this._GenerateVisualKeyboard(keyboard, keyboardMetadata);\r\n } else if(!keyboard /* && device.touchable (implied) */ || !keyboardMetadata) {\r\n // Show a basic, \"hollow\" OSK that at least allows input, since we're\r\n // on a touch device and hiding the system keyboard\r\n return this._GenerateVisualKeyboard(null, null);\r\n } else {\r\n // A keyboard help-page or help-text is still a visualization, even not a standard OSK.\r\n return new HelpPageView(keyboard);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Function _GenerateVisualKeyboard\r\n * Scope Private\r\n * @param {Object} keyboard The keyboard to visualize\r\n * Description Generates the visual keyboard element and attaches it to KMW\r\n */\r\n private _GenerateVisualKeyboard(keyboard: Keyboard, keyboardMetadata: KeyboardProperties): VisualKeyboard {\r\n let device = this.targetDevice;\r\n\r\n // Root element sets its own classes, one of which is 'kmw-osk-inner-frame'.\r\n let vkbd = new VisualKeyboard({\r\n keyboard: keyboard,\r\n keyboardMetadata: keyboardMetadata,\r\n device: device,\r\n hostDevice: this.hostDevice,\r\n topContainer: this._Box,\r\n styleSheetManager: this.kbdStyleSheetManager,\r\n pathConfig: this.config.pathConfig,\r\n embeddedGestureConfig: this.config.embeddedGestureConfig,\r\n isEmbedded: this.config.isEmbedded\r\n });\r\n\r\n vkbd.on('keyevent', (keyEvent) => this.emit('keyevent', keyEvent));\r\n vkbd.on('globekey', (keyElement, on) => this.emit('globekey', keyElement, on));\r\n vkbd.on('hiderequested', (keyElement) => {\r\n this.doHide(true);\r\n this.emit('hiderequested', keyElement);\r\n });\r\n\r\n // Set box class - OS and keyboard added for Build 360\r\n this._Box.className=device.formFactor+' '+ device.OS.toLowerCase() + ' kmw-osk-frame';\r\n\r\n // Add primary keyboard element to OSK\r\n return vkbd;\r\n }\r\n\r\n /**\r\n * This function may be provided to event sources to trigger changes in keyboard layer.\r\n * It is pre-bound to its OSKView instance.\r\n *\r\n ```\r\n {\r\n let core = com.keyman.singleton.core;\r\n core.keyboardProcessor.layerStore.handler = this.layerChangeHandler;\r\n }\r\n ```\r\n *\r\n * @param source\r\n * @param newValue\r\n * @returns\r\n */\r\n public layerChangeHandler: SystemStoreMutationHandler = (source: MutableSystemStore,\r\n newValue: string) => {\r\n // This handler is also triggered on state-key state changes (K_CAPS) that\r\n // may not actually change the layer.\r\n if(this.vkbd) {\r\n this.vkbd._UpdateVKShiftStyle(newValue);\r\n }\r\n\r\n if((this.vkbd && this.vkbd.layerId != newValue) || source.value != newValue) {\r\n // Prevents console errors when a keyboard only displays help.\r\n // Can occur when using SHIFT with sil_euro_latin on a desktop form-factor.\r\n //\r\n // Also, only change the layer ID itself if there is an actual corresponding layer\r\n // in the OSK.\r\n if(this.vkbd?.layerGroup.layers[newValue]) {\r\n this.vkbd.layerId = newValue;\r\n // Ensure that the layer's spacebar is properly captioned.\r\n this.vkbd.showLanguage();\r\n }\r\n\r\n // Ensure the keyboard view is modeling the correct state. (Correct layer, etc.)\r\n this.keyboardView.updateState(); // will also need the stateKeys.\r\n // We need to recalc the font size here because the layer did not have\r\n // calculated dimensions available before it was visible\r\n this.refreshLayout();\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * The main function for presenting the OSKView.\r\n *\r\n * This includes:\r\n * - refreshing its layout\r\n * - displaying it\r\n * - positioning it\r\n */\r\n public present(): void {\r\n // Do not try to display OSK if no active element\r\n if(!this.mayShow()) {\r\n return;\r\n }\r\n\r\n // Ensure the keyboard view is modeling the correct state. (Correct layer, etc.)\r\n this.keyboardView.updateState(); // get current state keys!\r\n\r\n this._Box.style.display='block'; // Is 'none' when hidden.\r\n\r\n // First thing after it's made visible.\r\n this.refreshLayoutIfNeeded();\r\n\r\n if(this.keyboardView instanceof VisualKeyboard) {\r\n this.keyboardView.showLanguage();\r\n }\r\n\r\n this._Visible=true;\r\n\r\n /* In case it's still '0' from a hide() operation.\r\n *\r\n * (Opacity is only modified when device.touchable = true,\r\n * though a couple of extra conditions may apply.)\r\n */\r\n this._Box.style.opacity = '1';\r\n\r\n // If OSK still hidden, make visible only after all calculation finished\r\n if(this._Box.style.visibility == 'hidden') {\r\n let _this = this;\r\n window.setTimeout(function() {\r\n _this._Box.style.visibility = 'visible';\r\n }, 0);\r\n }\r\n\r\n this.setDisplayPositioning();\r\n\r\n // Each subclass is responsible for raising the 'show' event on its own, since\r\n // certain ones supply extra information in their event param object.\r\n }\r\n\r\n /**\r\n * Method usable by subclasses of OSKView to control that OSKView type's\r\n * positioning behavior when needed by the present() method.\r\n */\r\n protected abstract setDisplayPositioning();\r\n\r\n /**\r\n * Method used to start a potentially-asynchronous hide of the OSK.\r\n * @param hiddenByUser `true` if this hide operation was directly requested by the user.\r\n */\r\n public startHide(hiddenByUser: boolean): void {\r\n if(!this.mayHide(hiddenByUser)) {\r\n return;\r\n }\r\n\r\n if(hiddenByUser) {\r\n // The one location outside of the `displayIfActive` property that bypasses the setter.\r\n // Avoids needless recursion that could be triggered by it, as we're already in the\r\n // process of hiding the OSK anyway.\r\n this.activationModel.enabled = ((this.keyboardData.keyboard.isCJK || this.hostDevice.touchable) ? true : false); // I3363 (Build 301)\r\n }\r\n\r\n let promise: Promise = null;\r\n if(this._Box && this.hostDevice.touchable && !(this.keyboardView instanceof EmptyView) && this.config.allowHideAnimations) {\r\n /**\r\n * Note: this refactored code appears to reflect a currently-dead code path. 14.0's\r\n * equivalent is either extremely niche or is actually inaccessible.\r\n */\r\n promise = this.useHideAnimation();\r\n } else {\r\n promise = Promise.resolve(true);\r\n }\r\n\r\n const _this = this;\r\n promise.then(function(shouldHide: boolean) {\r\n if(shouldHide) {\r\n _this.finalizeHide();\r\n }\r\n });\r\n\r\n // Allow UI to execute code when hiding the OSK\r\n this.doHide(hiddenByUser);\r\n }\r\n\r\n /**\r\n * Performs the _actual_ logic and functionality involved in hiding the OSK.\r\n */\r\n protected finalizeHide() {\r\n if(document.body.className.indexOf('osk-always-visible') >= 0) {\r\n return;\r\n }\r\n\r\n if(this._Box) {\r\n let bs=this._Box.style;\r\n bs.display = 'none';\r\n bs.transition = '';\r\n bs.opacity = '1';\r\n this._Visible=false;\r\n }\r\n\r\n if(this.vkbd) {\r\n this.vkbd.onHide();\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @returns `false` if the OSK is in an invalid state for being presented to the user.\r\n */\r\n protected mayShow(): boolean {\r\n if(!this.activationModel.conditionsMet) {\r\n return false;\r\n }\r\n\r\n // Never display the OSK for desktop browsers unless KMW element is focused, and a keyboard selected\r\n if(!this.keyboardView || this.keyboardView instanceof EmptyView || !this.activationModel.enabled) {\r\n return false;\r\n }\r\n\r\n if(!this._Box) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n *\r\n * @param hiddenByUser\r\n * @returns `false` if the OSK is in an invalid state for being hidden from the user.\r\n */\r\n protected mayHide(hiddenByUser: boolean): boolean {\r\n if(this.activationModel.conditionsMet && !this.mayDisable) {\r\n return false;\r\n }\r\n\r\n if(this.activationModel instanceof StaticActivator) {\r\n return false;\r\n }\r\n\r\n if(!hiddenByUser && this.hostDevice.formFactor == 'desktop') {\r\n //Allow desktop OSK to remain visible on blur if body class set\r\n if(document.body.className.indexOf('osk-always-visible') >= 0) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Applies CSS styling and handling needed to perform a fade animation when\r\n * hiding the OSK.\r\n *\r\n * Note: currently reflects an effectively-dead code path, though this is\r\n * likely not intentional. Other parts of the KMW engine seem to call hideNow()\r\n * synchronously after each and every part of the engine that calls this function,\r\n * cancelling the Promise.\r\n *\r\n * @returns A Promise denoting either cancellation of the hide (`false`) or\r\n * completion of the hide & its animation (`true`)\r\n */\r\n\r\n protected useHideAnimation(): Promise {\r\n const os = this._Box.style;\r\n const _this = this;\r\n\r\n return new Promise(function(resolve) {\r\n const cleanup = function() {\r\n // TODO(lowpri): attach event listeners on create and leave them there\r\n _this._Box.removeEventListener('transitionend', cleanup, false);\r\n _this._Box.removeEventListener('webkitTransitionEnd', cleanup, false);\r\n _this._Box.removeEventListener('transitioncancel', cleanup, false);\r\n _this._Box.removeEventListener('webkitTransitionCancel', cleanup, false);\r\n if(_this._animatedHideTimeout != 0) {\r\n window.clearTimeout(_this._animatedHideTimeout);\r\n }\r\n _this._animatedHideTimeout = 0;\r\n\r\n if(_this._Visible && _this.activationModel.conditionsMet) {\r\n // Leave opacity alone and clear transition if another element activated\r\n os.transition='';\r\n os.opacity='1';\r\n resolve(false);\r\n return false;\r\n } else {\r\n resolve(true);\r\n return true;\r\n }\r\n }, startup = function() {\r\n _this._Box.removeEventListener('transitionrun', startup, false);\r\n _this._Box.removeEventListener('webkitTransitionRun', startup, false);\r\n _this._Box.addEventListener('transitionend', cleanup, false);\r\n _this._Box.addEventListener('webkitTransitionEnd', cleanup, false);\r\n _this._Box.addEventListener('transitioncancel', cleanup, false);\r\n _this._Box.addEventListener('webkitTransitionCancel', cleanup, false);\r\n };\r\n\r\n _this._Box.addEventListener('transitionrun', startup, false);\r\n _this._Box.addEventListener('webkitTransitionRun', startup, false);\r\n\r\n os.transition='opacity 0.5s linear 0';\r\n os.opacity='0';\r\n\r\n // Cannot hide the OSK smoothly using a transitioned drop, since for\r\n // position:fixed elements transitioning is incompatible with translate3d(),\r\n // and also does not work with top, bottom or height styles.\r\n // Opacity can be transitioned and is probably the simplest alternative.\r\n // We must condition on osk._Visible in case focus has since been moved to another\r\n // input (in which case osk._Visible will be non-zero)\r\n _this._animatedHideTimeout = window.setTimeout(cleanup,\r\n 200); // Wait a bit before starting, to allow for moving to another element\r\n });\r\n }\r\n\r\n /**\r\n * Used to synchronously hide the OSK, cancelling any async hide animations that have\r\n * not started and immediately completing the hide of any hide ops pending completion\r\n * of their animation.\r\n */\r\n public hideNow() {\r\n if(!this.mayHide(false) || !this._Box) {\r\n return;\r\n }\r\n\r\n // Two possible uses for _animatedHideResolver:\r\n // - _animatedHideTimeout is set: animation is waiting to start\r\n // - _animatedHideTimeout is null: animation has already started.\r\n\r\n // Was an animated hide waiting to start? Just cancel it.\r\n if(this._animatedHideTimeout) {\r\n window.clearTimeout(this._animatedHideTimeout);\r\n this._animatedHideTimeout = 0;\r\n }\r\n\r\n // Was an animated hide already in progress? If so, just trigger it early.\r\n const os = this._Box.style;\r\n os.transition='';\r\n os.opacity='0';\r\n this.finalizeHide();\r\n }\r\n\r\n ['shutdown']() {\r\n // Disable the OSK's event handlers.\r\n this.removeBaseMouseEventListeners();\r\n this.removeBaseTouchEventListeners();\r\n\r\n // Remove the OSK's elements from the document, allowing them to be properly cleaned up.\r\n // Necessary for clean engine testing.\r\n var _box = this._Box;\r\n if(_box.parentElement) {\r\n _box.parentElement.removeChild(_box);\r\n }\r\n\r\n this.kbdStyleSheetManager.unlinkAll();\r\n this.uiStyleSheetManager.unlinkAll();\r\n }\r\n\r\n /**\r\n * Function getRect\r\n * Scope Public\r\n * @return {Object.} Array object with position and size of OSK container\r\n * Description Get rectangle containing KMW Virtual Keyboard\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/getRect\r\n */\r\n public getRect(): OSKRect {\t\t// I2405\r\n var p: OSKRect = {};\r\n\r\n // Always return these based upon _Box; using this.vkbd will fail to account for banner and/or\r\n // the desktop OSK border.\r\n p['left'] = p.left = getAbsoluteX(this._Box);\r\n p['top'] = p.top = getAbsoluteY(this._Box);\r\n\r\n p['width'] = this.computedWidth;\r\n p['height'] = this.computedHeight;\r\n return p;\r\n }\r\n\r\n /* ---- Legacy interfacing methods and fields ----\r\n *\r\n * The endgoal is to eliminate the need for these entirely, but extra work and care\r\n * will be necessary to achieve said endgoal for these methods.\r\n *\r\n * The simplest way forward is to maintain them, then resolve them independently,\r\n * one at a time.\r\n */\r\n\r\n // OSK state fields & events\r\n //\r\n // These are relatively stable and may be preserved as they are.\r\n _Visible: boolean = false;\r\n\r\n /**\r\n * Function enabled\r\n * Scope Public\r\n * @return {boolean|number} True if KMW OSK enabled\r\n * Description Test if KMW OSK is enabled\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/isEnabled\r\n */\r\n public isEnabled(): boolean {\r\n return this.displayIfActive;\r\n }\r\n\r\n /**\r\n * Function isVisible\r\n * Scope Public\r\n * @return {boolean|number} True if KMW OSK visible\r\n * Description Test if KMW OSK is actually visible\r\n * Note that this will usually return false after any UI event that results in (temporary) loss of input focus\r\n *\r\n * https://help.keyman.com/developer/engine/web/current-version/reference/osk/isVisible\r\n */\r\n public isVisible(): boolean {\r\n return this._Visible;\r\n }\r\n\r\n /**\r\n * Function hide\r\n * Scope Public\r\n * Description Prevent display of OSK window on focus\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/hide\r\n */\r\n public hide() {\r\n this.activationModel.enabled = false;\r\n this.startHide(true);\r\n }\r\n\r\n /**\r\n * Description Display KMW OSK (at position set in callback to UI)\r\n * Function show\r\n * Scope Public\r\n * @param {(boolean|number)=} bShow True to display, False to hide, omitted to toggle\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/show\r\n */\r\n public show(bShow?: boolean) {\r\n if(arguments.length > 0) {\r\n this.activationModel.enabled = bShow;\r\n } else {\r\n if(this.activationModel.conditionsMet) {\r\n this.activationModel.enabled = !this.activationModel.enabled;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Allow UI to respond to OSK being shown (passing position and properties)\r\n *\r\n * @param {Object=} p object with coordinates and userdefined flag\r\n * @return {boolean}\r\n *\r\n */\r\n doShow(p) {\r\n // Newer style 'doShow' emitted from .present by default.\r\n this.legacyEvents.callEvent('show', p);\r\n }\r\n\r\n /**\r\n * Allow UI to update respond to OSK being hidden\r\n *\r\n * @param {boolean} p object with coordinates and userdefined flag\r\n * @return {void}\r\n *\r\n */\r\n doHide(hiddenByUser: boolean) {\r\n const p={\r\n HiddenByUser: hiddenByUser\r\n };\r\n this.legacyEvents.callEvent('hide', p);\r\n }\r\n\r\n /**\r\n * Function addEventListener\r\n * Scope Public\r\n * @param {string} event event name\r\n * @param {function(Object)} func event handler\r\n * Description Wrapper function to add and identify OSK-specific event handlers\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/addEventListener\r\n */\r\n public addEventListener(\r\n event: T,\r\n fn: EventListener\r\n ): void {\r\n this.legacyEvents.addEventListener(event, fn);\r\n }\r\n\r\n /**\r\n * Function removeEventListener\r\n * Scope Public\r\n * @param {string} event event name\r\n * @param {function(Object)} func event handler\r\n * Description Wrapper function to remove previously-added OSK-specific event handlers\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/removeEventListener\r\n */\r\n public removeEventListener(\r\n event: T,\r\n fn: EventListener\r\n ): void {\r\n this.legacyEvents.removeEventListener(event, fn);\r\n }\r\n}", + "import EventEmitter from 'eventemitter3';\r\n\r\nimport { Banner, BlankBanner, ImageBanner, SuggestionBanner } from './banner.js';\r\nimport OSKViewComponent from '../components/oskViewComponent.interface.js';\r\nimport { ParsedLengthStyle } from '../lengthStyle.js';\r\n\r\nimport { DeviceSpec } from '@keymanapp/web-utils';\r\nimport type { PredictionContext, StateChangeEnum } from '@keymanapp/input-processor';\r\nimport { createUnselectableElement } from 'keyman/engine/dom-utils';\r\n\r\n/**\r\n * This object is used to specify options by both `BannerManager.getOptions`\r\n * and `BannerManager.setOptions`. Refer to the latter for specification of\r\n * each field.\r\n */\r\nexport interface BannerOptions {\r\n alwaysShow?: boolean;\r\n imagePath?: string;\r\n}\r\n\r\nexport type BannerType = \"blank\" | \"image\" | \"suggestion\";\r\n\r\ninterface BannerViewEventMap {\r\n 'bannerchange': () => void;\r\n}\r\n\r\n/**\r\n * The `BannerManager` module is designed to serve as a manager for the\r\n * different `Banner` types.\r\n * To facilitate this, it will provide a root element property that serves\r\n * as a container for any active `Banner`, helping KMW to avoid needless\r\n * DOM element shuffling.\r\n *\r\n * Goals for the `BannerManager`:\r\n *\r\n * * It will be exposed as `keyman.osk.banner` and will provide the following API:\r\n * * `getOptions`, `setOptions` - refer to the `BannerOptions` class for details.\r\n * * This provides a persistent point that the web page designers and our\r\n * model apps can utilize and can communicate with.\r\n * * These API functions are designed for live use and will allow\r\n * _hot-swapping_ the `Banner` instance; they're not initialization-only.\r\n * * Disabling the `Banner` (even for suggestions) outright with\r\n * `enablePredictions == false` will auto-unload any loaded predictive model\r\n * from `ModelManager` and setting it to `true` will revert this.\r\n * * This should help to avoid wasting computational resources.\r\n * * It will listen to ModelManager events and automatically swap Banner\r\n * instances as appropriate:\r\n * * The option `persistentBanner == true` is designed to replicate current\r\n * iOS system keyboard behavior.\r\n * * When true, an `ImageBanner` will be displayed.\r\n * * If false, it will be replaced with a `BlankBanner` of zero height,\r\n * corresponding to our current default lack of banner.\r\n * * It will not automatically set `persistentBanner == true`;\r\n * this must be set by the iOS app, and only under the following conditions:\r\n * * `keyman.isEmbedded == true`\r\n * * `device.OS == 'ios'`\r\n * * Keyman is being used as the system keyboard within an app that\r\n * needs to reserve this space (i.e: Keyman for iOS),\r\n * rather than as its standalone app.\r\n */\r\nexport default class BannerView implements OSKViewComponent {\r\n private bannerContainer: HTMLDivElement;\r\n private activeBanner: Banner;\r\n private _activeBannerHeight: number = Banner.DEFAULT_HEIGHT;\r\n\r\n public readonly events = new EventEmitter();\r\n\r\n constructor() {\r\n // Step 1 - establish the container element. Must come before this.setOptions.\r\n this.constructContainer();\r\n }\r\n\r\n /**\r\n * Constructs the
element used to contain hot-swapped `Banner` instances.\r\n */\r\n private constructContainer(): HTMLDivElement {\r\n let d = createUnselectableElement('div');\r\n d.id = \"keymanweb_banner_container\";\r\n d.className = \"kmw-banner-container\";\r\n return this.bannerContainer = d;\r\n }\r\n\r\n /**\r\n * Returns the `Banner`-containing div element used to facilitate hot-swapping.\r\n */\r\n public get element(): HTMLDivElement {\r\n return this.bannerContainer;\r\n }\r\n\r\n /**\r\n * Applies any stylesheets needed by specific `Banner` instances.\r\n */\r\n public appendStyles() {\r\n if(this.activeBanner) {\r\n this.activeBanner.appendStyleSheet();\r\n }\r\n }\r\n\r\n public get banner(): Banner {\r\n return this.activeBanner;\r\n }\r\n\r\n /**\r\n * Sets the active `Banner` to the specified type, regardless of\r\n * existing management logic settings.\r\n *\r\n * @param banner The `Banner` instance to set as active.\r\n */\r\n public set banner(banner: Banner) {\r\n if(this.activeBanner) {\r\n if(banner == this.activeBanner) {\r\n return;\r\n } else {\r\n let prevBanner = this.activeBanner;\r\n this.activeBanner = banner;\r\n this.bannerContainer.replaceChild(banner.getDiv(), prevBanner.getDiv());\r\n }\r\n } else {\r\n this.activeBanner = banner;\r\n if(banner) {\r\n this.bannerContainer.appendChild(banner.getDiv());\r\n }\r\n }\r\n\r\n if(!(banner instanceof BlankBanner)) {\r\n banner.height = this.activeBannerHeight;\r\n }\r\n\r\n this.events.emit('bannerchange');\r\n }\r\n\r\n /**\r\n * Gets the height (in pixels) of the active `Banner` instance.\r\n */\r\n public get height(): number {\r\n if(this.activeBanner) {\r\n return this.activeBanner.height;\r\n } else {\r\n return 0;\r\n }\r\n }\r\n\r\n public get activeBannerHeight(): number {\r\n return this._activeBannerHeight;\r\n }\r\n\r\n /**\r\n * Sets the height (in pixels) of the active 'Banner' instance.\r\n */\r\n public set activeBannerHeight(h: number) {\r\n this._activeBannerHeight = h;\r\n\r\n if (this.activeBanner && !(this.activeBanner instanceof BlankBanner)) {\r\n this.activeBanner.height = h;\r\n }\r\n }\r\n\r\n public get layoutHeight(): ParsedLengthStyle {\r\n return ParsedLengthStyle.inPixels(this.height);\r\n }\r\n\r\n public refreshLayout() {};\r\n}\r\n\r\nexport class BannerController {\r\n private _activeType: BannerType;\r\n private _options: BannerOptions = {};\r\n private container: BannerView;\r\n private alwaysShow: boolean;\r\n private imagePath?: string = \"\";\r\n\r\n private predictionContext?: PredictionContext;\r\n\r\n private readonly hostDevice: DeviceSpec;\r\n\r\n public static readonly DEFAULT_OPTIONS: BannerOptions = {\r\n alwaysShow: false,\r\n imagePath: \"\"\r\n }\r\n\r\n constructor(bannerView: BannerView, hostDevice: DeviceSpec, predictionContext?: PredictionContext) {\r\n // Step 1 - establish the container element. Must come before this.setOptions.\r\n this.hostDevice = hostDevice;\r\n this.container = bannerView;\r\n this.predictionContext = predictionContext;\r\n\r\n // Initialize with the default options - any 'manually set' options come post-construction.\r\n // This will also automatically set the default banner in place.\r\n this.setOptions(BannerController.DEFAULT_OPTIONS);\r\n }\r\n\r\n /**\r\n * This function corresponds to `keyman.osk.banner.getOptions`.\r\n *\r\n * Gets the current control settings in use by `BannerManager`.\r\n */\r\n public getOptions(): BannerOptions {\r\n let retObj = {};\r\n\r\n for(let key in this._options) {\r\n retObj[key] = this._options[key];\r\n }\r\n\r\n return retObj;\r\n }\r\n\r\n /**\r\n * This function corresponds to `keyman.osk.banner.setOptions`.\r\n *\r\n * Sets options used to tweak the automatic `Banner`\r\n * control logic used by `BannerManager`.\r\n * @param optionSpec An object specifying one or more of the following options:\r\n * * `persistentBanner` (boolean) When `true`, ensures that a `Banner`\r\n * is always displayed, even when no predictive model exists\r\n * for the active language.\r\n *\r\n * Default: `false`\r\n * * `imagePath` (URL string) Specifies the file path to use for an\r\n * `ImageBanner` when `persistentBanner` is `true` and no predictive model exists.\r\n *\r\n * Default: `''`.\r\n * * `enablePredictions` (boolean) Turns KMW predictions\r\n * on (when `true`) and off (when `false`).\r\n *\r\n * Default: `true`.\r\n */\r\n public setOptions(optionSpec: BannerOptions) {\r\n for(let key in optionSpec) {\r\n switch(key) {\r\n // Each defined option may require specialized handling.\r\n case 'alwaysShow':\r\n // Determines the banner type to activate.\r\n this.alwaysShow = optionSpec[key];\r\n break;\r\n case 'imagePath':\r\n // Determines the image file to use for ImageBanners.\r\n this.imagePath = optionSpec[key];\r\n break;\r\n default:\r\n // Invalid option specified!\r\n }\r\n this._options[key] = optionSpec[key];\r\n\r\n // If no banner instance exists yet, go with a safe, blank initialization.\r\n if(!this.container.banner) {\r\n this.selectBanner('inactive');\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sets the active `Banner` to the specified type, regardless of\r\n * existing management logic settings.\r\n *\r\n * @param type `'blank' | 'image' | 'suggestion'` - A plain-text string\r\n * representing the type of `Banner` to set active.\r\n * @param height - Optional banner height in pixels.\r\n */\r\n public setBanner(type: BannerType) {\r\n var banner: Banner;\r\n\r\n let oldBanner = this.container.banner;\r\n if(oldBanner instanceof SuggestionBanner) {\r\n this.predictionContext.off('update', oldBanner.onSuggestionUpdate);\r\n }\r\n\r\n switch(type) {\r\n case 'blank':\r\n banner = new BlankBanner();\r\n break;\r\n case 'image':\r\n banner = new ImageBanner(this.imagePath, this.container.activeBannerHeight);\r\n break;\r\n case 'suggestion':\r\n let suggestBanner = banner = new SuggestionBanner(this.hostDevice, this.container.activeBannerHeight);\r\n suggestBanner.predictionContext = this.predictionContext;\r\n suggestBanner.events.on('apply', (selection) => this.predictionContext.accept(selection.suggestion));\r\n\r\n this.predictionContext.on('update', suggestBanner.onSuggestionUpdate);\r\n break;\r\n default:\r\n throw new Error(\"Invalid type specified for the banner!\");\r\n }\r\n\r\n this._activeType = type;\r\n\r\n if(banner) {\r\n this.container.banner = banner;\r\n }\r\n }\r\n\r\n /**\r\n * Handles `LanguageProcessor`'s `'statechange'` events,\r\n * allowing logic to automatically hot-swap `Banner`s as needed.\r\n * @param state\r\n */\r\n selectBanner(state: StateChangeEnum) {\r\n // Only display a SuggestionBanner when LanguageProcessor states it is active.\r\n if(state == 'active' || state == 'configured') {\r\n this.setBanner('suggestion');\r\n } else if(state == 'inactive') {\r\n if(this.alwaysShow) {\r\n this.setBanner('image');\r\n } else {\r\n this.setBanner('blank');\r\n }\r\n }\r\n }\r\n\r\n public get activeType(): BannerType {\r\n return this._activeType;\r\n }\r\n}", + "import EventEmitter from 'eventemitter3';\r\n\r\nimport { DeviceSpec } from '@keymanapp/web-utils';\r\nimport { Keyboard, KeyboardProperties } from '@keymanapp/keyboard-processor';\r\nimport { type PredictionContext } from '@keymanapp/input-processor';\r\nimport InputEventEngine, { InputEventEngineConfig } from '../input/event-interpreter/inputEventEngine.js';\r\nimport MouseEventEngine from '../input/event-interpreter/mouseEventEngine.js';\r\nimport TouchEventEngine from '../input/event-interpreter/touchEventEngine.js';\r\nimport UITouchHandlerBase from '../input/event-interpreter/uiTouchHandlerBase.js';\r\n\r\nimport { createUnselectableElement } from 'keyman/engine/dom-utils';\r\n\r\n// Base class for a banner above the keyboard in the OSK\r\n\r\nexport abstract class Banner {\r\n private _height: number; // pixels\r\n private div: HTMLDivElement;\r\n\r\n public static DEFAULT_HEIGHT: number = 37; // pixels; embedded apps can modify\r\n\r\n public static readonly BANNER_CLASS: string = 'kmw-banner-bar';\r\n public static readonly BANNER_ID: string = 'kmw-banner-bar';\r\n\r\n /**\r\n * Function height\r\n * Scope Public\r\n * @returns {number} height in pixels\r\n * Description Returns the height of the banner in pixels\r\n */\r\n public get height(): number {\r\n return this._height;\r\n }\r\n\r\n /**\r\n * Function height\r\n * Scope Public\r\n * @param {number} height the height in pixels\r\n * Description Sets the height of the banner in pixels. If a negative\r\n * height is given, set height to 0 pixels.\r\n * Also updates the banner styling.\r\n */\r\n public set height(height: number) {\r\n this._height = (height > 0) ? height : 0;\r\n this.update();\r\n }\r\n\r\n /**\r\n * Function update\r\n * @return {boolean} true if the banner styling changed\r\n * Description Update the height and display styling of the banner\r\n */\r\n private update() : boolean {\r\n let ds = this.div.style;\r\n let currentHeightStyle = ds.height;\r\n let currentDisplayStyle = ds.display;\r\n\r\n if (this._height > 0) {\r\n ds.height = this._height + 'px';\r\n ds.display = 'block';\r\n } else {\r\n ds.height = '0px';\r\n ds.display = 'none';\r\n }\r\n\r\n return (!(currentHeightStyle === ds.height) ||\r\n !(currentDisplayStyle === ds.display));\r\n }\r\n\r\n public constructor(height?: number) {\r\n let d = createUnselectableElement('div');\r\n d.id = Banner.BANNER_ID;\r\n d.className = Banner.BANNER_CLASS;\r\n this.div = d;\r\n\r\n this.height = height;\r\n this.update();\r\n }\r\n\r\n public appendStyleSheet() {\r\n // TODO: add stylesheets\r\n // See VisualKeyboard's method + 'addFontStyle' for current handling.\r\n }\r\n\r\n /**\r\n * Function getDiv\r\n * Scope Public\r\n * @returns {HTMLElement} Base element of the banner\r\n * Description Returns the HTMLElelemnt of the banner\r\n */\r\n public getDiv(): HTMLElement {\r\n return this.div;\r\n }\r\n\r\n /**\r\n * Allows banners to adapt based on the active keyboard and related properties, such as\r\n * associated fonts.\r\n * @param keyboard\r\n * @param keyboardProperties\r\n */\r\n public configureForKeyboard(keyboard: Keyboard, keyboardProperties: KeyboardProperties) { }\r\n}\r\n\r\n/**\r\n * Function BlankBanner\r\n * Description A banner of height 0 that should not be shown\r\n */\r\nexport class BlankBanner extends Banner {\r\n\r\n constructor() {\r\n super(0);\r\n }\r\n}\r\n\r\n/**\r\n * Function ImageBanner\r\n * @param {string} imagePath Path of image to display in the banner\r\n * @param {number} height If provided, the height of the banner in pixels\r\n * Description Display an image in the banner\r\n */\r\nexport class ImageBanner extends Banner {\r\n private img: HTMLElement;\r\n\r\n constructor(imagePath: string, height?: number) {\r\n if (imagePath.length > 0) {\r\n super();\r\n if (height) {\r\n this.height = height;\r\n }\r\n } else {\r\n super(0);\r\n }\r\n\r\n if(imagePath.indexOf('base64') >=0) {\r\n console.log(\"Loading img from base64 data\");\r\n } else {\r\n console.log(\"Loading img with src '\" + imagePath + \"'\");\r\n }\r\n this.img = document.createElement('img');\r\n this.img.setAttribute('src', imagePath);\r\n let ds = this.img.style;\r\n ds.width = '100%';\r\n ds.height = '100%';\r\n this.getDiv().appendChild(this.img);\r\n console.log(\"Image loaded.\");\r\n }\r\n\r\n /**\r\n * Function setImagePath\r\n * Scope Public\r\n * @param {string} imagePath Path of image to display in the banner\r\n * Description Update the image in the banner\r\n */\r\n public setImagePath(imagePath: string) {\r\n if (this.img) {\r\n this.img.setAttribute('src', imagePath);\r\n }\r\n }\r\n}\r\n\r\nexport class BannerSuggestion {\r\n div: HTMLDivElement;\r\n private display: HTMLSpanElement;\r\n private fontFamily?: string;\r\n private rtl: boolean = false;\r\n\r\n private _suggestion: Suggestion;\r\n\r\n private index: number;\r\n\r\n static readonly BASE_ID = 'kmw-suggestion-';\r\n\r\n constructor(index: number, isRTL: boolean) {\r\n this.index = index;\r\n this.rtl = isRTL;\r\n\r\n this.constructRoot();\r\n\r\n // Provides an empty, base SPAN for text display. We'll swap these out regularly;\r\n // `Suggestion`s will have varying length and may need different styling.\r\n let display = this.display = createUnselectableElement('span');\r\n this.div.appendChild(display);\r\n }\r\n\r\n private constructRoot() {\r\n // Add OSK suggestion labels\r\n let div = this.div = createUnselectableElement('div'), ds=div.style;\r\n div.className = \"kmw-suggest-option\";\r\n div.id = BannerSuggestion.BASE_ID + this.index;\r\n\r\n // Ensures that a reasonable width % is set.\r\n let usableWidth = 100 - SuggestionBanner.MARGIN * (SuggestionBanner.SUGGESTION_LIMIT - 1);\r\n let widthpc = usableWidth / SuggestionBanner.SUGGESTION_LIMIT;\r\n\r\n ds.width = widthpc + '%';\r\n\r\n this.div['suggestion'] = this;\r\n }\r\n\r\n public matchKeyboardProperties(keyboardProperties: KeyboardProperties) {\r\n const div = this.div;\r\n\r\n if(keyboardProperties) {\r\n if (keyboardProperties['KLC']) {\r\n div.lang = keyboardProperties['KLC'];\r\n }\r\n\r\n // Establish base font settings\r\n let font = keyboardProperties['KFont'];\r\n if(font && font.family && font.family != '') {\r\n div.style.fontFamily = this.fontFamily = font.family;\r\n }\r\n }\r\n }\r\n\r\n get suggestion(): Suggestion {\r\n return this._suggestion;\r\n }\r\n\r\n /**\r\n * Function update\r\n * @param {string} id Element ID for the suggestion span\r\n * @param {Suggestion} suggestion Suggestion from the lexical model\r\n * Description Update the ID and text of the BannerSuggestionSpec\r\n */\r\n public update(suggestion: Suggestion) {\r\n this._suggestion = suggestion;\r\n this.updateText();\r\n }\r\n\r\n private updateText() {\r\n let display = this.generateSuggestionText(this.rtl);\r\n this.div.replaceChild(display, this.display);\r\n this.display = display;\r\n }\r\n\r\n public isEmpty(): boolean {\r\n return !this._suggestion;\r\n }\r\n\r\n /**\r\n * Function generateSuggestionText\r\n * @return {HTMLSpanElement} Span element of the suggestion\r\n * Description Produces a HTMLSpanElement with the key's actual text.\r\n */\r\n //\r\n public generateSuggestionText(rtl: boolean): HTMLSpanElement {\r\n let suggestion = this._suggestion;\r\n var suggestionText: string;\r\n\r\n var s=createUnselectableElement('span');\r\n s.className = 'kmw-suggestion-text';\r\n\r\n if(suggestion == null) {\r\n return s;\r\n }\r\n\r\n if(suggestion.displayAs == null || suggestion.displayAs == '') {\r\n suggestionText = '\\xa0'; // default: nbsp.\r\n } else {\r\n // Default the LTR ordering to match that of the active keyboard.\r\n let orderCode = rtl ? 0x202e /* RTL */ : 0x202d /* LTR */;\r\n suggestionText = String.fromCharCode(orderCode) + suggestion.displayAs;\r\n }\r\n\r\n // TODO: Dynamic suggestion text resizing. (Refer to OSKKey.getTextWidth in visualKeyboard.ts.)\r\n\r\n // Finalize the suggestion text\r\n s.innerHTML = suggestionText;\r\n return s;\r\n }\r\n}\r\n\r\n/**\r\n * Function SuggestionBanner\r\n * Scope Public\r\n * @param {number} height - If provided, the height of the banner in pixels\r\n * Description Display lexical model suggestions in the banner\r\n */\r\nexport class SuggestionBanner extends Banner {\r\n public static readonly SUGGESTION_LIMIT: number = 3;\r\n public static readonly MARGIN = 1;\r\n\r\n public readonly events: EventEmitter;\r\n\r\n private currentSuggestions: Suggestion[] = [];\r\n\r\n private options : BannerSuggestion[] = [];\r\n private hostDevice: DeviceSpec;\r\n\r\n private manager: SuggestionInputManager;\r\n\r\n private _predictionContext: PredictionContext;\r\n\r\n static readonly TOUCHED_CLASS: string = 'kmw-suggest-touched';\r\n static readonly BANNER_CLASS: string = 'kmw-suggest-banner';\r\n\r\n constructor(hostDevice: DeviceSpec, height?: number) {\r\n super(height || Banner.DEFAULT_HEIGHT);\r\n this.hostDevice = hostDevice;\r\n\r\n this.getDiv().className = this.getDiv().className + ' ' + SuggestionBanner.BANNER_CLASS;\r\n\r\n this.buildInternals(false);\r\n\r\n this.manager = new SuggestionInputManager(this.getDiv());\r\n this.events = this.manager.events;\r\n\r\n this.setupInputHandling();\r\n }\r\n\r\n buildInternals(rtl: boolean) {\r\n if(this.options.length > 0) {\r\n this.options.splice(0, this.options.length); // Clear the array.\r\n }\r\n for (var i=0; i {\r\n const elem = suggestion.div;\r\n let classes = elem.className;\r\n let cs = ' ' + SuggestionBanner.TOUCHED_CLASS;\r\n\r\n if(on && classes.indexOf(cs) < 0) {\r\n elem.className=classes+cs;\r\n } else {\r\n elem.className=classes.replace(cs,'');\r\n }\r\n });\r\n\r\n this.manager.events.on('apply', (option) => {\r\n if(this.predictionContext) {\r\n this.predictionContext.accept(option.suggestion);\r\n }\r\n });\r\n }\r\n\r\n public configureForKeyboard(keyboard: Keyboard, keyboardProperties: KeyboardProperties) {\r\n const rtl = keyboard.isRTL;\r\n\r\n // Removes all previous children. (.replaceChildren requires Chrome for Android 86.)\r\n // Instantly replaces all children with an empty text node, bypassing the need to actually\r\n // parse incoming HTML.\r\n //\r\n // Just in case, alternative approaches: https://stackoverflow.com/a/3955238\r\n this.getDiv().textContent = '';\r\n\r\n // Builds new children to match needed RTL properties.\r\n this.buildInternals(rtl);\r\n\r\n this.options.forEach((option) => option.matchKeyboardProperties(keyboardProperties));\r\n this.onSuggestionUpdate(this.currentSuggestions); // restore suggestions\r\n }\r\n\r\n private get mouseEventConfig() {\r\n const config: InputEventEngineConfig = {\r\n targetRoot: this.getDiv(),\r\n // document.body is the event root b/c we need to track the mouse if it leaves\r\n // the VisualKeyboard's hierarchy.\r\n eventRoot: document.body,\r\n inputStartHandler: this.manager.touchStart.bind(this.manager),\r\n inputMoveHandler: this.manager.touchMove.bind(this.manager),\r\n inputEndHandler: this.manager.touchEnd.bind(this.manager),\r\n coordConstrainedWithinInteractiveBounds: function() { return true; }\r\n };\r\n\r\n return new MouseEventEngine(config);\r\n }\r\n\r\n private get touchEventConfig() {\r\n const config: InputEventEngineConfig = {\r\n targetRoot: this.getDiv(),\r\n // document.body is the event root b/c we need to track the mouse if it leaves\r\n // the VisualKeyboard's hierarchy.\r\n eventRoot: this.getDiv(),\r\n inputStartHandler: this.manager.touchStart.bind(this.manager),\r\n inputMoveHandler: this.manager.touchMove.bind(this.manager),\r\n inputEndHandler: this.manager.touchEnd.bind(this.manager),\r\n coordConstrainedWithinInteractiveBounds: function() { return true; }\r\n };\r\n\r\n return new TouchEventEngine(config);\r\n }\r\n\r\n public get predictionContext(): PredictionContext {\r\n return this._predictionContext;\r\n }\r\n\r\n public set predictionContext(context: PredictionContext) {\r\n if(this._predictionContext) {\r\n // disconnect the old one!\r\n this._predictionContext.off('update', this.onSuggestionUpdate);\r\n }\r\n\r\n // connect the new one!\r\n this._predictionContext = context;\r\n if(context) {\r\n context.on('update', this.onSuggestionUpdate);\r\n this.onSuggestionUpdate(context.currentSuggestions);\r\n }\r\n }\r\n\r\n public onSuggestionUpdate = (suggestions: Suggestion[]): void => {\r\n this.currentSuggestions = suggestions;\r\n\r\n this.options.forEach((option: BannerSuggestion, i: number) => {\r\n if(i < suggestions.length) {\r\n option.update(suggestions[i]);\r\n } else {\r\n option.update(null);\r\n }\r\n });\r\n }\r\n}\r\n\r\ninterface SuggestionInputEventMap {\r\n highlight: (bannerSuggestion: BannerSuggestion, state: boolean) => void,\r\n apply: (bannerSuggestion: BannerSuggestion) => void;\r\n hold: (bannerSuggestion: BannerSuggestion) => void;\r\n}\r\n\r\nclass SuggestionInputManager extends UITouchHandlerBase {\r\n public readonly events = new EventEmitter();\r\n\r\n private eventDisablePromise: Promise;\r\n\r\n platformHold: (suggestion: BannerSuggestion, isCustom: boolean) => void;\r\n\r\n //#region Touch handling implementation\r\n findTargetFrom(e: HTMLElement): HTMLDivElement {\r\n try {\r\n if(e) {\r\n if(e.classList.contains('kmw-suggest-option')) {\r\n return e as HTMLDivElement;\r\n }\r\n if(e.parentElement && e.parentElement.classList.contains('kmw-suggest-option')) {\r\n return e.parentElement as HTMLDivElement;\r\n }\r\n // if(e.firstChild && util.hasClass( e.firstChild,'kmw-suggest-option')) {\r\n // return e.firstChild as HTMLDivElement;\r\n // }\r\n }\r\n } catch(ex) {}\r\n return null;\r\n }\r\n\r\n protected highlight(t: HTMLDivElement, on: boolean): void {\r\n let suggestion = t['suggestion'] as BannerSuggestion;\r\n\r\n // Never highlight an empty suggestion button.\r\n if(suggestion.isEmpty()) {\r\n on = false;\r\n }\r\n\r\n this.events.emit('highlight', suggestion, on);\r\n }\r\n\r\n protected select(t: HTMLDivElement): void {\r\n this.events.emit('apply', t['suggestion'] as BannerSuggestion);\r\n }\r\n\r\n //#region Long-press support\r\n protected hold(t: HTMLDivElement): void {\r\n // let suggestionObj = t['suggestion'] as BannerSuggestion;\r\n //\r\n // // Is this the suggestion? It's never in this.currentSuggestions, so check against that.\r\n // let isCustom = this.currentSuggestions.indexOf(suggestionObj.suggestion) == -1;\r\n\r\n this.events.emit('hold', t['suggestion'] as BannerSuggestion);\r\n }\r\n protected clearHolds(): void {\r\n // Temp, pending implementation of suggestion longpress submenus\r\n // - nothing to clear without them -\r\n\r\n // only really used in native-KMW\r\n }\r\n\r\n protected hasModalPopup(): boolean {\r\n return this.eventsBlocked;\r\n }\r\n\r\n protected dealiasSubTarget(target: HTMLDivElement): HTMLDivElement {\r\n return target;\r\n }\r\n\r\n protected hasSubmenu(t: HTMLDivElement): boolean {\r\n // Temp, pending implementation of suggestion longpress submenus\r\n\r\n // Only really used by native-KMW - see kmwnative's highlightSubKeys func.\r\n return false;\r\n }\r\n\r\n protected isSubmenuActive(): boolean {\r\n // Temp, pending implementation of suggestion longpress submenus\r\n\r\n // Utilized only by native-KMW - it parallels hasModalPopup() in purpose.\r\n return false;\r\n }\r\n\r\n protected displaySubmenuFor(target: HTMLDivElement) {\r\n // Utilized only by native-KMW to show submenus.\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n //#endregion\r\n //#endregion\r\n\r\n public get eventsBlocked(): boolean {\r\n return !!this.eventDisablePromise;\r\n }\r\n\r\n /**\r\n * Intended for use by the mobile apps, which sometimes 'takes over' touch handling.\r\n * For such cases, input should be blocked within KMW when the apps are managing an\r\n * ongoing touch-hold for any other interaction.\r\n *\r\n * Formerly:\r\n ```\r\n let keyman = com.keyman.singleton;\r\n return keyman['osk'].vkbd.subkeyGesture && keyman.isEmbedded;\r\n ```\r\n */\r\n public temporarilyBlockEvents(promise: Promise) { // TODO: ensure connection for embedded mode!\r\n this.eventDisablePromise = promise; // Will require routing; this class is not exported!\r\n promise.finally(() => {\r\n this.eventDisablePromise = null;\r\n })\r\n }\r\n\r\n constructor(div: HTMLElement) {\r\n // TODO: Determine appropriate CSS styling names, etc.\r\n super(div, Banner.BANNER_CLASS, SuggestionBanner.TOUCHED_CLASS);\r\n }\r\n}\r\n", + "import InputEventCoordinate from '../inputEventCoordinate.js';\r\n\r\nexport type InputHandler = (coord: InputEventCoordinate) => void;\r\n\r\nexport interface InputEventEngineConfig {\r\n /**\r\n * Specifies the element that input listeners should be attached to.\r\n */\r\n readonly eventRoot: HTMLElement;\r\n /**\r\n * Specifies the most specific common ancestor element of any event target\r\n * that the InputEventEngine should consider.\r\n */\r\n readonly targetRoot: HTMLElement;\r\n\r\n readonly coordConstrainedWithinInteractiveBounds: (coord: InputEventCoordinate) => boolean;\r\n\r\n readonly inputStartHandler?: InputHandler;\r\n readonly inputMoveHandler?: InputHandler;\r\n readonly inputMoveCancelHandler?: InputHandler;\r\n readonly inputEndHandler?: InputHandler;\r\n}\r\n\r\nexport default abstract class InputEventEngine {\r\n protected readonly config: InputEventEngineConfig;\r\n\r\n public constructor(config: InputEventEngineConfig) {\r\n this.config = config;\r\n }\r\n\r\n abstract registerEventHandlers();\r\n abstract unregisterEventHandlers();\r\n\r\n onInputStart(coord: InputEventCoordinate) {\r\n if(this.config.inputStartHandler) {\r\n this.config.inputStartHandler(coord);\r\n }\r\n }\r\n\r\n onInputMove(coord: InputEventCoordinate) {\r\n if(this.config.inputMoveHandler) {\r\n this.config.inputMoveHandler(coord);\r\n }\r\n }\r\n\r\n onInputMoveCancel(coord: InputEventCoordinate) {\r\n if(this.config.inputMoveCancelHandler) {\r\n this.config.inputMoveCancelHandler(coord);\r\n }\r\n }\r\n\r\n onInputEnd(coord: InputEventCoordinate) {\r\n if(this.config.inputEndHandler) {\r\n this.config.inputEndHandler(coord);\r\n }\r\n }\r\n}", + "/**\r\n * Represents the current location of the current cursor / touchpoint during\r\n * an ongoing OSK input event. This class standardizes to .pageX (document)\r\n * coordinates, rather than .clientX (viewport) coordinates.\r\n */\r\nexport default class InputEventCoordinate {\r\n public readonly x: number;\r\n public readonly y: number;\r\n\r\n private readonly source: MouseEvent | TouchEvent;\r\n\r\n public constructor(x: number, y: number, source?: MouseEvent | TouchEvent) {\r\n this.x = x;\r\n this.y = y;\r\n\r\n if(source) {\r\n this.source = source;\r\n }\r\n }\r\n\r\n // Converts a MouseEvent or TouchEvent into the base coordinates needed\r\n // by the mouse-dragging operations.\r\n public static fromEvent(e: MouseEvent | TouchEvent) {\r\n let coordSource: MouseEvent | Touch;\r\n\r\n // Desktop Safari versions as recent as 14.1 do not support TouchEvents.\r\n // So, just in case, a two-fold conditional check to avoid issues with a direct\r\n // 'instanceof' against the type.\r\n if(window['TouchEvent'] && e instanceof TouchEvent) {\r\n coordSource = e.changedTouches[0];\r\n } else if(e['changedTouches']) {\r\n coordSource = e['changedTouches'][0] as Touch;\r\n } else {\r\n coordSource = e as MouseEvent;\r\n }\r\n\r\n // For MouseEvents, .pageX is slightly less supported in older browsers when\r\n // compared to .clientX. They're about equally supported for TouchEvents.\r\n if (coordSource.pageX) {\r\n return new InputEventCoordinate(coordSource.pageX, coordSource.pageY, e);\r\n } else if (coordSource.clientX) {\r\n const x = coordSource.clientX + document.body.scrollLeft;\r\n const y = coordSource.clientY + document.body.scrollTop;\r\n\r\n return new InputEventCoordinate(x, y, e);\r\n } else {\r\n return new InputEventCoordinate(null, null, e);\r\n }\r\n }\r\n\r\n public get activeInputCount(): number {\r\n // May not be an ACTUAL touch event during unit tests.\r\n if(window['TouchEvent'] && this.source['touches'] !== undefined && this.source['touches'] !== null) {\r\n return this.source['touches'].length;\r\n } else {\r\n const event = this.source as MouseEvent;\r\n return event.buttons > 0 ? 1 : 0;\r\n }\r\n }\r\n\r\n public get target() {\r\n return this.source?.target;\r\n }\r\n\r\n public get isFromTouch(): boolean {\r\n return !this.isFromMouse;\r\n }\r\n\r\n public get isFromMouse(): boolean {\r\n return this.source instanceof MouseEvent;\r\n }\r\n}", + "import InputEventEngine, { InputEventEngineConfig } from './inputEventEngine.js';\r\nimport InputEventCoordinate from '../inputEventCoordinate.js';\r\n\r\nexport default class MouseEventEngine extends InputEventEngine {\r\n private readonly _mouseStart: typeof MouseEventEngine.prototype.onMouseStart;\r\n private readonly _mouseMove: typeof MouseEventEngine.prototype.onMouseMove;\r\n private readonly _mouseEnd: typeof MouseEventEngine.prototype.onMouseEnd;\r\n\r\n private hasActiveClick: boolean = false;\r\n private ignoreSequence: boolean = false;\r\n\r\n public constructor(config: InputEventEngineConfig) {\r\n super(config);\r\n\r\n this._mouseStart = this.onMouseStart.bind(this);\r\n this._mouseMove = this.onMouseMove.bind(this);\r\n this._mouseEnd = this.onMouseEnd.bind(this);\r\n }\r\n\r\n registerEventHandlers() {\r\n this.config.eventRoot.addEventListener('mousedown', this._mouseStart, true);\r\n this.config.eventRoot.addEventListener('mousemove', this._mouseMove, false);\r\n // The listener below fails to capture when performing automated testing checks in Chrome emulation unless 'true'.\r\n this.config.eventRoot.addEventListener('mouseup', this._mouseEnd, true);\r\n }\r\n\r\n unregisterEventHandlers() {\r\n this.config.eventRoot.removeEventListener('mousedown', this._mouseStart, true);\r\n this.config.eventRoot.removeEventListener('mousemove', this._mouseMove, false);\r\n this.config.eventRoot.removeEventListener('mouseup', this._mouseEnd, true);\r\n }\r\n\r\n private preventPropagation(e: MouseEvent) {\r\n // Standard event maintenance\r\n e.preventDefault();\r\n e.cancelBubble=true;\r\n e.returnValue=false; // I2409 - Avoid focus loss for visual keyboard events\r\n\r\n if(typeof e.stopImmediatePropagation == 'function') {\r\n e.stopImmediatePropagation();\r\n } else if(typeof e.stopPropagation == 'function') {\r\n e.stopPropagation();\r\n }\r\n }\r\n\r\n onMouseStart(event: MouseEvent) {\r\n if(!this.config.targetRoot.contains(event.target as Node)) {\r\n this.ignoreSequence = true;\r\n return;\r\n }\r\n\r\n this.preventPropagation(event);\r\n this.onInputStart(InputEventCoordinate.fromEvent(event));\r\n this.hasActiveClick = true;\r\n }\r\n\r\n onMouseMove(event: MouseEvent) {\r\n if(this.ignoreSequence) {\r\n return;\r\n }\r\n\r\n const coord = InputEventCoordinate.fromEvent(event);\r\n\r\n if(!event.buttons) {\r\n if(this.hasActiveClick) {\r\n this.hasActiveClick = false;\r\n this.onInputMoveCancel(coord);\r\n }\r\n return;\r\n } else if(!this.hasActiveClick) {\r\n // Can interfere with OSK drag-handlers (title bar, resize bar) otherwise.\r\n return;\r\n }\r\n\r\n this.preventPropagation(event);\r\n\r\n if(this.config.coordConstrainedWithinInteractiveBounds(coord)) {\r\n this.onInputMove(coord);\r\n } else {\r\n this.onInputMoveCancel(coord);\r\n }\r\n }\r\n\r\n onMouseEnd(event: MouseEvent) {\r\n if(this.ignoreSequence) {\r\n this.ignoreSequence = false;\r\n return;\r\n }\r\n\r\n if(!event.buttons) {\r\n this.hasActiveClick = false;\r\n }\r\n this.onInputEnd(InputEventCoordinate.fromEvent(event));\r\n }\r\n}", + "import InputEventEngine, { InputEventEngineConfig } from './inputEventEngine.js';\r\nimport InputEventCoordinate from '../inputEventCoordinate.js';\r\n\r\nexport default class TouchEventEngine extends InputEventEngine {\r\n private readonly _touchStart: typeof TouchEventEngine.prototype.onTouchStart;\r\n private readonly _touchMove: typeof TouchEventEngine.prototype.onTouchMove;\r\n private readonly _touchEnd: typeof TouchEventEngine.prototype.onTouchEnd;\r\n\r\n public constructor(config: InputEventEngineConfig) {\r\n super(config);\r\n\r\n this._touchStart = this.onTouchStart.bind(this);\r\n this._touchMove = this.onTouchMove.bind(this);\r\n this._touchEnd = this.onTouchEnd.bind(this);\r\n }\r\n\r\n registerEventHandlers() {\r\n this.config.eventRoot.addEventListener('touchstart', this._touchStart, true);\r\n this.config.eventRoot.addEventListener('touchmove', this._touchMove, false);\r\n // The listener below fails to capture when performing automated testing checks in Chrome emulation unless 'true'.\r\n this.config.eventRoot.addEventListener('touchend', this._touchEnd, true);\r\n }\r\n\r\n unregisterEventHandlers() {\r\n this.config.eventRoot.removeEventListener('touchstart', this._touchStart, true);\r\n this.config.eventRoot.removeEventListener('touchmove', this._touchMove, false);\r\n this.config.eventRoot.removeEventListener('touchend', this._touchEnd, true);\r\n }\r\n\r\n private preventPropagation(e: TouchEvent) {\r\n // Standard event maintenance\r\n e.preventDefault();\r\n e.cancelBubble=true;\r\n\r\n if(typeof e.stopImmediatePropagation == 'function') {\r\n e.stopImmediatePropagation();\r\n } else if(typeof e.stopPropagation == 'function') {\r\n e.stopPropagation();\r\n }\r\n }\r\n\r\n onTouchStart(event: TouchEvent) {\r\n this.onInputStart(InputEventCoordinate.fromEvent(event));\r\n }\r\n\r\n onTouchMove(event: TouchEvent) {\r\n this.preventPropagation(event);\r\n const coord = InputEventCoordinate.fromEvent(event);\r\n\r\n if(this.config.coordConstrainedWithinInteractiveBounds(coord)) {\r\n this.onInputMove(coord);\r\n } else {\r\n this.onInputMoveCancel(coord);\r\n }\r\n }\r\n\r\n onTouchEnd(event: TouchEvent) {\r\n this.onInputEnd(InputEventCoordinate.fromEvent(event));\r\n }\r\n}", + "import InputEventCoordinate from \"../inputEventCoordinate.js\";\r\nimport { getAbsoluteY } from 'keyman/engine/dom-utils';\r\n\r\n/**\r\n * This class was added to facilitate scroll handling for overflow-x elements, though it could\r\n * be extended in the future to accept overflow-y if needed.\r\n *\r\n * This is necessary because of the OSK's need to use `.preventDefault()` for stability; that\r\n * same method blocks native handling of overflow scrolling for touch browsers.\r\n */\r\nclass ScrollState {\r\n // While we don't currently track y-coordinates here, the class is designed\r\n // to permit tracking them with minimal extra effort if we ever decide to do so.\r\n x: number;\r\n totalLength = 0;\r\n\r\n // The amount of coordinate 'noise' allowed during a scroll-enabled touch allowed\r\n // before interpreting the currently-ongoing touch command as having scrolled.\r\n static readonly HAS_SCROLLED_FUDGE_FACTOR = 10;\r\n\r\n constructor(coord: InputEventCoordinate) {\r\n this.x = coord.x;\r\n\r\n this.totalLength = 0;\r\n }\r\n\r\n updateTo(coord: InputEventCoordinate): {deltaX: number} {\r\n let x = this.x;\r\n this.x = coord.x;\r\n\r\n let deltas = {deltaX: this.x - x};\r\n this.totalLength += Math.abs(deltas.deltaX);\r\n\r\n return deltas;\r\n }\r\n\r\n public get hasScrolled(): boolean {\r\n // Allow an accidental fudge-factor for overflow element noise during a touch, but not much.\r\n return this.totalLength > ScrollState.HAS_SCROLLED_FUDGE_FACTOR;\r\n }\r\n}\r\n\r\nexport default abstract class UITouchHandlerBase {\r\n private rowClassMatch: string;\r\n private selectedTargetMatch: string;\r\n private baseElement: HTMLElement;\r\n\r\n private touchX: number;\r\n private touchY: number;\r\n private touchCount: number;\r\n\r\n private currentTarget: Target;\r\n\r\n private scrollTouchState: ScrollState;\r\n private pendingTarget: Target;\r\n\r\n constructor(baseElement: HTMLElement, rowClassMatch: string, selectedTargetMatch: string) {\r\n this.baseElement = baseElement;\r\n this.rowClassMatch = rowClassMatch;\r\n this.selectedTargetMatch = selectedTargetMatch;\r\n }\r\n\r\n /**\r\n * Finds the internally-preferred target element or submenu target element.\r\n * @param e The DOM element that actually received the touch event.\r\n * May be parent, child, or the actually-desired element itself.\r\n */\r\n abstract findTargetFrom(e: HTMLElement): Target;\r\n\r\n /**\r\n * Highlights the target element as visual feedback representing\r\n * a pending touch.\r\n * @param t The `Target` to highlight\r\n * @param state `true` to apply highlighting, `false` to remove it.\r\n */\r\n protected abstract highlight(t: Target, state: boolean): void;\r\n\r\n /**\r\n * Called whenever the touch-handling analysis determines that the Target has been selected\r\n * @param t The `Target` to activate/execute.\r\n */\r\n protected abstract select(t: Target): void;\r\n\r\n /**\r\n * Requests info on whether or not the indicated `Target` has subkeys or a submenu.\r\n * @param t A `Target`.\r\n */\r\n protected abstract hasSubmenu(t: Target): boolean;\r\n\r\n /**\r\n * Indicates that the user is maintaining a `Touch` on the specified `Target`.\r\n * Popups and-or longpress menus may be appropriate.\r\n * @param t The `Target` being held.\r\n */\r\n protected abstract hold(t: Target): void;\r\n\r\n /**\r\n * Signals that any popup elements (previews, subkey views, etc) should be cancelled.\r\n */\r\n protected abstract clearHolds(): void;\r\n\r\n /**\r\n * Requests a boolean indicating whether or not the UI is currently displaying any input-blocking popup elements.\r\n * Embedded mode should return `true` when the app is displaying popup menus.\r\n */\r\n protected abstract hasModalPopup(): boolean;\r\n\r\n /**\r\n * Designed to support highlighting of prepended base keys on phone form-factor subkey menus.\r\n * @param target The base element with a potential subkey menu alias.\r\n * @returns The aliased submenu version of the `Target`, or the original `Target` if no alias exists.\r\n */\r\n protected abstract dealiasSubTarget(target: Target): Target;\r\n\r\n /**\r\n * Should return true whenever a 'native'-mode submenu (or subkey) display is active.\r\n */\r\n protected abstract isSubmenuActive(): boolean;\r\n\r\n /**\r\n * For 'native' mode - requests that the submenu for the indicated `Target` be instantly displayed.\r\n * @param target The base element with a potential submenu\r\n */\r\n protected abstract displaySubmenuFor(target: Target);\r\n\r\n /**\r\n * Identify the key nearest to (but NOT under) the touch point if at the end of a key row,\r\n * but return null more than about 0.6 key width from the nearest key.\r\n *\r\n * @param {Object} coord A pre-analyzed input coordinate\r\n * @param {Object} t HTML object at touch point\r\n * @param {boolean} omitCurrent Omits any target directly under the touch point.\r\n * @return {Object} nearest key to touch point\r\n *\r\n **/\r\n private findTargetFromTouch(coord: InputEventCoordinate, t: HTMLElement, forMove: boolean): Target {\r\n var x = coord.x;\r\n\r\n // Get the UI row beneath touch point (SuggestionBanner div, 'kmw-key-row' if OSK, ...)\r\n while(t && t.className !== undefined && t.className.indexOf(this.rowClassMatch) < 0) {\r\n t = t.parentNode;\r\n }\r\n if(!t) {\r\n return null;\r\n }\r\n\r\n // Find minimum distance from any key\r\n var k: number, bestMatch=0, dxMax=24, dxMin=100000, x1: number, x2: number;\r\n for(k = 0; k < t.childNodes.length; k++) {\r\n let childNode = t.childNodes[k] as HTMLElement;\r\n\r\n if(this.isInvalidTarget(this.findTargetFrom(childNode))) {\r\n continue;\r\n }\r\n\r\n x1 = childNode.offsetLeft;\r\n x2 = x1 + childNode.offsetWidth;\r\n\r\n // If it lies completely to the right and is the closest so far\r\n let dxRight = x1 - x;\r\n if(dxRight >= 0 && dxRight < dxMin) {\r\n bestMatch = k;\r\n dxMin = dxRight;\r\n }\r\n\r\n // If it lies completely to the left and is the closest so far\r\n let dxLeft = x - x2;\r\n if(dxLeft >= 0 && dxLeft < dxMin) {\r\n bestMatch = k;\r\n dxMin = dxLeft;\r\n }\r\n\r\n // If it is neither completely to the left nor completely to the right,\r\n // it's under the cursor. Stop the search!\r\n if(dxLeft < 0 && dxRight < 0) {\r\n return this.findTargetFrom(childNode);\r\n }\r\n }\r\n\r\n if(dxMin < 100000) {\r\n t = t.childNodes[bestMatch];\r\n x1 = t.offsetLeft;\r\n x2 = x1 + t.offsetWidth;\r\n\r\n // Limit extended touch area to the larger of 0.6 of the potential target's width and 24 px\r\n if(t.offsetWidth > 40) {\r\n dxMax = 0.6 * t.offsetWidth;\r\n }\r\n\r\n if(((x1 - x) >= 0 && (x1 - x) < dxMax) || ((x - x2) >= 0 && (x - x2) < dxMax)) {\r\n return this.findTargetFrom(t);\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n findBestTarget(coord: InputEventCoordinate, forMove?: boolean) {\r\n var eventTarget: HTMLElement;\r\n\r\n if(forMove) {\r\n const clientX = coord.x + document.body.scrollLeft;\r\n const clientY = coord.y + document.body.scrollTop;\r\n eventTarget = document.elementFromPoint(clientX, clientY) as HTMLElement;\r\n } else {\r\n eventTarget = coord.target as HTMLElement;\r\n }\r\n\r\n let target = this.findTargetFrom(eventTarget);\r\n\r\n // Should refactor this multi-check a bit for more overall reliability.\r\n if(!target) {\r\n // We didn't find a direct target, so we should look for the closest possible one.\r\n // Filters out invalid targets.\r\n target = this.findTargetFromTouch(coord, eventTarget, forMove);\r\n }\r\n\r\n return target;\r\n }\r\n\r\n /**\r\n * Reports whether or not a `Target` should be considered invalid. Needed by the OSK for\r\n * hidden keys.\r\n * @param target A `Target` element to be validated.\r\n */\r\n protected isInvalidTarget(target: Target): boolean {\r\n return false;\r\n }\r\n\r\n touchStart(coord: InputEventCoordinate) {\r\n // Determine the selected Target, manage state.\r\n this.currentTarget = this.findBestTarget(coord);\r\n this.touchX = coord.x;\r\n this.touchY = coord.y;\r\n\r\n // If popup stuff, immediately return.\r\n\r\n this.touchCount = coord.activeInputCount;\r\n\r\n if(!this.currentTarget) {\r\n return;\r\n }\r\n\r\n // Establish scroll tracking.\r\n let shouldScroll = (this.currentTarget.clientWidth < this.currentTarget.scrollWidth);\r\n this.scrollTouchState = shouldScroll ? new ScrollState(coord) : null;\r\n\r\n // Alright, Target acquired! Now to use it:\r\n\r\n // Highlight the touched key\r\n this.highlight(this.currentTarget,true);\r\n\r\n // If used by the OSK, the special function keys need immediate action\r\n // Add a `checkForImmediates()` to facilitate this.\r\n if(this.pendingTarget) {\r\n this.highlight(this.pendingTarget, false);\r\n this.select(this.pendingTarget);\r\n this.clearHolds();\r\n // Decrement the number of unreleased touch points to prevent\r\n // sending the keystroke again when the key is actually released\r\n this.touchCount--;\r\n } else {\r\n // If this key has subkey, start timer to display subkeys after delay, set up release\r\n this.hold(this.currentTarget);\r\n }\r\n this.pendingTarget = this.currentTarget;\r\n }\r\n\r\n touchEnd(coord: InputEventCoordinate): void {\r\n // Prevent incorrect multi-touch behaviour if native or device popup visible\r\n let t = this.currentTarget;\r\n\r\n if(this.isSubmenuActive() || this.hasModalPopup()) {\r\n // Ignore release if a multiple touch\r\n if(coord.activeInputCount > 0) {\r\n return;\r\n }\r\n\r\n // Cancel (but do not execute) pending key if neither a popup key or the base key\r\n if(t == null || t.id.indexOf('popup') < 0) {\r\n if (this.pendingTarget) {\r\n this.highlight(this.pendingTarget,false);\r\n }\r\n this.clearHolds();\r\n this.pendingTarget = null;\r\n }\r\n }\r\n\r\n // Test if moved off screen (effective release point must be corrected for touch point horizontal speed)\r\n // This is not completely effective and needs some tweaking, especially on Android\r\n var x = coord.x;\r\n var beyondEdge = ((x < 2 && this.touchX > 5) || (x > window.innerWidth - 2 && this.touchX < window.innerWidth - 5));\r\n\r\n if(this.scrollTouchState) {\r\n beyondEdge = beyondEdge || this.scrollTouchState.hasScrolled;\r\n }\r\n\r\n // Save then decrement current touch count\r\n var tc=this.touchCount;\r\n if(this.touchCount > 0) {\r\n this.touchCount--;\r\n }\r\n\r\n // Process and clear highlighting of pending target\r\n if(this.pendingTarget) {\r\n this.highlight(this.pendingTarget,false);\r\n\r\n // Output character unless moved off key\r\n if(this.pendingTarget.className.indexOf('hidden') < 0 && tc > 0 && !beyondEdge) {\r\n this.select(this.pendingTarget);\r\n }\r\n this.clearHolds();\r\n this.pendingTarget = null;\r\n // Always clear highlighting of current target on release (multi-touch)\r\n } else {\r\n t = this.findBestTarget(coord);\r\n\r\n if(t) {\r\n this.highlight(t,false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * OSK touch move event handler\r\n *\r\n * @param {Object} coord A pre-analyzed input coordinate\r\n *\r\n **/\r\n touchMove(coord: InputEventCoordinate) : void {\r\n //let keyman = com.keyman.singleton;\r\n\r\n // Do not attempt to support reselection of target key for overlapped keystrokes\r\n if(coord.activeInputCount > 1 || this.touchCount == 0) {\r\n return;\r\n }\r\n\r\n if(this.currentTarget && this.scrollTouchState != null) {\r\n let deltaX = this.scrollTouchState.updateTo(coord).deltaX;\r\n this.currentTarget.scrollLeft -= window.devicePixelRatio * deltaX;\r\n\r\n return;\r\n }\r\n\r\n // Get touch position\r\n var y = coord.y;\r\n\r\n // Move target key and highlighting\r\n var key0 = this.pendingTarget,\r\n key1 = this.findBestTarget(coord, true); // For the OSK, this ALSO gets subkeys.\r\n\r\n // If option should not be selectable, how do we re-target?\r\n\r\n\r\n // Do not move over keys if device popup visible\r\n if(this.hasModalPopup()) {\r\n if(key0) {\r\n this.highlight(key0,false);\r\n }\r\n this.pendingTarget=null;\r\n return;\r\n }\r\n\r\n // Use the popup duplicate of the base key if a phone with a visible popup array\r\n key1 = this.dealiasSubTarget(key1);\r\n\r\n // Identify current touch position (to manage off-key release)\r\n this.currentTarget = key1;\r\n\r\n // Clear previous key highlighting\r\n if(key0 && key1 && key1 !== key0) {\r\n this.highlight(key0,false);\r\n }\r\n\r\n // Code below directly related to subkeys should only be triggered within 'native' mode.\r\n // The embedded version instead passes info to the apps to produce their own subkeys in-app.\r\n\r\n // If popup is visible, need to move over popup, not over main keyboard\r\n if(key1 && this.hasSubmenu(key1)) {\r\n //this.highlightSubKeys(key1,x,y);\r\n\r\n // Currently only used by the banner... which currently does not do submenus.\r\n // // Native-mode: show popup keys immediately if touch moved up towards key array (KMEW-100, Build 353)\r\n // if(!keyman.isEmbedded && (this.touchY-y > 5) && !this.isSubmenuActive()) {\r\n // // Instantly show the submenu.\r\n // this.displaySubmenuFor(key1);\r\n // }\r\n\r\n // Once a subkey array is displayed, do not allow changing the base key.\r\n // Keep that array visible and accept no other options until the touch ends.\r\n if(key1 && key1.id.indexOf('popup') < 0) { // TODO: reliant on 'popup' in .id\r\n return;\r\n }\r\n\r\n // Highlight the base key on devices that do not append it to the subkey array.\r\n if(key1 && key1.className.indexOf(this.selectedTargetMatch) < 0) {\r\n this.highlight(key1,true);\r\n }\r\n // Cancel touch if moved up and off keyboard, unless popup keys visible\r\n } else {\r\n let base = this.baseElement;\r\n let top = getAbsoluteY(base);\r\n let height = base.offsetHeight;\r\n let yMin = Math.max(5, top - 0.25 * height);\r\n let yMax = (top + height) + 0.25 * height;\r\n if(key0 && (coord.y < yMin || coord.y > yMax)) {\r\n this.highlight(key0,false);\r\n this.clearHolds();\r\n this.pendingTarget = null;\r\n }\r\n }\r\n\r\n // Replace the target key, if any, by the new target key\r\n // Do not replace a null target, as that indicates the key has already been released\r\n if(key1 && this.pendingTarget) {\r\n this.pendingTarget = key1;\r\n }\r\n\r\n if(this.pendingTarget) {\r\n if(key1 && (key0 != key1 || key1.className.indexOf(this.selectedTargetMatch) < 0)) {\r\n this.highlight(key1,true);\r\n }\r\n }\r\n\r\n if(key0 && key1 && (key1 != key0) && (key1.id != '')) {\r\n // Display the touch-hold keys (after a pause)\r\n this.hold(key1);\r\n }\r\n }\r\n}\r\n", + "export interface LengthStyle {\r\n val: number,\r\n absolute: boolean,\r\n special?: 'em' | 'rem';\r\n};\r\n\r\nexport class ParsedLengthStyle implements LengthStyle {\r\n public readonly val: number;\r\n public readonly absolute: boolean;\r\n public readonly special: 'em' | 'rem';\r\n\r\n public constructor(style: LengthStyle | string) {\r\n let parsed: LengthStyle = (typeof style == 'string') ? ParsedLengthStyle.parseLengthStyle(style) : style;\r\n\r\n // While Object.assign would be nice (and previously, was used), it will break\r\n // on old but still supported versions of Android if their Chrome isn't updated.\r\n // Requires mobile Chrome 45+, but API 21 (5.0) launches with an older browser.\r\n\r\n // Object.assign(this, parsed);\r\n this.val = parsed.val;\r\n this.absolute = parsed.absolute;\r\n if(parsed.special) {\r\n this.special = parsed.special;\r\n }\r\n }\r\n\r\n public get styleString(): string {\r\n if(this.absolute) {\r\n return this.val + 'px';\r\n } else if(this.special) {\r\n // Only 'em' and 'rem' are allowed, and both may be treated similarly.\r\n // Both relate to font sizes, though the path to the reference element\r\n // differs between them.\r\n return this.val + this.special;\r\n } else {\r\n return (this.val * 100) + '%';\r\n }\r\n }\r\n\r\n public scaledBy(scalar: number): ParsedLengthStyle {\r\n return new ParsedLengthStyle({\r\n val: scalar * this.val,\r\n absolute: this.absolute\r\n });\r\n }\r\n\r\n public static inPixels(val: number): ParsedLengthStyle {\r\n return new ParsedLengthStyle({val: val, absolute: true});\r\n }\r\n\r\n public static inPercent(val: number): ParsedLengthStyle {\r\n return new ParsedLengthStyle({val: val/100, absolute: false});\r\n }\r\n\r\n public static forScalar(val: number): ParsedLengthStyle {\r\n return new ParsedLengthStyle({val: val, absolute: false});\r\n }\r\n\r\n public static special(val: number, suffix: 'em' | 'rem'): ParsedLengthStyle {\r\n return new ParsedLengthStyle({val: val, absolute: false, special: suffix});\r\n }\r\n\r\n private static parseLengthStyle(spec: string): LengthStyle {\r\n const val = parseFloat(spec);\r\n\r\n if(isNaN(val)) {\r\n // Cannot parse.\r\n console.error(\"Could not properly parse specified length style info: '\" + spec + \"'.\");\r\n return null;\r\n }\r\n\r\n return spec.indexOf('px') != -1 ? {val: val, absolute: true} :\r\n // 16 px ~= 12 pt.\r\n // Reference: https://kyleschaeffer.com/css-font-size-em-vs-px-vs-pt-vs-percent\r\n spec.indexOf('pt') != -1 ? {val: (4 * val / 3), absolute: true} :\r\n spec.indexOf('%') != -1 ? {val: val/100, absolute: false} :\r\n spec.indexOf('rem') != -1 ? {val: val, absolute: false, special: 'rem'} :\r\n spec.indexOf('em') != -1 ? {val: val, absolute: false, special: 'em'} :\r\n // At this point, assuming either Number or number in a string without units\r\n // Note: this one is NOT natively handled by browsers!\r\n // We'll treat it as if it were 'pt', since that's likely the user's\r\n // most familiar font size unit.\r\n {val: (4 * val / 3), absolute: true};\r\n }\r\n}\r\n", + "import KeyboardView from \"./keyboardView.interface.js\";\r\nimport { ParsedLengthStyle } from \"../lengthStyle.js\";\r\n\r\nexport default class EmptyView implements KeyboardView {\r\n readonly element: HTMLDivElement;\r\n\r\n constructor() {\r\n let Ldiv = this.element = document.createElement('div');\r\n Ldiv.style.userSelect = 'none';\r\n Ldiv.className='kmw-osk-none';\r\n }\r\n\r\n // No operations needed; this is a stand-in for the desktop OSK when no keyboard is active.\r\n public postInsert() { }\r\n public updateState() { }\r\n\r\n public refreshLayout() { }\r\n\r\n public get layoutHeight(): ParsedLengthStyle {\r\n return ParsedLengthStyle.inPixels(0);\r\n }\r\n}", + "import { Keyboard } from '@keymanapp/keyboard-processor';\r\n\r\nimport KeyboardView from './keyboardView.interface.js';\r\nimport { ParsedLengthStyle } from \"../lengthStyle.js\";\r\n\r\nexport default class HelpPageView implements KeyboardView {\r\n private readonly kbd: Keyboard;\r\n public readonly element: HTMLDivElement;\r\n\r\n private static readonly ID = 'kmw-osk-help-page';\r\n\r\n constructor(keyboard: Keyboard) {\r\n this.kbd = keyboard;\r\n\r\n var Ldiv = this.element = document.createElement('div');\r\n Ldiv.style.userSelect = \"none\";\r\n Ldiv.className = 'kmw-osk-static';\r\n Ldiv.id = HelpPageView.ID;\r\n Ldiv.innerHTML = keyboard.helpText;\r\n }\r\n\r\n public postInsert() {\r\n if(!this.element.parentElement || !document.getElementById(HelpPageView.ID)) {\r\n throw new Error(\"The HelpPage root element has not yet been inserted into the DOM.\");\r\n }\r\n\r\n if(this.kbd.hasScript) {\r\n // .parentElement: ensure this matches the _Box element from OSKManager / OSKView\r\n // Not a hard requirement for any known keyboards, but is asserted by legacy docs.\r\n this.kbd.embedScript(this.element.parentElement);\r\n }\r\n }\r\n\r\n public updateState() { }\r\n public refreshLayout() { }\r\n\r\n public get layoutHeight(): ParsedLengthStyle {\r\n return ParsedLengthStyle.inPercent(100);\r\n }\r\n}", + "import EventEmitter from 'eventemitter3';\r\n\r\nimport {\r\n ActiveKey,\r\n ActiveLayout,\r\n ButtonClass,\r\n DeviceSpec,\r\n type InternalKeyboardFont,\r\n Keyboard,\r\n KeyboardProperties,\r\n KeyDistribution,\r\n KeyEvent,\r\n Layouts,\r\n StateKeyMap\r\n} from '@keymanapp/keyboard-processor';\r\n\r\nimport { createStyleSheet, getAbsoluteX, getAbsoluteY, StylesheetManager } from 'keyman/engine/dom-utils';\r\n\r\nimport GlobeHint from './globehint.interface.js';\r\nimport InputEventCoordinate from './input/inputEventCoordinate.js';\r\nimport InputEventEngine, { InputEventEngineConfig } from './input/event-interpreter/inputEventEngine.js';\r\nimport MouseEventEngine from './input/event-interpreter/mouseEventEngine.js';\r\nimport TouchEventEngine from './input/event-interpreter/touchEventEngine.js';\r\nimport KeyboardView from './components/keyboardView.interface.js';\r\nimport { type KeyElement, getKeyFrom } from './keyElement.js';\r\nimport KeyTip from './keytip.interface.js';\r\nimport OSKKey, { OSKKeySpec } from './keyboard-layout/oskKey.js';\r\nimport OSKLayer from './keyboard-layout/oskLayer.js';\r\nimport OSKLayerGroup from './keyboard-layout/oskLayerGroup.js';\r\nimport { LengthStyle, ParsedLengthStyle } from './lengthStyle.js';\r\nimport PendingGesture from './input/gestures/pendingGesture.interface.js';\r\nimport RealizedGesture from './input/gestures/realizedGesture.interface.js';\r\nimport { defaultFontSize, getFontSizeStyle } from './fontSizeUtils.js';\r\nimport PendingMultiTap, { PendingMultiTapState } from './input/gestures/browser/pendingMultiTap.js';\r\nimport InternalSubkeyPopup from './input/gestures/browser/subkeyPopup.js';\r\nimport InternalPendingLongpress from './input/gestures/browser/pendingLongpress.js';\r\nimport InternalKeyTip from './input/gestures/browser/keytip.js';\r\nimport CommonConfiguration from './config/commonConfiguration.js';\r\n\r\nimport { getViewportScale } from './screenUtils.js';\r\n\r\nexport interface VisualKeyboardConfiguration extends CommonConfiguration {\r\n /**\r\n * The Keyman keyboard on which to base the on-screen keyboard being represented.\r\n */\r\n keyboard: Keyboard,\r\n\r\n /**\r\n * Metadata about the keyboard, such as relevant fonts, display name, and language code.\r\n *\r\n * Designed for use with `KeyboardStub` objects, which are defined external to the\r\n * on-screen keyboard module.\r\n */\r\n keyboardMetadata: KeyboardProperties,\r\n\r\n /**\r\n * OSK-internal: the top-most element of the full on-screen keyboard element hierarchy.\r\n *\r\n * May be set to `null` if `isStatic` is `true`.\r\n */\r\n topContainer: HTMLElement,\r\n\r\n /**\r\n * Set to `true` for documentation keyboards, disabling all user-interactivity.\r\n */\r\n isStatic?: boolean,\r\n\r\n /**\r\n * Provide this field with the OSKView's stylesheet per-keyboard manager instance.\r\n *\r\n * Interim developer note: do NOT attach kmwosk.css using the same instance! We don't\r\n * want to remove that one when swapping keyboards.\r\n */\r\n styleSheetManager: StylesheetManager;\r\n}\r\n\r\ninterface BoundingRect {\r\n left: number,\r\n right: number,\r\n top: number,\r\n bottom: number\r\n};\r\n\r\ninterface EventMap {\r\n /**\r\n * Designed to pass key events off to any consuming modules/libraries.\r\n *\r\n * Note: the following code block was originally used to integrate with the keyboard & input\r\n * processors, but it requires entanglement with components external to this OSK module.\r\n */\r\n 'keyevent': (event: KeyEvent) => void,\r\n\r\n 'hiderequested': (keyElement: KeyElement) => void,\r\n\r\n 'globekey': (keyElement: KeyElement, on: boolean) => void\r\n}\r\n\r\nexport default class VisualKeyboard extends EventEmitter implements KeyboardView {\r\n // Legacy alias, maintaining a reference for code built against older\r\n // versions of KMW.\r\n static readonly specialCharacters = OSKKey.specialCharacters;\r\n\r\n /**\r\n * Contains layout properties corresponding to the OSK's layout. Needs to be public\r\n * so that its geometry may be updated on rotations and keyboard resize events, as\r\n * said geometry needs to be accurate for fat-finger probability calculations.\r\n */\r\n kbdLayout: ActiveLayout;\r\n layerGroup: OSKLayerGroup;\r\n\r\n readonly config: VisualKeyboardConfiguration;\r\n\r\n private _layerId: string = \"default\";\r\n layerIndex: number = 0; // the index of the default layer\r\n readonly isRTL: boolean;\r\n\r\n inputEngine: InputEventEngine;\r\n\r\n readonly isStatic: boolean = false;\r\n _fixedWidthScaling: boolean = false;\r\n _fixedHeightScaling: boolean = true;\r\n\r\n // Stores the base element for this instance of the visual keyboard.\r\n kbdDiv: HTMLDivElement;\r\n styleSheet: HTMLStyleElement;\r\n\r\n /**\r\n * The configured width for this VisualKeyboard. May be `undefined` or `null`\r\n * to allow automatic width scaling.\r\n */\r\n private _width: number;\r\n\r\n /**\r\n * The configured height for this VisualKeyboard. May be `undefined` or `null`\r\n * to allow automatic height scaling.\r\n */\r\n private _height: number;\r\n\r\n /**\r\n * The computed width for this VisualKeyboard. May be null if auto sizing\r\n * is allowed and the VisualKeyboard is not currently in the DOM hierarchy.\r\n */\r\n private _computedWidth: number;\r\n\r\n /**\r\n * The computed height for this VisualKeyboard. May be null if auto sizing\r\n * is allowed and the VisualKeyboard is not currently in the DOM hierarchy.\r\n */\r\n private _computedHeight: number;\r\n\r\n // Style-related properties\r\n fontFamily: string;\r\n private _fontSize: ParsedLengthStyle;\r\n // fontSize: string;\r\n\r\n // State-related properties\r\n keyPending: KeyElement;\r\n touchPending: InputEventCoordinate;\r\n deleteKey: KeyElement;\r\n deleting: number; // Tracks a timer id for repeated deletions.\r\n nextLayer: string;\r\n currentKey: string;\r\n stateKeys: StateKeyMap = {\r\n K_CAPS: false,\r\n K_NUMLOCK: false,\r\n K_SCROLL: false\r\n };\r\n\r\n // Touch-tracking properties\r\n initTouchCoord: InputEventCoordinate;\r\n touchCount: number;\r\n currentTarget: KeyElement;\r\n\r\n // Used by embedded-mode's globe key\r\n menuEvent: KeyElement; // Used by embedded-mode.\r\n\r\n // Popup key management\r\n keytip: KeyTip;\r\n globeHint: GlobeHint;\r\n pendingSubkey: PendingGesture;\r\n subkeyGesture: RealizedGesture;\r\n\r\n // Multi-tap gesture management\r\n pendingMultiTap: PendingMultiTap;\r\n\r\n // The keyboard object corresponding to this VisualKeyboard.\r\n public readonly layoutKeyboard: Keyboard;\r\n public readonly layoutKeyboardProperties: KeyboardProperties;\r\n\r\n get layerId(): string {\r\n return this._layerId;\r\n }\r\n\r\n set layerId(value: string) {\r\n const changedLayer = value != this._layerId;\r\n if(!this.layerGroup.layers[value]) {\r\n throw new Error(`Keyboard ${this.layoutKeyboard.id} does not have a layer with id ${value}`);\r\n } else {\r\n this._layerId = value;\r\n }\r\n\r\n if(changedLayer) {\r\n this.updateState();\r\n this.refreshLayout();\r\n }\r\n }\r\n\r\n get currentLayer(): OSKLayer {\r\n return this.layerId ? this.layerGroup?.layers[this.layerId] : null;\r\n }\r\n\r\n // Special keys (for the currently-visible layer)\r\n get lgKey(): KeyElement { // currently, must be visible for the touch language menu.\r\n return this.currentLayer?.globeKey?.btn;\r\n }\r\n\r\n private get hkKey(): KeyElement { // hide keyboard key\r\n return this.currentLayer?.hideKey?.btn;\r\n }\r\n\r\n public get spaceBar(): KeyElement { // also referenced by the touch language menu.\r\n return this.currentLayer?.spaceBarKey?.btn;\r\n }\r\n\r\n //#region OSK constructor and helpers\r\n\r\n /**\r\n * @param {Object} PVK Visual keyboard name\r\n * @param {Object} Lhelp true if OSK defined for this keyboard\r\n * @param {Object} layout0\r\n * @param {Number} kbdBitmask Keyboard modifier bitmask\r\n * Description Generates the base visual keyboard element, prepping for attachment to KMW\r\n */\r\n constructor(config: VisualKeyboardConfiguration) {\r\n super();\r\n\r\n this.config = config; // TODO: replace related parameters.\r\n\r\n this.config.device = config.device || config.hostDevice;\r\n this.config.isEmbedded = config.isEmbedded || false;\r\n\r\n if (config.isStatic) {\r\n this.isStatic = config.isStatic;\r\n }\r\n\r\n this._fixedWidthScaling = this.device.touchable && !this.isStatic;\r\n this._fixedHeightScaling = this.device.touchable && !this.isStatic;\r\n\r\n // Create the collection of HTML elements from the device-dependent layout object\r\n var Lkbd = document.createElement('div');\r\n this.config.styleSheetManager = config.styleSheetManager || new StylesheetManager(Lkbd);\r\n\r\n let layout: ActiveLayout;\r\n if (config.keyboard) {\r\n layout = this.kbdLayout = config.keyboard.layout(config.device.formFactor);\r\n this.layoutKeyboardProperties = config.keyboardMetadata;\r\n this.isRTL = config.keyboard.isRTL;\r\n } else {\r\n // This COULD be called with no backing keyboard; KMW will try to force-show the OSK even without\r\n // a backing keyboard on mobile, using the most generic default layout as the OSK's base.\r\n //\r\n // In KMW's current state, it'd take a major break, though - Processor always has an activeKeyboard,\r\n // even if it's \"hollow\".\r\n let rawLayout = Layouts.buildDefaultLayout(null, null, config.device.formFactor);\r\n layout = this.kbdLayout = ActiveLayout.polyfill(rawLayout, null, config.device.formFactor);\r\n // null will probably need to be replaced with a defined value.\r\n this.layoutKeyboardProperties = null;\r\n this.isRTL = false;\r\n }\r\n\r\n // Override font if specified by keyboard\r\n if ('font' in layout) {\r\n this.fontFamily = layout['font'];\r\n } else {\r\n this.fontFamily = '';\r\n }\r\n\r\n // Now to build the actual layout.\r\n const formFactor = config.device.formFactor;\r\n this.layoutKeyboard = config.keyboard;\r\n if (!this.layoutKeyboard) {\r\n // May occasionally be null in embedded contexts; have seen this when iOS engine sets\r\n // keyboard height during change of keyboards.\r\n this.layoutKeyboard = new Keyboard(null);\r\n }\r\n\r\n this.layerGroup = new OSKLayerGroup(this, this.layoutKeyboard, formFactor);\r\n\r\n // Now that we've properly processed the keyboard's layout, mark it as calibrated.\r\n // TODO: drop the whole 'calibration' thing. The newer layout system supersedes the\r\n // need for it. (Is no longer really used, so the drop ought be clean.)\r\n this.layoutKeyboard.markLayoutCalibrated(formFactor);\r\n\r\n // Append the OSK layer group container element to the containing element\r\n //osk.keyMap = divLayerContainer;\r\n Lkbd.appendChild(this.layerGroup.element);\r\n\r\n // Set base class - OS and keyboard added for Build 360\r\n this.kbdDiv = Lkbd;\r\n\r\n // For 'live' touch keyboards, attach touch-based event handling.\r\n // Needs to occur AFTER this.kbdDiv is initialized.\r\n if (!this.isStatic) {\r\n if (this.hostDevice.touchable) {\r\n this.inputEngine = this.touchInputConfiguration;\r\n } else {\r\n this.inputEngine = this.mouseInputConfiguration;\r\n }\r\n this.inputEngine.registerEventHandlers();\r\n }\r\n\r\n Lkbd.classList.add(config.device.formFactor, 'kmw-osk-inner-frame');\r\n\r\n // Tag the VisualKeyboard with a CSS class corresponding to its ID.\r\n let kbdID: string = this.layoutKeyboard?.id.replace('Keyboard_','') ?? '';\r\n\r\n const separatorIndex = kbdID.indexOf('::');\r\n if(separatorIndex != -1) { // We used to also test if we were in embedded mode, but... whatever.\r\n // De-namespaces the ID for use with CSS classes.\r\n // Assumes that keyboard IDs may not contain the ':' symbol.\r\n kbdID = kbdID.substring(separatorIndex + 2);\r\n }\r\n\r\n const kbdClassSuffix = 'kmw-keyboard-' + kbdID;\r\n this.element.classList.add(kbdClassSuffix);\r\n }\r\n\r\n private get mouseInputConfiguration() {\r\n const config: InputEventEngineConfig = {\r\n targetRoot: this.element,\r\n // document.body is the event root b/c we need to track the mouse if it leaves\r\n // the VisualKeyboard's hierarchy.\r\n eventRoot: document.body,\r\n inputStartHandler: this.touch.bind(this),\r\n inputMoveHandler: this.moveOver.bind(this),\r\n inputMoveCancelHandler: this.moveCancel.bind(this),\r\n inputEndHandler: this.release.bind(this),\r\n coordConstrainedWithinInteractiveBounds: this.detectWithinInteractiveBounds.bind(this)\r\n };\r\n\r\n return new MouseEventEngine(config);\r\n }\r\n\r\n private get touchInputConfiguration() {\r\n let config: InputEventEngineConfig = {\r\n targetRoot: this.element,\r\n eventRoot: this.element,\r\n inputStartHandler: this.touch.bind(this),\r\n inputMoveHandler: this.moveOver.bind(this),\r\n inputMoveCancelHandler: this.moveCancel.bind(this),\r\n inputEndHandler: this.release.bind(this),\r\n coordConstrainedWithinInteractiveBounds: this.detectWithinInteractiveBounds.bind(this)\r\n };\r\n\r\n return new TouchEventEngine(config);\r\n }\r\n\r\n public get element(): HTMLDivElement {\r\n return this.kbdDiv;\r\n }\r\n\r\n public get device(): DeviceSpec {\r\n return this.config.device;\r\n }\r\n\r\n public get hostDevice(): DeviceSpec {\r\n return this.config.hostDevice;\r\n }\r\n\r\n public get fontRootPath(): string {\r\n return this.config.pathConfig.fonts;\r\n }\r\n\r\n public get styleSheetManager(): StylesheetManager {\r\n return this.config.styleSheetManager;\r\n }\r\n\r\n public get topContainer(): HTMLElement {\r\n return this.config.topContainer;\r\n }\r\n\r\n public get isEmbedded(): boolean {\r\n return this.config.isEmbedded;\r\n }\r\n\r\n public postInsert(): void { }\r\n\r\n /**\r\n * The configured width for this VisualKeyboard. May be `undefined` or `null`\r\n * to allow automatic width scaling.\r\n */\r\n get width(): number {\r\n return this._width;\r\n }\r\n\r\n /**\r\n * The configured height for this VisualKeyboard. May be `undefined` or `null`\r\n * to allow automatic height scaling.\r\n */\r\n get height(): number {\r\n return this._height;\r\n }\r\n\r\n get layoutWidth(): ParsedLengthStyle {\r\n if (this.usesFixedWidthScaling) {\r\n let baseWidth = this.width;\r\n let cs = getComputedStyle(this.element);\r\n if (cs.border) {\r\n let borderWidth = new ParsedLengthStyle(cs.borderWidth).val;\r\n baseWidth -= borderWidth * 2;\r\n }\r\n return ParsedLengthStyle.inPixels(baseWidth);\r\n } else {\r\n return ParsedLengthStyle.forScalar(1);\r\n }\r\n }\r\n\r\n get layoutHeight(): ParsedLengthStyle {\r\n if (this.usesFixedHeightScaling) {\r\n let baseHeight = this.height;\r\n let cs = getComputedStyle(this.element);\r\n if (cs.border) {\r\n let borderHeight = new ParsedLengthStyle(cs.borderWidth).val;\r\n baseHeight -= borderHeight * 2;\r\n }\r\n return ParsedLengthStyle.inPixels(baseHeight);\r\n } else {\r\n return ParsedLengthStyle.forScalar(1);\r\n }\r\n }\r\n\r\n get internalHeight(): ParsedLengthStyle {\r\n if (this.usesFixedHeightScaling) {\r\n // Touch OSKs may apply internal padding to prevent row cropping at the edges.\r\n return ParsedLengthStyle.inPixels(this.layoutHeight.val - this.getVerticalLayerGroupPadding());\r\n } else {\r\n return ParsedLengthStyle.forScalar(1);\r\n }\r\n }\r\n\r\n get fontSize(): ParsedLengthStyle {\r\n if (!this._fontSize) {\r\n this._fontSize = new ParsedLengthStyle('1em');\r\n }\r\n return this._fontSize;\r\n }\r\n\r\n set fontSize(value: ParsedLengthStyle) {\r\n this._fontSize = value;\r\n this.kbdDiv.style.fontSize = value.styleString;\r\n }\r\n\r\n /**\r\n * Uses fixed scaling for widths of internal elements, rather than relative,\r\n * percent-based scaling.\r\n */\r\n public get usesFixedWidthScaling(): boolean {\r\n return this._fixedWidthScaling;\r\n }\r\n\r\n public set usesFixedWidthScaling(val: boolean) {\r\n this._fixedWidthScaling = val;\r\n }\r\n\r\n /**\r\n * Uses fixed scaling for heights of internal elements, rather than relative,\r\n * percent-based scaling.\r\n */\r\n public get usesFixedHeightScaling(): boolean {\r\n return this._fixedHeightScaling;\r\n }\r\n\r\n public set usesFixedHeightScaling(val: boolean) {\r\n this._fixedHeightScaling = val;\r\n }\r\n\r\n /**\r\n * Denotes if the VisualKeyboard or its containing OSKView / OSKManager uses\r\n * fixed positioning.\r\n */\r\n public get usesFixedPositioning(): boolean {\r\n let node: HTMLElement = this.element;\r\n while (node) {\r\n if (getComputedStyle(node).position == 'fixed') {\r\n return true;\r\n } else {\r\n node = node.offsetParent as HTMLElement;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Sets & tracks the size of the VisualKeyboard's primary element.\r\n * @param width\r\n * @param height\r\n * @param pending Set to `true` if called during a resizing interaction\r\n */\r\n public setSize(width?: number, height?: number, pending?: boolean) {\r\n this._width = width;\r\n this._height = height;\r\n\r\n if (this.kbdDiv) {\r\n this.kbdDiv.style.width = width ? this._width + 'px' : '';\r\n this.kbdDiv.style.height = height ? this._height + 'px' : '';\r\n\r\n if (!this.device.touchable && height) {\r\n this.fontSize = new ParsedLengthStyle((this._height / 8) + 'px');\r\n }\r\n\r\n if (!pending) {\r\n this.refreshLayout();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns the default properties for a key object, used to construct\r\n * both a base keyboard key and popup keys\r\n *\r\n * @return {Object} An object that contains default key properties\r\n */\r\n getDefaultKeyObject(): OSKKeySpec {\r\n return new OSKKeySpec(undefined, '', ActiveKey.DEFAULT_KEY.width, ActiveKey.DEFAULT_KEY.sp as ButtonClass,\r\n null, ActiveKey.DEFAULT_KEY.pad);\r\n };\r\n //#endregion\r\n\r\n //#region OSK touch handlers\r\n getTouchCoordinatesOnKeyboard(input: InputEventCoordinate) {\r\n // We need to compute the 'local', keyboard-based coordinates for the touch.\r\n let kbdCoords = {\r\n x: getAbsoluteX(this.kbdDiv),\r\n y: getAbsoluteY(this.kbdDiv)\r\n }\r\n let offsetCoords = { x: input.x - kbdCoords.x, y: input.y - kbdCoords.y };\r\n\r\n // The layer group's element always has the proper width setting, unlike kbdDiv itself.\r\n offsetCoords.x /= this.layerGroup.element.offsetWidth;\r\n offsetCoords.y /= this.kbdDiv.offsetHeight;\r\n\r\n return offsetCoords;\r\n }\r\n\r\n /**\r\n * Builds the fat-finger distribution used by predictive text as its source for likelihood\r\n * of alternate keystroke sequences.\r\n * @param input The input coordinate of the event that led to use of this function\r\n * @param keySpec The spec of the key directly triggered by the input event. May be for a subkey.\r\n * @returns\r\n */\r\n getTouchProbabilities(input: InputEventCoordinate, keySpec?: ActiveKey): KeyDistribution {\r\n // TODO: It'd be nice to optimize by keeping these off when unused, but the wiring\r\n // necessary would get in the way of modularization at the moment.\r\n // let keyman = com.keyman.singleton;\r\n // if (!keyman.core.languageProcessor.mayCorrect) {\r\n // return null;\r\n // }\r\n\r\n // Note: if subkeys are active, they will still be displayed at this time.\r\n // TODO: In such cases, we should build an ActiveLayout (of sorts) for subkey displays,\r\n // update their geometries to the actual display values, and use the results here.\r\n let touchKbdPos = this.getTouchCoordinatesOnKeyboard(input);\r\n let layerGroup = this.layerGroup.element; // Always has proper dimensions, unlike kbdDiv itself.\r\n let width = layerGroup.offsetWidth, height = this.kbdDiv.offsetHeight;\r\n // Prevent NaN breakages.\r\n if (!width || !height) {\r\n return null;\r\n }\r\n\r\n let kbdAspectRatio = layerGroup.offsetWidth / this.kbdDiv.offsetHeight;\r\n let baseKeyProbabilities = this.kbdLayout.getLayer(this.layerId).getTouchProbabilities(touchKbdPos, kbdAspectRatio);\r\n\r\n if (!keySpec || !this.subkeyGesture || !this.subkeyGesture.baseKey.key) {\r\n return baseKeyProbabilities;\r\n } else {\r\n // A temp-hack, as this was noted just before 14.0's release.\r\n // Since a more... comprehensive solution would be way too complex this late in the game,\r\n // this provides a half-decent stopgap measure.\r\n //\r\n // Will not correct to nearby subkeys; only includes the selected subkey and its base keys.\r\n // Still, better than ignoring them both for whatever base key is beneath the final cursor location.\r\n let baseMass = 1.0;\r\n\r\n let baseKeyMass = 1.0;\r\n let baseKeyID = this.subkeyGesture.baseKey.key.spec.coreID;\r\n\r\n let popupKeyMass = 0.0;\r\n let popupKeyID: string = null;\r\n\r\n popupKeyMass = 3.0;\r\n popupKeyID = keySpec.coreID;\r\n\r\n // If the base key appears in the subkey array and was selected, merge the probability masses.\r\n if (popupKeyID == baseKeyID) {\r\n baseKeyMass += popupKeyMass;\r\n popupKeyMass = 0;\r\n } else {\r\n // We namespace it so that lookup operations know to find it via its base key.\r\n popupKeyID = `${baseKeyID}::${popupKeyID}`;\r\n }\r\n\r\n // Compute the normalization factor\r\n let totalMass = baseMass + baseKeyMass + popupKeyMass;\r\n let scalar = 1.0 / totalMass;\r\n\r\n // Prevent duplicate entries in the final map & normalize the remaining entries!\r\n for (let i = 0; i < baseKeyProbabilities.length; i++) {\r\n let entry = baseKeyProbabilities[i];\r\n if (entry.keyId == baseKeyID) {\r\n baseKeyMass += entry.p * scalar;\r\n baseKeyProbabilities.splice(i, 1);\r\n i--;\r\n } else if (entry.keyId == popupKeyID) {\r\n popupKeyMass = + entry.p * scalar;\r\n baseKeyProbabilities.splice(i, 1);\r\n i--;\r\n } else {\r\n entry.p *= scalar;\r\n }\r\n }\r\n\r\n let finalArray: { keyId: string, p: number }[] = [];\r\n\r\n if (popupKeyMass > 0) {\r\n finalArray.push({ keyId: popupKeyID, p: popupKeyMass * scalar });\r\n }\r\n\r\n finalArray.push({ keyId: baseKeyID, p: baseKeyMass * scalar });\r\n\r\n finalArray = finalArray.concat(baseKeyProbabilities);\r\n return finalArray;\r\n }\r\n }\r\n\r\n //#region Input handling start\r\n\r\n /**\r\n * Determines a \"fuzzy boundary\" area around the OSK within which active mouse and\r\n * touch events will be maintained, even if their coordinates lie outside of the OSK's\r\n * true visual bounds.\r\n * @returns A `BoundingRect`, in `.pageX` / `.pageY` coordinates.\r\n */\r\n private getInteractiveBoundingRect(): BoundingRect {\r\n // Determine the important geometric values involved\r\n let oskX = getAbsoluteX(this.element);\r\n let oskY = getAbsoluteY(this.element);\r\n\r\n // Determine the out-of-bounds threshold at which touch-cancellation should automatically occur.\r\n // Assuming square key-squares, we'll use 1/3 the height of a row for bounds detection\r\n // for both dimensions.\r\n const rowCount = this.currentLayer.rows.length;\r\n const buffer = (0.333 * this.height / rowCount);\r\n\r\n // Determine the OSK's boundaries and the boundaries of the page / view.\r\n // These values are needed in .pageX / .pageY coordinates for the final calcs.\r\n let boundingRect: BoundingRect = {\r\n left: oskX - buffer,\r\n right: oskX + this.width + buffer,\r\n top: oskY - buffer,\r\n bottom: oskY + this.height + buffer\r\n };\r\n\r\n return boundingRect;\r\n }\r\n\r\n /**\r\n * Adjusts a potential \"interactive boundary\" definition by enforcing an\r\n * \"event cancellation zone\" near screen boundaries that are not directly adjacent\r\n * to the ongoing input event's initial coordinate.\r\n *\r\n * This facilitates modeling of conventional cancellation gestures where a user would\r\n * drag the mouse or touch point off the OSK, as mouse and touch event handlers receive\r\n * no input beyond screen boundaries.\r\n *\r\n * @param baseBounds The baseline interactive bounding area to be adjusted\r\n * @param startCoord The initial coordinate of a currently-ongoing input event\r\n * @returns\r\n */\r\n private applyScreenMarginBoundsThresholding(baseBounds: BoundingRect,\r\n startCoord: InputEventCoordinate): BoundingRect {\r\n // Determine the needed linear translation to screen coordinates.\r\n const xDelta = window.screenLeft - window.pageXOffset;\r\n const yDelta = window.screenTop - window.pageYOffset;\r\n\r\n let adjustedBounds: BoundingRect = { ...baseBounds };\r\n\r\n // Also translate the initial touch's screen coord, as it affects our bounding box logic.\r\n const initScreenCoord = new InputEventCoordinate(startCoord.x + xDelta, startCoord.y + yDelta);\r\n\r\n // Detection: is the OSK aligned with any screen boundaries?\r\n // If so, create a 'fuzzy' zone around the edges not near the initial touch point that allow\r\n // move-based cancellation.\r\n\r\n // If the initial input screen-coord is at least 5 pixels from the screen's left AND\r\n // the OSK's left boundary is within 2 pixels from the screen's left...\r\n if (initScreenCoord.x >= 5 && baseBounds.left + xDelta <= 2) {\r\n adjustedBounds.left = 2 - xDelta; // new `leftBound` is set to 2 pixels from the screen's left.\r\n }\r\n\r\n if (initScreenCoord.x <= screen.width - 5 && baseBounds.right + xDelta >= screen.width - 2) {\r\n adjustedBounds.right = (screen.width - 2) - xDelta; // new `rightBound` 2px from screen's right.\r\n }\r\n\r\n if (initScreenCoord.y >= 5 && baseBounds.top + yDelta <= 2) {\r\n adjustedBounds.top = 2 - yDelta;\r\n }\r\n\r\n if (initScreenCoord.y <= screen.height - 5 && baseBounds.bottom + yDelta >= screen.height - 2) {\r\n adjustedBounds.bottom = (screen.height - 2) - yDelta;\r\n }\r\n\r\n return adjustedBounds;\r\n }\r\n\r\n detectWithinInteractiveBounds(coord: InputEventCoordinate): boolean {\r\n // Shortcuts the method during unit testing, as we don't currently\r\n // provide coordinate values in its synthetic events.\r\n if (coord.x === null && coord.y === null) {\r\n return true;\r\n }\r\n\r\n const baseBoundingRect = this.getInteractiveBoundingRect();\r\n let adjustedBoundingRect = baseBoundingRect;\r\n if(this.initTouchCoord) {\r\n this.applyScreenMarginBoundsThresholding(baseBoundingRect, this.initTouchCoord);\r\n }\r\n\r\n // Now to check where the input coordinate lies in relation to the final bounding box!\r\n\r\n if (coord.x < adjustedBoundingRect.left || coord.x > adjustedBoundingRect.right) {\r\n return false;\r\n } else if (coord.y < adjustedBoundingRect.top || coord.y > adjustedBoundingRect.bottom) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n }\r\n\r\n /**\r\n * The main OSK touch start event handler\r\n *\r\n * @param {Event} e touch start event object\r\n *\r\n */\r\n touch(input: InputEventCoordinate) {\r\n // Identify the key touched\r\n var t = input.target, key = this.keyTarget(t);\r\n\r\n // Save the touch point, which is used for quick-display of popup keys (defined in highlightSubKeys)\r\n this.initTouchCoord = input;\r\n\r\n // Set the key for the new touch point to be current target, if defined\r\n this.currentTarget = key;\r\n\r\n // Clear repeated backspace if active, preventing 'sticky' behavior.\r\n this.cancelDelete();\r\n\r\n // Prevent multi-touch if popup displayed\r\n if (this.subkeyGesture && this.subkeyGesture.isVisible()) {\r\n return;\r\n }\r\n\r\n // Keep track of number of active (unreleased) touch points\r\n this.touchCount = input.activeInputCount;\r\n\r\n // Get nearest key if touching a hidden key or the end of a key row\r\n if ((key && ((key.className.indexOf('key-hidden') >= 0) || (key.className.indexOf('key-blank') >= 0)))\r\n || t.className.indexOf('kmw-key-row') >= 0) {\r\n\r\n // Perform \"fudged\" selection ops if and only if we're not sure about the precision of the\r\n // input source. Mouse-based selection IS precise, so no need for \"fudging\" there.\r\n if (!input.isFromMouse) {\r\n key = this.findNearestKey(input, t);\r\n }\r\n }\r\n // Do not do anything if no key identified!\r\n if (key == null) {\r\n return;\r\n }\r\n\r\n // Get key name (K_...) from element ID\r\n let keyName = key['keyId'];\r\n\r\n // Highlight the touched key\r\n this.highlightKey(key, true);\r\n\r\n // Special function keys need immediate action\r\n if (keyName == 'K_LOPT' || keyName == 'K_ROPT') {\r\n window.setTimeout(function (this: VisualKeyboard) {\r\n this.modelKeyClick(key);\r\n // Because we immediately process the key, we need to re-highlight it after the click.\r\n this.highlightKey(key, true);\r\n // Highlighting'll be cleared automatically later.\r\n }.bind(this), 0);\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n\r\n // Also backspace, to allow delete to repeat while key held\r\n } else if (keyName == 'K_BKSP') {\r\n // While we could inline the execution of the delete key here, we lose the ability to\r\n // record the backspace key if we do so.\r\n this.modelKeyClick(key, input);\r\n this.deleteKey = key;\r\n this.deleting = window.setTimeout(this.repeatDelete, 500);\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n } else {\r\n if (this.keyPending) {\r\n this.highlightKey(this.keyPending, false);\r\n\r\n if (this.subkeyGesture && this.subkeyGesture instanceof InternalSubkeyPopup) {\r\n let subkeyPopup = this.subkeyGesture as InternalSubkeyPopup;\r\n subkeyPopup.updateTouch(input);\r\n subkeyPopup.finalize(input);\r\n } else {\r\n this.modelKeyClick(this.keyPending, this.touchPending);\r\n }\r\n // Decrement the number of unreleased touch points to prevent\r\n // sending the keystroke again when the key is actually released\r\n this.touchCount--;\r\n } else {\r\n this.initGestures(key, input);\r\n }\r\n this.keyPending = key;\r\n this.touchPending = input;\r\n }\r\n }\r\n\r\n /**\r\n * OSK touch release event handler\r\n *\r\n * @param {Event} e touch release event object\r\n *\r\n **/\r\n release(input: InputEventCoordinate): void {\r\n // Prevent incorrect multi-touch behaviour if native or device popup visible\r\n var t = this.currentTarget;\r\n\r\n // Clear repeated backspace if active, preventing 'sticky' behavior.\r\n this.cancelDelete();\r\n\r\n // Multi-Tap\r\n if (this.pendingMultiTap && this.pendingMultiTap.realized) {\r\n // Ignore pending key if we've just handled a multitap\r\n this.pendingMultiTap = null;\r\n\r\n this.highlightKey(this.keyPending, false);\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n\r\n return;\r\n }\r\n\r\n if (this.pendingMultiTap && this.pendingMultiTap.cancelled) {\r\n this.pendingMultiTap = null;\r\n }\r\n\r\n // Longpress\r\n if ((this.subkeyGesture && this.subkeyGesture.isVisible())) {\r\n // Ignore release if a multiple touch\r\n if (input.activeInputCount > 0) {\r\n return;\r\n }\r\n\r\n if (this.subkeyGesture instanceof InternalSubkeyPopup) {\r\n let subkeyPopup = this.subkeyGesture as InternalSubkeyPopup;\r\n subkeyPopup.finalize(input);\r\n }\r\n this.highlightKey(this.keyPending, false);\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n\r\n return;\r\n }\r\n\r\n // Handle menu key release event\r\n if (t && t.id) {\r\n this.optionKey(t, t.id, false);\r\n }\r\n\r\n // Test if moved off screen (effective release point must be corrected for touch point horizontal speed)\r\n // This is not completely effective and needs some tweaking, especially on Android\r\n if (!this.detectWithinInteractiveBounds(input)) {\r\n this.moveCancel(input);\r\n this.touchCount--;\r\n return;\r\n }\r\n\r\n // Save then decrement current touch count\r\n var tc = this.touchCount;\r\n if (this.touchCount > 0) {\r\n this.touchCount--;\r\n }\r\n\r\n // Process and clear highlighting of pending target\r\n if (this.keyPending) {\r\n this.highlightKey(this.keyPending, false);\r\n // Output character unless moved off key\r\n if (this.keyPending.className.indexOf('hidden') < 0 && tc > 0) {\r\n this.modelKeyClick(this.keyPending, input);\r\n }\r\n this.clearPopup();\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n // Always clear highlighting of current target on release (multi-touch)\r\n } else {\r\n var tt = input;\r\n t = this.keyTarget(tt.target);\r\n if (!t) {\r\n // Operates relative to the viewport, not based on the actual coordinate on the page.\r\n var t1 = document.elementFromPoint(input.x - window.pageXOffset, input.y - window.pageYOffset);\r\n t = this.findNearestKey(input, t1);\r\n }\r\n\r\n this.highlightKey(t, false);\r\n }\r\n }\r\n\r\n moveCancel(input: InputEventCoordinate): void {\r\n // Do not attempt to support reselection of target key for overlapped keystrokes.\r\n // Perform _after_ ensuring possible sticky keys have been cancelled.\r\n if (input.activeInputCount > 1) {\r\n return;\r\n }\r\n\r\n // Update all gesture tracking. The function returns true if further input processing\r\n // should be blocked. (Keeps the subkey array operating when the input coordinate has\r\n // moved outside the OSK's boundaries.)\r\n if (this.updateGestures(null, this.keyPending, input)) {\r\n return;\r\n }\r\n\r\n this.cancelDelete();\r\n\r\n this.highlightKey(this.keyPending, false);\r\n this.showKeyTip(null, false);\r\n this.clearPopup();\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n }\r\n\r\n /**\r\n * OSK touch move event handler\r\n *\r\n * @param {Event} e touch move event object\r\n *\r\n **/\r\n moveOver(input: InputEventCoordinate): void {\r\n // Shouldn't be possible, but just in case.\r\n if (this.touchCount == 0) {\r\n this.cancelDelete();\r\n return;\r\n }\r\n\r\n // Get touch position\r\n const x = input.x - window.pageXOffset;\r\n const y = input.y - window.pageYOffset;\r\n\r\n // Move target key and highlighting\r\n this.touchPending = input;\r\n // Operates on viewport-based coordinates, not page-based.\r\n var t1 = document.elementFromPoint(x, y);\r\n const key0 = this.keyPending;\r\n let key1 = this.keyTarget(t1); // Not only gets base keys, but also gets popup keys!\r\n\r\n // Find the nearest key to the touch point if not on a visible key\r\n if ((key1 && key1.className.indexOf('key-hidden') >= 0) ||\r\n (t1 && (!key1) && t1.className.indexOf('key-row') >= 0)) {\r\n key1 = this.findNearestKey(input, t1);\r\n }\r\n\r\n // Cancels BKSP if it's not the key. (Note... could also cancel BKSP if the ongoing\r\n // input is cancelled, regardless of key, just to be safe.)\r\n\r\n // Stop repeat if no longer on BKSP key\r\n if (key1 && (typeof key1.id == 'string') && (key1.id.indexOf('-K_BKSP') < 0)) {\r\n this.cancelDelete();\r\n }\r\n\r\n // Cancels if it's a multitouch attempt.\r\n\r\n // Do not attempt to support reselection of target key for overlapped keystrokes.\r\n // Perform _after_ ensuring possible sticky keys have been cancelled.\r\n if (input.activeInputCount > 1) {\r\n return;\r\n }\r\n\r\n // Gesture-updates should probably be a separate call from other touch-move aspects.\r\n\r\n // Update all gesture tracking. The function returns true if further input processing\r\n // should be blocked.\r\n if (this.updateGestures(key1, key0, input)) {\r\n return;\r\n }\r\n\r\n // Identify current touch position (to manage off-key release)\r\n this.currentTarget = key1;\r\n\r\n // Only NOW do we denote the newly-selected key as the currently-focused key.\r\n\r\n // Replace the target key, if any, by the new target key\r\n // Do not replace a null target, as that indicates the key has already been released\r\n if (key1 && this.keyPending) {\r\n this.highlightKey(key0, false);\r\n this.keyPending = key1;\r\n this.touchPending = input;\r\n }\r\n\r\n if (key0 && key1 && (key1 != key0) && (key1.id != '')) {\r\n // While there may not be an active subkey menu, we should probably update which base key\r\n // is being highlighted by the current touch & start a pending longpress for it.\r\n this.clearPopup();\r\n this.initGestures(key1, input);\r\n }\r\n\r\n if (this.keyPending) {\r\n if (key0 != key1 || key1.className.indexOf(OSKKey.HIGHLIGHT_CLASS) < 0) {\r\n this.highlightKey(key1, true);\r\n }\r\n }\r\n }\r\n\r\n //#endregion\r\n\r\n /**\r\n * Get the current key target from the touch point element within the key\r\n *\r\n * @param {Object} t element at touch point\r\n * @return {Object} the key element (or null)\r\n **/\r\n keyTarget(target: HTMLElement | EventTarget): KeyElement {\r\n let t = target;\r\n\r\n try {\r\n if (t) {\r\n if (t.classList.contains('kmw-key')) {\r\n return getKeyFrom(t);\r\n }\r\n if (t.parentNode && (t.parentNode as HTMLElement).classList.contains('kmw-key')) {\r\n return getKeyFrom(t.parentNode);\r\n }\r\n if (t.firstChild && (t.firstChild as HTMLElement).classList.contains('kmw-key')) {\r\n return getKeyFrom(t.firstChild);\r\n }\r\n }\r\n } catch (ex) { }\r\n return null;\r\n }\r\n\r\n /**\r\n * Identify the key nearest to the touch point if at the end of a key row,\r\n * but return null more than about 0.6 key width from the nearest key.\r\n *\r\n * @param {Event} e touch event\r\n * @param {Object} t HTML object at touch point\r\n * @return {Object} nearest key to touch point\r\n *\r\n **/\r\n findNearestKey(input: InputEventCoordinate, t: HTMLElement): KeyElement {\r\n if (!input) {\r\n return null;\r\n }\r\n\r\n // Get touch point on screen\r\n var x = input.x;\r\n\r\n // Get key-row beneath touch point\r\n while (t && t.className !== undefined && t.className.indexOf('key-row') < 0) {\r\n t = t.parentNode;\r\n }\r\n if (!t) {\r\n return null;\r\n }\r\n\r\n // Find minimum distance from any key\r\n var k, k0 = 0, dx, dxMax = 24, dxMin = 100000, x1, x2;\r\n for (k = 0; k < t.childNodes.length; k++) {\r\n let keySquare = t.childNodes[k] as HTMLElement; // gets the .kmw-key-square containing a key\r\n // Find the actual key element.\r\n let childNode = keySquare.firstChild ? keySquare.firstChild as HTMLElement : keySquare;\r\n\r\n if (childNode.className !== undefined\r\n && (childNode.className.indexOf('key-hidden') >= 0\r\n || childNode.className.indexOf('key-blank') >= 0)) {\r\n continue;\r\n }\r\n x1 = keySquare.offsetLeft;\r\n x2 = x1 + keySquare.offsetWidth;\r\n if (x >= x1 && x <= x2) {\r\n // Within the key square\r\n return childNode;\r\n }\r\n dx = x1 - x;\r\n if (dx >= 0 && dx < dxMin) {\r\n // To right of key\r\n k0 = k; dxMin = dx;\r\n }\r\n dx = x - x2;\r\n if (dx >= 0 && dx < dxMin) {\r\n // To left of key\r\n k0 = k; dxMin = dx;\r\n }\r\n }\r\n\r\n if (dxMin < 100000) {\r\n t = t.childNodes[k0];\r\n x1 = t.offsetLeft;\r\n x2 = x1 + t.offsetWidth;\r\n\r\n // Limit extended touch area to the larger of 0.6 of key width and 24 px\r\n if (t.offsetWidth > 40) {\r\n dxMax = 0.6 * t.offsetWidth;\r\n }\r\n\r\n if (((x1 - x) >= 0 && (x1 - x) < dxMax) || ((x - x2) >= 0 && (x - x2) < dxMax)) {\r\n return t.firstChild;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Repeat backspace as long as the backspace key is held down\r\n **/\r\n repeatDelete: () => void = function (this: VisualKeyboard) {\r\n if (this.deleting) {\r\n this.modelKeyClick(this.deleteKey);\r\n this.deleting = window.setTimeout(this.repeatDelete, 100);\r\n }\r\n }.bind(this);\r\n\r\n /**\r\n * Cancels any active repeatDelete() timeouts, ensuring that\r\n * repeating backspace operations are properly terminated.\r\n */\r\n cancelDelete() {\r\n // Clears the delete-repeating timeout.\r\n if (this.deleting) {\r\n window.clearTimeout(this.deleting);\r\n }\r\n this.deleting = 0;\r\n }\r\n //#endregion\r\n\r\n modelKeyClick(e: KeyElement, input?: InputEventCoordinate) {\r\n let keyEvent = this.initKeyEvent(e, input);\r\n this.raiseKeyEvent(keyEvent, e);\r\n }\r\n\r\n initKeyEvent(e: KeyElement, input?: InputEventCoordinate) {\r\n // Turn off key highlighting (or preview)\r\n this.highlightKey(e, false);\r\n\r\n // Future note: we need to refactor osk.OSKKeySpec to instead be a 'tag field' for\r\n // keyboards.ActiveKey. (Prob with generics, allowing the Web-only parts to\r\n // be fully specified within the tag.)\r\n //\r\n // Would avoid the type shenanigans needed here because of our current type-abuse setup\r\n // for key spec tracking.\r\n let keySpec = (e['key'] ? e['key'].spec : null) as unknown as ActiveKey;\r\n if (!keySpec) {\r\n console.error(\"OSK key with ID '\" + e.id + \"', keyID '\" + e.keyId + \"' missing needed specification\");\r\n return null;\r\n }\r\n\r\n // Return the event object.\r\n return this.keyEventFromSpec(keySpec, input);\r\n }\r\n\r\n keyEventFromSpec(keySpec: ActiveKey, input?: InputEventCoordinate) {\r\n //let core = com.keyman.singleton.core; // only singleton-based ref currently needed here.\r\n\r\n // Start: mirrors _GetKeyEventProperties\r\n\r\n // First check the virtual key, and process shift, control, alt or function keys\r\n //let Lkc = keySpec.constructKeyEvent(core.keyboardProcessor, this.device);\r\n let Lkc = this.layoutKeyboard.constructKeyEvent(keySpec, this.device, this.stateKeys);\r\n\r\n /* In case of \"fun\" edge cases caused by JS's single-threadedness & event processing queue.\r\n *\r\n * Should a touch occur on an OSK key during active JS execution that results in a change\r\n * of the active keyboard, it's possible for an OSK key to be evaluated against an\r\n * unexpected, non-matching keyboard - one that could even be `null`!\r\n *\r\n * So, we mark the keyboard backing the OSK as the 'correct' keyboard for this key.\r\n */\r\n Lkc.srcKeyboard = this.layoutKeyboard;\r\n\r\n // End - mirrors _GetKeyEventProperties\r\n\r\n if (input) {\r\n Lkc.source = input;\r\n Lkc.keyDistribution = this.getTouchProbabilities(input, keySpec);\r\n }\r\n\r\n // Return the event object.\r\n return Lkc;\r\n }\r\n\r\n // cancel = function(e) {} //cancel event is never generated by iOS\r\n\r\n /**\r\n * Function _UpdateVKShiftStyle\r\n * Scope Private\r\n * @param {string=} layerId\r\n * Description Updates the OSK's visual style for any toggled state keys\r\n */\r\n _UpdateVKShiftStyle(layerId?: string) {\r\n var i;\r\n //let core = com.keyman.singleton.core;\r\n\r\n if (!layerId) {\r\n layerId = this.layerId;\r\n }\r\n\r\n const layer = this.layerGroup.layers[layerId];\r\n if (!layer) {\r\n return;\r\n }\r\n\r\n // So... through KMW 14, we actually never tracked the capsKey, numKey, and scrollKey\r\n // properly for keyboard-defined layouts - only _default_, desktop-style layouts.\r\n //\r\n // We _could_ remedy this, but then... touch keyboards like khmer_angkor actually\r\n // repurpose certain state keys, and in an inconsistent manner at that.\r\n // Considering the potential complexity of touch layouts, with multiple possible\r\n // layer-shift keys, it's likely best to just leave things as they are for now.\r\n if (!this.layoutKeyboard?.usesDesktopLayoutOnDevice(this.device)) {\r\n return;\r\n }\r\n\r\n // Set the on/off state of any visible state keys.\r\n const states = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'];\r\n const keys = [layer.capsKey, layer.numKey, layer.scrollKey];\r\n\r\n for (i = 0; i < keys.length; i++) {\r\n // Skip any keys not in the OSK!\r\n if (keys[i] == null) {\r\n continue;\r\n }\r\n\r\n keys[i].setToggleState(this.stateKeys[states[i]]);\r\n }\r\n }\r\n\r\n updateStateKeys(stateKeys: StateKeyMap) {\r\n for(let key in this.stateKeys) {\r\n this.stateKeys[key] = stateKeys[key];\r\n }\r\n\r\n this._UpdateVKShiftStyle();\r\n }\r\n\r\n clearPopup() {\r\n // Remove the displayed subkey array, if any, and cancel popup request\r\n if (this.subkeyGesture) {\r\n this.subkeyGesture.clear();\r\n this.subkeyGesture = null;\r\n }\r\n\r\n if (this.pendingSubkey) {\r\n this.pendingSubkey.cancel();\r\n this.pendingSubkey = null;\r\n }\r\n }\r\n\r\n //#endregion\r\n\r\n /**\r\n * Indicate the current language and keyboard on the space bar\r\n **/\r\n showLanguage() {\r\n let activeStub = this.layoutKeyboardProperties;\r\n let displayName: string = activeStub?.displayName ?? '(System keyboard)';\r\n\r\n try {\r\n var t = this.spaceBar.key.label;\r\n let tParent = t.parentNode;\r\n if (typeof (tParent.className) == 'undefined' || tParent.className == '') {\r\n tParent.className = 'kmw-spacebar';\r\n } else if (tParent.className.indexOf('kmw-spacebar') == -1) {\r\n tParent.className += ' kmw-spacebar';\r\n }\r\n\r\n if (t.className != 'kmw-spacebar-caption') {\r\n t.className = 'kmw-spacebar-caption';\r\n }\r\n\r\n // It sounds redundant, but this dramatically cuts down on browser DOM processing;\r\n // but sometimes innerText is reported empty when it actually isn't, so set it\r\n // anyway in that case (Safari, iOS 14.4)\r\n if (t.innerText != displayName || displayName == '') {\r\n t.innerText = displayName;\r\n }\r\n\r\n this.spaceBar.key.refreshLayout(this);\r\n }\r\n catch (ex) { }\r\n }\r\n\r\n /**\r\n * Add or remove a class from a keyboard key (when touched or clicked)\r\n * or add a key preview for phone devices\r\n *\r\n * @param {Object} key key affected\r\n * @param {boolean} on add or remove highlighting\r\n **/\r\n highlightKey(key: KeyElement, on: boolean) {\r\n // Do not change element class unless a key\r\n if (!key || !key.key || (key.className == '') || (key.className.indexOf('kmw-key-row') >= 0)) return;\r\n\r\n // For phones, use key preview rather than highlighting the key,\r\n var usePreview = (this.keytip != null) && key.key.allowsKeyTip();\r\n\r\n if (usePreview) {\r\n this.showKeyTip(key, on);\r\n } else {\r\n // No key tip should be shown. In some cases (e.g. multitap), we\r\n // may still have a tip visible so let's always hide in that case\r\n this.showKeyTip(null, false);\r\n key.key.highlight(on);\r\n }\r\n }\r\n\r\n /**\r\n * Use of `getComputedStyle` is ideal, but in many of our use cases its preconditions are not met.\r\n * This function allows us to calculate the font size in those situations.\r\n */\r\n getKeyEmFontSize(): number {\r\n if (!this.fontSize) {\r\n return 0;\r\n }\r\n\r\n if (this.device.formFactor == 'desktop') {\r\n let keySquareScale = 0.8; // Set in kmwosk.css, is relative.\r\n return this.fontSize.scaledBy(keySquareScale).val;\r\n } else {\r\n let emSizeStr = getComputedStyle(document.body).fontSize;\r\n let emSize = getFontSizeStyle(emSizeStr).val;\r\n\r\n var emScale = 1;\r\n if (!this.isStatic) {\r\n // Double-check against the font scaling applied to the _Box element.\r\n if (this.fontSize.absolute) {\r\n return this.fontSize.val;\r\n } else {\r\n emScale = this.fontSize.val;\r\n }\r\n }\r\n return emSize * emScale;\r\n }\r\n }\r\n\r\n updateState() {\r\n // May happen for desktop-oriented keyboards that neglect to specify a touch layout.\r\n // See `test_chirality.js` from the unit-test keyboard suite, which tests keystrokes\r\n // using modifiers that lack corresponding visual-layout representation.\r\n if (!this.currentLayer) {\r\n return;\r\n }\r\n\r\n var n, b = this.kbdDiv.childNodes[0].childNodes;\r\n this.nextLayer = this.layerId;\r\n\r\n if (this.currentLayer.nextlayer) {\r\n this.nextLayer = this.currentLayer.nextlayer;\r\n }\r\n\r\n for (n = 0; n < b.length; n++) {\r\n let layerElement = b[n];\r\n if (layerElement['layer'] == this.layerId) {\r\n layerElement.style.display = 'block';\r\n //b[n].style.visibility='visible';\r\n\r\n // Most functions that call this one often indicate a change in modifier\r\n // or state key state. Keep it updated!\r\n this._UpdateVKShiftStyle();\r\n } else {\r\n layerElement.style.display = 'none';\r\n //layerElement.style.visibility='hidden';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Used to refresh the VisualKeyboard's geometric layout and key sizes\r\n * when needed.\r\n */\r\n refreshLayout() {\r\n //let keyman = com.keyman.singleton;\r\n let device = this.device;\r\n\r\n var fs = 1.0;\r\n // TODO: Logically, this should be needed for Android, too - may need to be changed for the next version!\r\n if (device.OS == DeviceSpec.OperatingSystem.iOS && !this.isEmbedded) {\r\n fs = fs / getViewportScale();\r\n }\r\n\r\n let paddedHeight: number;\r\n if (this.height) {\r\n paddedHeight = this.computedAdjustedOskHeight(this.height);\r\n }\r\n\r\n let b = this.layerGroup.element as HTMLElement;\r\n let gs = this.kbdDiv.style;\r\n let bs = b.style;\r\n if (this.usesFixedHeightScaling && this.height) {\r\n // Sets the layer group to the correct height.\r\n gs.height = gs.maxHeight = this.height + 'px';\r\n }\r\n\r\n // The font-scaling applied on the layer group.\r\n gs.fontSize = this.fontSize.styleString;\r\n bs.fontSize = ParsedLengthStyle.forScalar(fs).styleString;\r\n\r\n // NEW CODE ------\r\n\r\n // Step 1: have the necessary conditions been met?\r\n const fixedSize = this.width && this.height;\r\n const computedStyle = getComputedStyle(this.kbdDiv);\r\n const isInDOM = computedStyle.height != '' && computedStyle.height != 'auto';\r\n\r\n // Step 2: determine basic layout geometry, refresh things that might update.\r\n this.showLanguage(); // In case the spacebar-text mode setting has changed.\r\n\r\n if (fixedSize) {\r\n this._computedWidth = this.width;\r\n this._computedHeight = this.height;\r\n } else if (isInDOM) {\r\n this._computedWidth = parseInt(computedStyle.width, 10);\r\n if (!this._computedWidth) {\r\n // For touch keyboards, the width _was_ specified on the layer group,\r\n // not the root element (`kbdDiv`).\r\n const groupStyle = getComputedStyle(this.kbdDiv.firstElementChild);\r\n this._computedWidth = parseInt(groupStyle.width, 10);\r\n }\r\n this._computedHeight = parseInt(computedStyle.height, 10);\r\n } else {\r\n // Cannot perform layout operations!\r\n return;\r\n }\r\n\r\n // Step 3: perform layout operations. (Handled by 'old code' section below.)\r\n\r\n // END NEW CODE -----------\r\n\r\n // Needs the refreshed layout info to work correctly.\r\n if(this.currentLayer) {\r\n this.currentLayer.refreshLayout(this, this._computedHeight - this.getVerticalLayerGroupPadding());\r\n }\r\n }\r\n\r\n private getVerticalLayerGroupPadding(): number {\r\n // For touch-based OSK layouts, kmwosk.css may include top & bottom padding on the layer-group element.\r\n const computedGroupStyle = getComputedStyle(this.layerGroup.element);\r\n\r\n // parseInt('') => NaN, which is falsy; we want to fallback to zero.\r\n let pt = parseInt(computedGroupStyle.paddingTop, 10) || 0;\r\n let pb = parseInt(computedGroupStyle.paddingBottom, 10) || 0;\r\n return pt + pb;\r\n }\r\n\r\n /*private*/ computedAdjustedOskHeight(allottedHeight: number): number {\r\n if (!this.layerGroup) {\r\n return allottedHeight;\r\n }\r\n\r\n const layers = this.layerGroup.layers;\r\n let oskHeight = 0;\r\n\r\n // In case the keyboard's layers have differing row counts, we check them all for the maximum needed oskHeight.\r\n for (const layerID in layers) {\r\n const layer = layers[layerID];\r\n let nRows = layer.rows.length;\r\n let rowHeight = Math.floor(allottedHeight / (nRows == 0 ? 1 : nRows));\r\n let layerHeight = nRows * rowHeight;\r\n\r\n if (layerHeight > oskHeight) {\r\n oskHeight = layerHeight;\r\n }\r\n }\r\n\r\n // This isn't set anywhere else; it's a legacy part of the original methods.\r\n const oskPad = 0;\r\n let oskPaddedHeight = oskHeight + oskPad;\r\n\r\n return oskPaddedHeight;\r\n }\r\n\r\n /**\r\n * Append a style sheet for the current keyboard if needed for specifying an embedded font\r\n * or to re-apply the default element font\r\n *\r\n **/\r\n appendStyleSheet() {\r\n //let util = com.keyman.singleton.util;\r\n\r\n var activeKeyboard = this.layoutKeyboard;\r\n var activeStub = this.layoutKeyboardProperties;\r\n\r\n // Do not do anything if a null stub\r\n if (activeStub == null) {\r\n return;\r\n }\r\n\r\n // First remove any existing keyboard style sheet\r\n if (this.styleSheet && this.styleSheet.parentNode) {\r\n this.styleSheet.parentNode.removeChild(this.styleSheet);\r\n }\r\n\r\n var kfd = activeStub.textFont, ofd = activeStub.oskFont;\r\n\r\n // Add and define style sheets for embedded fonts if necessary (each font-face style will only be added once)\r\n this.styleSheetManager.addStyleSheetForFont(kfd, this.fontRootPath, this.device.OS);\r\n this.styleSheetManager.addStyleSheetForFont(ofd, this.fontRootPath, this.device.OS);\r\n\r\n // Build the style string to USE the fonts and append (or replace) the font style sheet\r\n // Note: Some browsers do not download the font-face font until it is applied,\r\n // so must apply style before testing for font availability\r\n // Extended to allow keyboard-specific custom styles for Build 360\r\n var customStyle = this.addFontStyle(kfd, ofd);\r\n if (activeKeyboard != null && typeof (activeKeyboard.oskStyling) == 'string') // KMEW-129\r\n customStyle = customStyle + activeKeyboard.oskStyling;\r\n\r\n this.styleSheet = createStyleSheet(customStyle); //Build 360\r\n this.styleSheet.addEventListener('load', () => {\r\n // Once any related fonts are loaded, we can re-adjust key-cap scaling.\r\n this.refreshLayout();\r\n })\r\n this.styleSheetManager.linkStylesheet(this.styleSheet);\r\n }\r\n\r\n /**\r\n * Add or replace the style sheet used to set the font for input elements and OSK\r\n *\r\n * @param {Object} kfd KFont font descriptor\r\n * @param {Object} ofd OSK font descriptor (if any)\r\n * @return {string}\r\n *\r\n **/\r\n addFontStyle(kfd: InternalKeyboardFont, ofd: InternalKeyboardFont): string {\r\n let s: string = '';\r\n\r\n let family = (fd: InternalKeyboardFont) => fd.family.replace(/\\u0022/g, '').replace(/,/g, '\",\"');\r\n\r\n // Set font family for OSK text, suggestion text\r\n if (kfd || ofd) {\r\n s = `\r\n.kmw-key-text {\r\n font-family: \"${family(ofd || kfd)}\";\r\n}\r\n\r\n.kmw-suggestion-text {\r\n font-family: \"${family(kfd || ofd)}\";\r\n}\r\n`;\r\n }\r\n\r\n // Return the style string\r\n return s;\r\n }\r\n\r\n /**\r\n * Create copy of the OSK that can be used for embedding in documentation or help\r\n * The currently active keyboard will be returned if PInternalName is null\r\n *\r\n * @param {Object} PKbd the keyboard object to be displayed\r\n * @param {string=} argFormFactor layout form factor, defaulting to 'desktop'\r\n * @param {(string|number)=} argLayerId name or index of layer to show, defaulting to 'default'\r\n * @param {number} height Target height for the rendered keyboard\r\n * (currently required for legacy reasons)\r\n * @return {Object} DIV object with filled keyboard layer content\r\n */\r\n static buildDocumentationKeyboard(PKbd: Keyboard, kbdProperties: KeyboardProperties, fontRootPath: string, argFormFactor: DeviceSpec.FormFactor, argLayerId, height: number): HTMLElement { // I777\r\n if (!PKbd) {\r\n return null;\r\n }\r\n\r\n var formFactor = (typeof (argFormFactor) == 'undefined' ? 'desktop' : argFormFactor) as DeviceSpec.FormFactor,\r\n layerId = (typeof (argLayerId) == 'undefined' ? 'default' : argLayerId),\r\n device: {\r\n formFactor?: DeviceSpec.FormFactor,\r\n OS?: DeviceSpec.OperatingSystem,\r\n touchable?: boolean\r\n } = {};\r\n\r\n // Device emulation for target documentation.\r\n device.formFactor = formFactor;\r\n if (formFactor != 'desktop') {\r\n device.OS = DeviceSpec.OperatingSystem.iOS;\r\n device.touchable = true;\r\n } else {\r\n device.OS = DeviceSpec.OperatingSystem.Windows;\r\n device.touchable = false;\r\n }\r\n\r\n let layout = PKbd.layout(formFactor);\r\n\r\n const deviceSpec = new DeviceSpec('other', device.formFactor, device.OS, device.touchable);\r\n let kbdObj = new VisualKeyboard({\r\n keyboard: PKbd,\r\n keyboardMetadata: kbdProperties,\r\n hostDevice: deviceSpec,\r\n isStatic: true,\r\n topContainer: null,\r\n pathConfig: {\r\n fonts: fontRootPath,\r\n resources: '' // ignored\r\n },\r\n styleSheetManager: null\r\n }); //\r\n\r\n kbdObj.layerGroup.element.className = kbdObj.kbdDiv.className; // may contain multiple classes\r\n kbdObj.layerGroup.element.classList.add(device.formFactor + '-static');\r\n\r\n let kbd = kbdObj.kbdDiv.childNodes[0] as HTMLDivElement; // Gets the layer group.\r\n\r\n // Models CSS classes hosted on the OSKView in normal operation. We can't do this on the main\r\n // layer-group element because of the CSS rule structure for keyboard styling.\r\n //\r\n // For example, `.ios .kmw-keyboard-sil_cameroon_azerty` requires the element with the keyboard\r\n // ID to be in a child of an element with the .ios class.\r\n let classWrapper = document.createElement('div');\r\n classWrapper.classList.add(device.OS.toLowerCase(), device.formFactor);\r\n\r\n // Select the layer to display, and adjust sizes\r\n if (layout != null) {\r\n kbdObj.layerId = layerId;\r\n\r\n // This still feels fairly hacky... but something IS needed to constrain the height.\r\n // There are plans to address related concerns through some of the later aspects of\r\n // the Web OSK-Core design.\r\n kbdObj.setSize(800, height); // Probably need something for width, too, rather than\r\n kbdObj.fontSize = defaultFontSize(deviceSpec, height, false);\r\n\r\n // assuming 100%.\r\n kbdObj.refreshLayout(); // Necessary for the row heights to be properly set!\r\n // Relocates the font size definition from the main VisualKeyboard wrapper, since we don't return the whole thing.\r\n kbd.style.fontSize = kbdObj.kbdDiv.style.fontSize;\r\n kbd.style.height = kbdObj.kbdDiv.style.height;\r\n kbd.style.maxHeight = kbdObj.kbdDiv.style.maxHeight;\r\n } else {\r\n kbd.innerHTML = \"

No \" + formFactor + \" layout is defined for \" + PKbd.name + \".

\";\r\n }\r\n // Add a faint border\r\n kbd.style.border = '1px solid #ccc';\r\n\r\n // Once the element is inserted into the DOM, refresh the layout so that proper text scaling may apply.\r\n const detectAndHandleInsertion = () => {\r\n if(document.contains(kbd)) {\r\n // Yay, insertion!\r\n\r\n try {\r\n // Are there font-size attributes we may safely adjust? If so, do that!\r\n if(getComputedStyle(kbd) && kbd.style.fontSize) {\r\n kbdObj.fontSize = new ParsedLengthStyle(kbd.style.fontSize);\r\n }\r\n\r\n // Make sure that the stylesheet is attached, now that the keyboard-doc's been inserted.\r\n // The stylesheet is currently built + constructed in the same code that attaches it to\r\n // the page.\r\n kbdObj.appendStyleSheet();\r\n\r\n // Grab a reference to the stylesheet.\r\n const stylesheet = kbdObj.styleSheet;\r\n const stylesheetParentElement = stylesheet.parentElement;\r\n\r\n // Don't reset top-level stuff; just the visible layer.\r\n // kbdObj.currentLayer.refreshLayout(kbdObj, kbdObj.height);\r\n\r\n // We refresh the full layout so that font-size is properly detected & stored\r\n // on the documentation keyboard.\r\n kbdObj.refreshLayout();\r\n kbd.style.fontSize = kbdObj.kbdDiv.style.fontSize;\r\n\r\n // We no longer need a reference to the constructing VisualKeyboard, so we should let\r\n // it clean up its stylesheet links. This detaches the stylesheet, though.\r\n kbdObj.shutdown();\r\n\r\n // Now that shutdown is done, re-attach the stylesheet - but to the layer group.\r\n kbd.appendChild(stylesheet);\r\n } finally {\r\n insertionObserver.disconnect();\r\n }\r\n }\r\n }\r\n\r\n const insertionObserver = new MutationObserver(detectAndHandleInsertion);\r\n insertionObserver.observe(document.body, {\r\n childList: true,\r\n subtree: true\r\n });\r\n\r\n classWrapper.append(kbd);\r\n return classWrapper;\r\n }\r\n\r\n onHide() {\r\n // Remove highlighting from hide keyboard key, if applied\r\n if (this.hkKey) {\r\n this.highlightKey(this.hkKey, false);\r\n }\r\n }\r\n\r\n /**\r\n * Starts an implementation-specific longpress gesture. Separately implemented for\r\n * in-browser and embedded modes.\r\n * @param key The base key of the longpress.\r\n * @returns\r\n */\r\n startLongpress(key: KeyElement): PendingGesture {\r\n // First-level object/Promise: will produce a subkey popup when the longpress gesture completes.\r\n // 'Returns' a second-level object/Promise: resolves when a subkey is selected or is cancelled.\r\n let pendingLongpress = new InternalPendingLongpress(this, key);\r\n pendingLongpress.promise.then((subkeyPopup) => {\r\n // In-browser-specific handling.\r\n if (subkeyPopup) {\r\n // Append the touch-hold (subkey) array to the OSK\r\n this.topContainer.appendChild(subkeyPopup.element);\r\n this.topContainer.appendChild(subkeyPopup.shim);\r\n\r\n // Must be placed after its `.element` has been inserted into the DOM.\r\n subkeyPopup.reposition(this);\r\n }\r\n });\r\n\r\n return pendingLongpress;\r\n }\r\n\r\n /**\r\n * Initializes all supported gestures given a base key and the triggering touch coordinates.\r\n * @param key The gesture's base key\r\n * @param touch The starting touch coordinates for the gesture\r\n * @returns\r\n */\r\n initGestures(key: KeyElement, input: InputEventCoordinate) {\r\n\r\n if (this.pendingMultiTap) {\r\n switch (this.pendingMultiTap.incrementTouch(key)) {\r\n case PendingMultiTapState.Cancelled:\r\n this.pendingMultiTap = null;\r\n break;\r\n case PendingMultiTapState.Realized:\r\n // Don't initialize any other gestures if the\r\n // multi tap is realized; we cleanup on touch\r\n // release because we need to cancel the base\r\n // key action\r\n return;\r\n }\r\n }\r\n\r\n if (!this.pendingMultiTap && PendingMultiTap.isValidTarget(this, key)) {\r\n // We are only going to support double-tap on Shift\r\n // in Keyman 15, so we pass in the constant count = 2\r\n this.pendingMultiTap = new PendingMultiTap(this, key, 2);\r\n this.pendingMultiTap.timeout.then(() => {\r\n this.pendingMultiTap = null;\r\n });\r\n }\r\n\r\n\r\n if (key['subKeys']) {\r\n let _this = this;\r\n\r\n let pendingLongpress = this.startLongpress(key);\r\n if (pendingLongpress == null) {\r\n return;\r\n }\r\n this.pendingSubkey = pendingLongpress;\r\n\r\n pendingLongpress.promise.then(function (subkeyPopup) {\r\n if (_this.pendingSubkey == pendingLongpress) {\r\n _this.pendingSubkey = null;\r\n }\r\n\r\n if (subkeyPopup) {\r\n // Clear key preview if any\r\n _this.showKeyTip(null, false);\r\n\r\n _this.subkeyGesture = subkeyPopup;\r\n subkeyPopup.promise.then(function (keyEvent: KeyEvent) {\r\n // Allow active cancellation, even if the source should allow passive.\r\n // It's an easy and cheap null guard.\r\n if (keyEvent) {\r\n _this.raiseKeyEvent(keyEvent, null);\r\n }\r\n _this.clearPopup();\r\n });\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Updates all currently-pending and activated gestures.\r\n *\r\n * @param currentKey The key currently underneath the most recent touch coordinate\r\n * @param previousKey The previously-selected key\r\n * @param input The current mouse or touch coordinate for the gesture\r\n * @returns true if should fully capture input, false if input should 'fall through'.\r\n */\r\n updateGestures(currentKey: KeyElement, previousKey: KeyElement, input: InputEventCoordinate): boolean {\r\n let key0 = previousKey;\r\n let key1 = currentKey;\r\n\r\n if(!currentKey && this.pendingMultiTap) {\r\n this.pendingMultiTap.cancel();\r\n this.pendingMultiTap = null;\r\n }\r\n\r\n // Clear previous key highlighting, allow subkey controller to highlight as appropriate.\r\n if (this.subkeyGesture) {\r\n if (key0) {\r\n key0.key.highlight(false);\r\n }\r\n this.subkeyGesture.updateTouch(input);\r\n\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n\r\n return true;\r\n }\r\n\r\n this.currentTarget = null;\r\n\r\n // If popup is visible, need to move over popup, not over main keyboard\r\n // Could be turned into a browser-longpress specific implementation within browser.PendingLongpress?\r\n if (key1 && key1['subKeys'] != null && this.initTouchCoord) {\r\n if(this.pendingSubkey && this.pendingSubkey instanceof InternalPendingLongpress) {\r\n // Show popup keys immediately if touch moved up towards key array (KMEW-100, Build 353)\r\n if (this.initTouchCoord.y - input.y > this.getLongpressFlickThreshold()) {\r\n this.pendingSubkey.resolve();\r\n }\r\n }\r\n }\r\n\r\n // If there is an active popup menu (which can occur from the previous block),\r\n // a subkey popup exists; do not allow base key output.\r\n if (this.subkeyGesture || this.pendingSubkey) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private getLongpressFlickThreshold(): number {\r\n const rowHeight = this.currentLayer.rowHeight;\r\n\r\n // If larger than 5 (and it likely is), new threshold = 1/4 the std. key height.\r\n const proportionalThreshold = rowHeight / 4;\r\n\r\n // 5 - the longpress-flick triggering threshold before 15.0.\r\n return Math.max(proportionalThreshold, 5);\r\n }\r\n\r\n optionKey(e: KeyElement, keyName: string, keyDown: boolean) {\r\n if (keyName.indexOf('K_LOPT') >= 0) {\r\n this.emit('globekey', e, keyDown);\r\n } else if (keyName.indexOf('K_ROPT') >= 0) {\r\n if (keyDown) {\r\n this.emit('hiderequested', e);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Add (or remove) the keytip preview (if KeymanWeb on a phone device)\r\n *\r\n * @param {Object} key HTML key element\r\n * @param {boolean} on show or hide\r\n */\r\n showKeyTip(key: KeyElement, on: boolean) {\r\n var tip = this.keytip;\r\n\r\n if (tip == null) {\r\n return;\r\n }\r\n\r\n let sk = this.subkeyGesture;\r\n let popup = (sk && sk.isVisible());\r\n\r\n // If popup keys are active, do not show the key tip.\r\n on = popup ? false : on;\r\n\r\n tip.show(key, on, this);\r\n };\r\n\r\n /**\r\n * Create a key preview element for phone devices\r\n */\r\n createKeyTip() {\r\n if(this.device.formFactor == 'phone') {\r\n if (this.keytip == null) {\r\n // For now, should only be true (in production) when keyman.isEmbedded == true.\r\n let constrainPopup = this.isEmbedded;\r\n this.keytip = new InternalKeyTip(constrainPopup);\r\n }\r\n }\r\n\r\n // Always append to _Box (since cleared during OSK Load)\r\n if (this.keytip && this.keytip.element) {\r\n this.topContainer.appendChild(this.keytip.element);\r\n }\r\n };\r\n\r\n createGlobeHint(): GlobeHint {\r\n if(this.config.embeddedGestureConfig.createGlobeHint) {\r\n return this.config.embeddedGestureConfig.createGlobeHint(this);\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n shutdown() {\r\n // Prevents style-sheet pollution from multiple keyboard swaps.\r\n if(this.styleSheet && this.styleSheet.parentNode) {\r\n this.styleSheet.parentNode.removeChild(this.styleSheet);\r\n }\r\n\r\n if(this.inputEngine) {\r\n this.inputEngine.unregisterEventHandlers();\r\n }\r\n\r\n if(this.deleting) {\r\n window.clearTimeout(this.deleting);\r\n }\r\n\r\n this.keyPending = null;\r\n this.touchPending = null;\r\n\r\n this.keytip?.show(null, false, this);\r\n this.subkeyGesture?.clear();\r\n this.pendingMultiTap?.cancel();\r\n this.pendingSubkey?.cancel();\r\n }\r\n\r\n raiseKeyEvent(keyEvent: KeyEvent, e: KeyElement) {\r\n // Exclude menu and OSK hide keys from normal click processing\r\n if(keyEvent.kName == 'K_LOPT' || keyEvent.kName == 'K_ROPT') {\r\n this.optionKey(e, keyEvent.kName, true);\r\n return true;\r\n }\r\n\r\n this.emit('keyevent', keyEvent);\r\n }\r\n}\r\n", + "import { DeviceSpec } from \"@keymanapp/web-utils\";\r\nimport { ParsedLengthStyle } from \"./lengthStyle.js\";\r\n\r\nexport function getFontSizeStyle(e: HTMLElement|string): {val: number, absolute: boolean} {\r\n var fs: string;\r\n\r\n if(typeof e == 'string') {\r\n fs = e;\r\n } else {\r\n fs = e.style.fontSize;\r\n if(!fs) {\r\n fs = getComputedStyle(e).fontSize;\r\n }\r\n }\r\n\r\n return new ParsedLengthStyle(fs);\r\n}\r\n\r\nexport function defaultFontSize(device: DeviceSpec, computedHeight: number, isEmbedded: boolean): ParsedLengthStyle {\r\n if(device.touchable) {\r\n const fontScale = device.formFactor == 'phone'\r\n ? 1.6 * (isEmbedded ? 0.65 : 0.6) * 1.2 // Combines original scaling factor with one previously applied to the layer group.\r\n : 2; // iPad or Android tablet\r\n return ParsedLengthStyle.special(fontScale, 'em');\r\n } else {\r\n return computedHeight ? ParsedLengthStyle.inPixels(computedHeight / 8) : undefined;\r\n }\r\n}", + "// Defines the PUA code mapping for the various 'special' modifier/control/non-printing keys on keyboards.\r\n// `specialCharacters` must be kept in sync with the same variable in constants.js. See also CompileKeymanWeb.pas: CSpecialText10\r\nlet specialCharacters = {\r\n '*Shift*': 8,\r\n '*Enter*': 5,\r\n '*Tab*': 6,\r\n '*BkSp*': 4,\r\n '*Menu*': 11,\r\n '*Hide*': 10,\r\n '*Alt*': 25,\r\n '*Ctrl*': 1,\r\n '*Caps*': 3,\r\n '*ABC*': 16,\r\n '*abc*': 17,\r\n '*123*': 19,\r\n '*Symbol*': 21,\r\n '*Currency*': 20,\r\n '*Shifted*': 9,\r\n '*AltGr*': 2,\r\n '*TabLeft*': 7,\r\n '*LAlt*': 0x56,\r\n '*RAlt*': 0x57,\r\n '*LCtrl*': 0x58,\r\n '*RCtrl*': 0x59,\r\n '*LAltCtrl*': 0x60,\r\n '*RAltCtrl*': 0x61,\r\n '*LAltCtrlShift*': 0x62,\r\n '*RAltCtrlShift*': 0x63,\r\n '*AltShift*': 0x64,\r\n '*CtrlShift*': 0x65,\r\n '*AltCtrlShift*': 0x66,\r\n '*LAltShift*': 0x67,\r\n '*RAltShift*': 0x68,\r\n '*LCtrlShift*': 0x69,\r\n '*RCtrlShift*': 0x70,\r\n // Added in Keyman 14.0.\r\n '*LTREnter*': 0x05, // Default alias of '*Enter*'.\r\n '*LTRBkSp*': 0x04, // Default alias of '*BkSp*'.\r\n '*RTLEnter*': 0x71,\r\n '*RTLBkSp*': 0x72,\r\n '*ShiftLock*': 0x73,\r\n '*ShiftedLock*': 0x74,\r\n '*ZWNJ*': 0x75, // If this one is specified, auto-detection will kick in.\r\n '*ZWNJiOS*': 0x75, // The iOS version will be used by default, but the\r\n '*ZWNJAndroid*': 0x76, // Android platform has its own default glyph.\r\n // Added in Keyman 17.0.\r\n // Reference: https://github.com/silnrsi/font-symchar/blob/v4.000/documentation/encoding.md\r\n '*ZWNJGeneric*': 0x79, // Generic version of ZWNJ (no override)\r\n '*Sp*': 0x80, // Space\r\n '*NBSp*': 0x82, // No-break Space\r\n '*NarNBSp*': 0x83, // Narrow No-break Space\r\n '*EnQ*': 0x84, // En Quad\r\n '*EmQ*': 0x85, // Em Quad\r\n '*EnSp*': 0x86, // En Space\r\n '*EmSp*': 0x87, // Em Space\r\n // TODO: Skipping #-per-em-space\r\n '*PunctSp*': 0x8c, // Punctuation Space\r\n '*ThSp*': 0x8d, // Thin Space\r\n '*HSp*': 0x8e, // Hair Space\r\n '*ZWSp*': 0x81, // Zero Width Space\r\n '*ZWJ*': 0x77, // Zero Width Joiner\r\n '*WJ*': 0x78, // Word Joiner\r\n '*CGJ*': 0x7a, // Combining Grapheme Joiner\r\n '*LTRM*': 0x90, // Left-to-right Mark\r\n '*RTLM*': 0x91, // Right-to-left Mark\r\n '*SH*': 0xa1, // Soft Hyphen\r\n '*HTab*': 0xa2, // Horizontal Tabulation\r\n // TODO: Skipping size references\r\n\r\n};\r\n\r\nexport default specialCharacters;", + "\r\n/**\r\n * Maps 'sp' properties on a touch-layout spec to their corresponding CSS class names.\r\n */\r\nlet BUTTON_CLASSES = [\r\n 'default',\r\n 'shift',\r\n 'shift-on',\r\n 'special',\r\n 'special-on',\r\n '', // Key classes 5 through 7 are reserved for future use.\r\n '',\r\n '',\r\n 'deadkey',\r\n 'blank',\r\n 'hidden'\r\n];\r\n\r\nexport default BUTTON_CLASSES;", + "import { ActiveKey, ButtonClass, DeviceSpec, LayoutKey } from '@keymanapp/keyboard-processor';\r\n// At present, we don't use @keymanapp/keyman. Just `keyman`. (Refer to /web/package.json.)\r\nimport { getAbsoluteX, getAbsoluteY } from 'keyman/engine/dom-utils';\r\n\r\nimport { getFontSizeStyle } from '../fontSizeUtils.js';\r\nimport InputEventCoordinate from '../input/inputEventCoordinate.js';\r\nimport specialChars from '../specialCharacters.js';\r\nimport buttonClassNames from '../buttonClassNames.js';\r\n\r\nimport { KeyElement } from '../keyElement.js';\r\nimport VisualKeyboard from '../visualKeyboard.js';\r\n\r\nexport class OSKKeySpec implements LayoutKey {\r\n id: string;\r\n\r\n // Only set (within @keymanapp/keyboard-processor) for keys actually specified in a loaded layout\r\n baseKeyID?: string;\r\n coreID?: string;\r\n elementID?: string;\r\n\r\n text?: string;\r\n sp?: ButtonClass;\r\n width: number;\r\n layer?: string; // The key will derive its base modifiers from this property - may not equal the layer on which it is displayed.\r\n nextlayer?: string;\r\n pad?: number;\r\n sk?: OSKKeySpec[];\r\n default?: boolean;\r\n\r\n constructor(id: string, text?: string, width?: number, sp?: ButtonClass, nextlayer?: string, pad?: number) {\r\n this.id = id;\r\n this.text = text;\r\n this.width = width ? width : 50;\r\n this.sp = sp;\r\n this.nextlayer = nextlayer;\r\n this.pad = pad;\r\n }\r\n}\r\n\r\nexport default abstract class OSKKey {\r\n // Only set here to act as an alias for code built against legacy versions.\r\n static readonly specialCharacters = specialChars;\r\n\r\n static readonly BUTTON_CLASSES = buttonClassNames;\r\n\r\n static readonly HIGHLIGHT_CLASS = 'kmw-key-touched';\r\n readonly spec: OSKKeySpec;\r\n\r\n btn: KeyElement;\r\n label: HTMLSpanElement;\r\n square: HTMLDivElement;\r\n\r\n /**\r\n * The layer of the OSK on which the key is displayed.\r\n */\r\n readonly layer: string;\r\n\r\n constructor(spec: OSKKeySpec, layer: string) {\r\n this.spec = spec;\r\n this.layer = layer;\r\n }\r\n\r\n abstract getId(): string;\r\n\r\n /**\r\n * Attach appropriate class to each key button, according to the layout\r\n *\r\n * @param {Object=} layout source layout description (optional, sometimes)\r\n */\r\n public setButtonClass() {\r\n let key = this.spec;\r\n let btn = this.btn;\r\n\r\n var n=0;\r\n if(typeof key['dk'] == 'string' && key['dk'] == '1') {\r\n n=8;\r\n }\r\n\r\n n = key['sp'] ?? n;\r\n\r\n if(n < 0 || n > 10) {\r\n n=0;\r\n }\r\n\r\n btn.className='kmw-key kmw-key-'+ buttonClassNames[n];\r\n }\r\n\r\n /**\r\n * For keys with button classes that support toggle states, this method\r\n * may be used to toggle which state the key's button class is in.\r\n * - shift <=> shift-on\r\n * - special <=> special-on\r\n * @param {boolean=} flag The new toggle state\r\n */\r\n public setToggleState(flag?: boolean) {\r\n let btnClassId: number;\r\n\r\n btnClassId = this.spec['sp'];\r\n\r\n // 1 + 2: shift + shift-on\r\n // 3 + 4: special + special-on\r\n switch(buttonClassNames[btnClassId]) {\r\n case 'shift':\r\n case 'shift-on':\r\n if(flag === undefined) {\r\n flag = buttonClassNames[btnClassId] == 'shift';\r\n }\r\n\r\n this.spec['sp'] = 1 + (flag ? 1 : 0) as ButtonClass;\r\n break;\r\n // Added in 15.0: special key highlight toggling.\r\n // Was _intended_ in earlier versions, but not actually implemented.\r\n case 'special':\r\n case 'special-on':\r\n if(flag === undefined) {\r\n flag = buttonClassNames[btnClassId] == 'special';\r\n }\r\n\r\n this.spec['sp'] = 3 + (flag ? 1 : 0) as ButtonClass;\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n this.setButtonClass();\r\n }\r\n\r\n // \"Frame key\" - generally refers to non-linguistic keys on the keyboard\r\n public isFrameKey(): boolean {\r\n let classIndex = this.spec['sp'] || 0;\r\n switch(buttonClassNames[classIndex]) {\r\n case 'default':\r\n case 'deadkey':\r\n // Note: will (generally) include the spacebar.\r\n return false;\r\n default:\r\n return true;\r\n }\r\n }\r\n\r\n public allowsKeyTip(): boolean {\r\n if(this.isFrameKey()) {\r\n return false;\r\n } else {\r\n return !this.btn.classList.contains('kmw-spacebar');\r\n }\r\n }\r\n\r\n public highlight(on: boolean) {\r\n var classes=this.btn.classList;\r\n\r\n if(on) {\r\n if(!classes.contains(OSKKey.HIGHLIGHT_CLASS)) {\r\n classes.add(OSKKey.HIGHLIGHT_CLASS);\r\n }\r\n } else {\r\n classes.remove(OSKKey.HIGHLIGHT_CLASS);\r\n }\r\n }\r\n\r\n /**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n *\r\n * @param {String} text The text to be rendered.\r\n * @param {String} style The CSSStyleDeclaration for an element to measure against, without modification.\r\n *\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * This version has been substantially modified to work for this particular application.\r\n */\r\n static getTextMetrics(text: string, emScale: number, style: {fontFamily?: string, fontSize: string}): TextMetrics {\r\n // Since we may mutate the incoming style, let's make sure to copy it first.\r\n // Only the relevant properties, though.\r\n style = {\r\n fontFamily: style.fontFamily,\r\n fontSize: style.fontSize\r\n };\r\n\r\n // A final fallback - having the right font selected makes a world of difference.\r\n if(!style.fontFamily) {\r\n style.fontFamily = getComputedStyle(document.body).fontFamily;\r\n }\r\n\r\n if(!style.fontSize || style.fontSize == \"\") {\r\n style.fontSize = '1em';\r\n }\r\n\r\n let fontFamily = style.fontFamily;\r\n let fontSpec = getFontSizeStyle(style.fontSize);\r\n\r\n var fontSize: string;\r\n if(fontSpec.absolute) {\r\n // We've already got an exact size - use it!\r\n fontSize = fontSpec.val + 'px';\r\n } else {\r\n fontSize = fontSpec.val * emScale + 'px';\r\n }\r\n\r\n // re-use canvas object for better performance\r\n var canvas: HTMLCanvasElement = OSKKey.getTextMetrics['canvas'] ||\r\n (OSKKey.getTextMetrics['canvas'] = document.createElement(\"canvas\"));\r\n var context = canvas.getContext(\"2d\");\r\n context.font = fontSize + \" \" + fontFamily;\r\n var metrics = context.measureText(text);\r\n\r\n return metrics;\r\n }\r\n\r\n /**\r\n * Calculate the font size required for a key cap, scaling to fit longer text\r\n * @param vkbd\r\n * @param style specification for the desired base font size\r\n * @param override if true, don't use the font spec from the button, just use the passed in spec\r\n * @returns font size as a style string\r\n */\r\n getIdealFontSize(vkbd: VisualKeyboard, text: string, style: {height?: string, fontFamily?: string, fontSize: string}, override?: boolean): string {\r\n let buttonStyle = getComputedStyle(this.btn);\r\n let keyWidth = parseFloat(buttonStyle.width);\r\n let emScale = 1;\r\n\r\n const originalSize = getFontSizeStyle(style.fontSize || '1em');\r\n\r\n // Not yet available; it'll be handled in a later layout pass.\r\n if(!buttonStyle.fontSize) {\r\n // NOTE: preserves old behavior for use in documentation keyboards, for now.\r\n // Once we no longer need to maintain this code block, we can drop all current\r\n // method parameters safely.\r\n //\r\n // Recompute the new width for use in autoscaling calculations below, just in case.\r\n emScale = vkbd.getKeyEmFontSize();\r\n keyWidth = this.getKeyWidth(vkbd);\r\n } else if(!override) {\r\n // When available, just use computedStyle instead.\r\n style = buttonStyle;\r\n }\r\n\r\n let fontSpec = getFontSizeStyle(style.fontSize || '1em');\r\n let metrics = OSKKey.getTextMetrics(text, emScale, style);\r\n\r\n const MAX_X_PROPORTION = 0.90;\r\n const MAX_Y_PROPORTION = 0.90;\r\n const X_PADDING = 2;\r\n const Y_PADDING = 2;\r\n\r\n var fontHeight: number, keyHeight: number;\r\n if(metrics.fontBoundingBoxAscent) {\r\n fontHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;\r\n }\r\n\r\n let textHeight = fontHeight ? fontHeight + Y_PADDING : 0;\r\n if(style.height && style.height.indexOf('px') != -1) {\r\n keyHeight = Number.parseFloat(style.height.substring(0, style.height.indexOf('px')));\r\n }\r\n\r\n let xProportion = (keyWidth * MAX_X_PROPORTION) / (metrics.width + X_PADDING); // How much of the key does the text want to take?\r\n let yProportion = textHeight && keyHeight ? (keyHeight * MAX_Y_PROPORTION) / textHeight : undefined;\r\n\r\n var proportion: number = xProportion;\r\n if(yProportion && yProportion < xProportion) {\r\n proportion = yProportion;\r\n }\r\n\r\n // Never upscale keys past the default - only downscale them.\r\n // Proportion < 1: ratio of key width to (padded [loosely speaking]) text width\r\n // maxProportion determines the 'padding' involved.\r\n //\r\n if(proportion < 1) {\r\n if(originalSize.absolute) {\r\n return proportion * fontSpec.val + 'px';\r\n } else {\r\n return proportion * originalSize.val + 'em';\r\n }\r\n } else {\r\n if(originalSize.absolute) {\r\n return fontSpec.val + 'px';\r\n } else {\r\n return originalSize.val + 'em';\r\n }\r\n }\r\n }\r\n\r\n getKeyWidth(vkbd: VisualKeyboard): number {\r\n let key = this.spec as ActiveKey;\r\n return key.proportionalWidth * vkbd.width;\r\n }\r\n\r\n /**\r\n * Replace default key names by special font codes for modifier keys\r\n *\r\n * @param {string} oldText\r\n * @return {string}\r\n **/\r\n protected renameSpecialKey(oldText: string, vkbd: VisualKeyboard): string {\r\n // If a 'special key' mapping exists for the text, replace it with its corresponding special OSK character.\r\n switch(oldText) {\r\n case '*ZWNJ*':\r\n // Default ZWNJ symbol comes from iOS. We'd rather match the system defaults where\r\n // possible / available though, and there's a different standard symbol on Android.\r\n oldText = vkbd.device.OS == DeviceSpec.OperatingSystem.Android ?\r\n '*ZWNJAndroid*' :\r\n '*ZWNJiOS*';\r\n break;\r\n case '*Enter*':\r\n oldText = vkbd.isRTL ? '*RTLEnter*' : '*LTREnter*';\r\n break;\r\n case '*BkSp*':\r\n oldText = vkbd.isRTL ? '*RTLBkSp*' : '*LTRBkSp*';\r\n break;\r\n default:\r\n // do nothing.\r\n }\r\n\r\n let specialCodePUA = 0XE000 + specialChars[oldText];\r\n\r\n return specialChars[oldText] ?\r\n String.fromCharCode(specialCodePUA) :\r\n oldText;\r\n }\r\n\r\n public get keyText(): string {\r\n const spec = this.spec;\r\n const DEFAULT_BLANK = '\\xa0';\r\n\r\n // Add OSK key labels\r\n let keyText = null;\r\n if(spec['text'] == null || spec['text'] == '') {\r\n if(typeof spec['id'] == 'string') {\r\n // If the ID's Unicode-based, just use that code.\r\n keyText = ActiveKey.unicodeIDToText(spec['id']);\r\n }\r\n\r\n keyText = keyText || DEFAULT_BLANK;\r\n } else {\r\n keyText=spec['text'];\r\n\r\n // Unique layer-based transformation: SHIFT-TAB uses a different glyph.\r\n if(keyText == '*Tab*' && this.layer == 'shift') {\r\n keyText = '*TabLeft*';\r\n }\r\n }\r\n\r\n return keyText;\r\n }\r\n\r\n // Produces a HTMLSpanElement with the key's actual text.\r\n protected generateKeyText(vkbd: VisualKeyboard): HTMLSpanElement {\r\n const spec = this.spec;\r\n\r\n let t = document.createElement('span'), ts=t.style;\r\n t.className='kmw-key-text';\r\n\r\n // Add OSK key labels\r\n let keyText = this.keyText;\r\n let specialText = this.renameSpecialKey(keyText, vkbd);\r\n if(specialText != keyText) {\r\n // The keyboard wants to use the code for a special glyph defined by the SpecialOSK font.\r\n keyText = specialText;\r\n spec['font'] = \"SpecialOSK\";\r\n }\r\n\r\n //Override font spec if set for this key in the layout\r\n if(typeof spec['font'] == 'string' && spec['font'] != '') {\r\n ts.fontFamily=spec['font'];\r\n }\r\n\r\n if(typeof spec['fontsize'] == 'string' && spec['fontsize'] != '') {\r\n ts.fontSize=spec['fontsize'];\r\n }\r\n\r\n // For some reason, fonts will sometimes 'bug out' for the embedded iOS page if we\r\n // instead assign fontFamily to the existing style 'ts'. (Occurs in iOS 12.)\r\n let styleSpec: {fontFamily?: string, fontSize: string} = {fontSize: ts.fontSize};\r\n\r\n if(ts.fontFamily) {\r\n styleSpec.fontFamily = ts.fontFamily;\r\n } else {\r\n styleSpec.fontFamily = vkbd.fontFamily; // Helps with style sheet calculations.\r\n }\r\n\r\n // Check the key's display width - does the key visualize well?\r\n let emScale = vkbd.getKeyEmFontSize();\r\n var width: number = OSKKey.getTextMetrics(keyText, emScale, styleSpec).width;\r\n if(width == 0 && keyText != '' && keyText != '\\xa0') {\r\n // Add the Unicode 'empty circle' as a base support for needy diacritics.\r\n\r\n // Disabled by mcdurdin 2020-10-19; dotted circle display is inconsistent on iOS/Safari\r\n // at least and doesn't combine with diacritic marks. For consistent display, it may be\r\n // necessary to build a custom font that does not depend on renderer choices for base\r\n // mark display -- e.g. create marks with custom base included, potentially even on PUA\r\n // code points and use those in rendering the OSK. See #3039 for more details.\r\n // keyText = '\\u25cc' + keyText;\r\n\r\n if(vkbd.isRTL) {\r\n // Add the RTL marker to ensure it displays properly.\r\n keyText = '\\u200f' + keyText;\r\n }\r\n }\r\n\r\n ts.fontSize = this.getIdealFontSize(vkbd, keyText, styleSpec);\r\n\r\n // Finalize the key's text.\r\n t.innerText = keyText;\r\n\r\n return t;\r\n }\r\n\r\n public isUnderTouch(input: InputEventCoordinate): boolean {\r\n let x = input.x;\r\n let y = input.y;\r\n\r\n let btn = this.btn;\r\n let x0 = getAbsoluteX(btn);\r\n let y0 = getAbsoluteY(btn);\r\n let x1 = x0 + btn.offsetWidth;\r\n let y1 = y0 + btn.offsetHeight;\r\n\r\n return (x > x0 && x < x1 && y > y0 && y < y1);\r\n }\r\n\r\n public refreshLayout(vkbd: VisualKeyboard) {\r\n // space bar may not define the text span!\r\n if(this.label) {\r\n if(!this.label.classList.contains('kmw-spacebar-caption')) {\r\n this.label.style.fontSize = this.getIdealFontSize(vkbd, this.keyText, this.btn.style);\r\n } else {\r\n // Remove any custom setting placed on it before recomputing its inherited style info.\r\n this.label.style.fontSize = '';\r\n const fontSize = this.getIdealFontSize(vkbd, this.label.textContent, getComputedStyle(this.label), true);\r\n\r\n // Since the kmw-spacebar-caption version uses !important, we must specify\r\n // it directly on the element too; otherwise, scaling gets ignored.\r\n this.label.style.setProperty(\"font-size\", fontSize, \"important\");\r\n }\r\n }\r\n }\r\n}\r\n", + "import OSKKey, { OSKKeySpec } from \"./keyboard-layout/oskKey.js\";\r\n\r\nexport class KeyData {\r\n ['key']: OSKKey;\r\n ['keyId']: string;\r\n ['subKeys']?: OSKKeySpec[];\r\n\r\n constructor(keyData: OSKKey, keyId: string) {\r\n this['key'] = keyData;\r\n this['keyId'] = keyId;\r\n }\r\n}\r\n\r\nexport type KeyElement = HTMLDivElement & KeyData;\r\n\r\n// Many thanks to https://www.typescriptlang.org/docs/handbook/advanced-types.html for this.\r\nexport function link(elem: HTMLDivElement, data: KeyData): KeyElement {\r\n let e = elem;\r\n\r\n // Merges all properties and methods of KeyData onto the underlying HTMLDivElement, creating a merged class.\r\n for(let id in data) {\r\n if(!e.hasOwnProperty(id)) {\r\n (e)[id] = (data)[id];\r\n }\r\n }\r\n\r\n return e;\r\n}\r\n\r\nexport function isKey(elem: Node): boolean {\r\n return elem && ('key' in elem) && (( elem['key']) instanceof OSKKey);\r\n}\r\n\r\nexport function getKeyFrom(elem: Node): KeyElement {\r\n if(isKey(elem)) {\r\n return elem;\r\n } else {\r\n return null;\r\n }\r\n}", + "import { ActiveKey, Codes, DeviceSpec } from '@keymanapp/keyboard-processor';\r\nimport { landscapeView } from 'keyman/engine/dom-utils';\r\n\r\nimport OSKKey, { OSKKeySpec } from './oskKey.js';\r\nimport { KeyData, KeyElement, link } from '../keyElement.js';\r\nimport OSKRow from './oskRow.js';\r\nimport VisualKeyboard from '../visualKeyboard.js';\r\n\r\n\r\nexport default class OSKBaseKey extends OSKKey {\r\n private capLabel: HTMLDivElement;\r\n public readonly row: OSKRow;\r\n\r\n constructor(spec: OSKKeySpec, layer: string, row: OSKRow) {\r\n super(spec, layer);\r\n this.row = row;\r\n }\r\n\r\n getId(): string {\r\n // Define each key element id by layer id and key id (duplicate possible for SHIFT - does it matter?)\r\n return this.spec.elementID;\r\n }\r\n\r\n getCoreId(): string {\r\n return this.spec.coreID;\r\n }\r\n\r\n getBaseId(): string {\r\n return this.spec.baseKeyID;\r\n }\r\n\r\n // Produces a small reference label for the corresponding physical key on a US keyboard.\r\n private generateKeyCapLabel(): HTMLDivElement {\r\n // Create the default key cap labels (letter keys, etc.)\r\n var x = Codes.keyCodes[this.spec.baseKeyID];\r\n switch(x) {\r\n // Converts the keyman key id code for common symbol keys into its representative ASCII code.\r\n // K_COLON -> K_BKQUOTE\r\n case 186: x=59; break;\r\n case 187: x=61; break;\r\n case 188: x=44; break;\r\n case 189: x=45; break;\r\n case 190: x=46; break;\r\n case 191: x=47; break;\r\n case 192: x=96; break;\r\n // K_LBRKT -> K_QUOTE\r\n case 219: x=91; break;\r\n case 220: x=92; break;\r\n case 221: x=93; break;\r\n case 222: x=39; break;\r\n default:\r\n // No other symbol character represents a base key on the standard QWERTY English layout.\r\n if(x < 48 || x > 90) {\r\n x=0;\r\n }\r\n }\r\n\r\n let q = document.createElement('div');\r\n q.className='kmw-key-label';\r\n if(x > 0) {\r\n q.innerText=String.fromCharCode(x);\r\n } else {\r\n // Keyman-only virtual keys have no corresponding physical key.\r\n // So, no text for the key-cap.\r\n }\r\n return q;\r\n }\r\n\r\n private processSubkeys(btn: KeyElement, vkbd: VisualKeyboard) {\r\n // Add reference to subkey array if defined\r\n var bsn: number, bsk=btn['subKeys'] = this.spec['sk'];\r\n // Transform any special keys into their PUA representations.\r\n for(bsn=0; bsn 0) {\r\n return this.keys[0].displaysKeyCap;\r\n } else {\r\n return undefined;\r\n }\r\n }\r\n\r\n public set displaysKeyCaps(flag: boolean) {\r\n for(const key of this.keys) {\r\n key.displaysKeyCap = flag;\r\n }\r\n }\r\n\r\n public refreshLayout(vkbd: VisualKeyboard) {\r\n const rs = this.element.style;\r\n\r\n const rowHeight = vkbd.internalHeight.scaledBy(this.heightFraction);\r\n rs.maxHeight=rs.lineHeight=rs.height=rowHeight.styleString;\r\n\r\n // Only used for fixed-height scales at present.\r\n const padRatio = 0.15;\r\n\r\n const keyHeightBase = vkbd.usesFixedHeightScaling ? rowHeight : ParsedLengthStyle.forScalar(1);\r\n const padTop = keyHeightBase.scaledBy(padRatio / 2);\r\n const keyHeight = keyHeightBase.scaledBy(1 - padRatio);\r\n\r\n for(const key of this.keys) {\r\n const keySquare = key.btn.parentElement;\r\n const keyElement = key.btn;\r\n\r\n // Set the kmw-key-square position\r\n const kss = keySquare.style;\r\n kss.height=kss.minHeight=keyHeightBase.styleString;\r\n\r\n const kes = keyElement.style;\r\n kes.top = padTop.styleString;\r\n kes.height=kes.lineHeight=kes.minHeight=keyHeight.styleString;\r\n\r\n if(keyElement.key) {\r\n keyElement.key.refreshLayout(vkbd);\r\n }\r\n }\r\n }\r\n}", + "import { ActiveLayer, ActiveLayout } from '@keymanapp/keyboard-processor';\r\n\r\nimport OSKRow from './oskRow.js';\r\nimport OSKBaseKey from './oskBaseKey.js';\r\nimport VisualKeyboard from '../visualKeyboard.js';\r\n\r\nexport default class OSKLayer {\r\n public readonly element: HTMLDivElement;\r\n public readonly rows: OSKRow[];\r\n public readonly spec: ActiveLayer;\r\n public readonly nextlayer: string;\r\n\r\n public readonly globeKey: OSKBaseKey;\r\n public readonly spaceBarKey: OSKBaseKey;\r\n public readonly hideKey: OSKBaseKey;\r\n public readonly capsKey: OSKBaseKey;\r\n public readonly numKey: OSKBaseKey;\r\n public readonly scrollKey: OSKBaseKey;\r\n\r\n private _rowHeight: number;\r\n\r\n public get rowHeight(): number {\r\n return this._rowHeight;\r\n }\r\n\r\n public get id(): string {\r\n return this.spec.id;\r\n }\r\n\r\n public constructor(vkbd: VisualKeyboard,\r\n layout: ActiveLayout,\r\n layer: ActiveLayer) {\r\n this.spec = layer;\r\n\r\n const gDiv = this.element = document.createElement('div');\r\n const gs=gDiv.style;\r\n gDiv.className='kmw-key-layer';\r\n\r\n var nRows=layer['row'].length;\r\n if(nRows > 4 && vkbd.device.formFactor == 'phone') {\r\n gDiv.className = gDiv.className + ' kmw-5rows';\r\n }\r\n\r\n // Set font for layer if defined in layout\r\n gs.fontFamily = 'font' in layout ? layout['font'] : '';\r\n\r\n this.nextlayer = gDiv['layer'] = layer['id'];\r\n if(typeof layer['nextlayer'] == 'string') {\r\n // The gDiv['nextLayer'] is no longer referenced in KMW 15.0+, but is\r\n // maintained for partial back-compat in case any site devs actually\r\n // relied on its value from prior versions.\r\n //\r\n // We won't pay attention to any mutations to the gDiv copy, though.\r\n gDiv['nextLayer'] = this.nextlayer = layer['nextlayer'];\r\n }\r\n\r\n // Create a DIV for each row of the group\r\n let rows=layer['row'];\r\n this.rows = [];\r\n\r\n for(let i=0; i;\r\n private cancelDelayFactor = 125; // 125msec * count\r\n private _destinationLayerId;\r\n\r\n public get timeout() {\r\n return this._timeout;\r\n }\r\n public get realized() {\r\n return this._state == PendingMultiTapState.Realized;\r\n }\r\n public get cancelled() {\r\n return this._state == PendingMultiTapState.Cancelled;\r\n }\r\n\r\n /**\r\n * Construct a record of a potential multitap gesture\r\n * @param vkbd\r\n * @param baseKey key which is being tapped\r\n * @param count number of taps required to finalize this gesture\r\n */\r\n constructor(vkbd: VisualKeyboard, baseKey: KeyElement, count: number) {\r\n this.vkbd = vkbd;\r\n this.count = count;\r\n this.baseKey = baseKey;\r\n\r\n this._destinationLayerId = 'caps';\r\n let multitap = baseKey?.key?.spec?.['multitap'];\r\n if(multitap?.length && multitap[0]?.['nextlayer']) {\r\n this._destinationLayerId = multitap[0]['nextlayer'];\r\n }\r\n\r\n const _this = this;\r\n this._timeout = new Promise(function(resolve) {\r\n // If multiple taps do not occur within the timeout window,\r\n // then we will abandon the gesture\r\n _this.timerId = window.setTimeout(() => {\r\n _this.cancel();\r\n resolve();\r\n }, _this.cancelDelayFactor * _this.count);\r\n });\r\n }\r\n\r\n public static isValidTarget(vkbd: VisualKeyboard, baseKey: KeyElement) {\r\n // Could use String.includes, but Chrome for Android must be version 41+.\r\n // We support down to version 37.\r\n return (\r\n baseKey['keyId'].indexOf('K_SHIFT') >= 0 &&\r\n vkbd.layerGroup.layers['caps'] &&\r\n !baseKey['subKeys'] &&\r\n vkbd.touchCount == 1\r\n );\r\n }\r\n\r\n private cleanup(): void {\r\n if(this.timerId) {\r\n window.clearTimeout(this.timerId);\r\n }\r\n this.timerId = null;\r\n }\r\n\r\n /**\r\n * Cancel a pending multitap gesture\r\n */\r\n public cancel(): void {\r\n this._state = PendingMultiTapState.Cancelled;\r\n this.cleanup();\r\n }\r\n\r\n /**\r\n * Increments the touch counter for the gesture, and\r\n * if the touch count is reached, realize the gesture\r\n * @returns new state of the gesture\r\n */\r\n public incrementTouch(newKey: KeyElement): PendingMultiTapState {\r\n // TODO: support for any key\r\n if(this._state == PendingMultiTapState.Waiting) {\r\n if(!newKey?.['keyId']?.includes('K_SHIFT')) {\r\n this.cancel();\r\n }\r\n else if(++this._touches == this.count) {\r\n this.realize();\r\n }\r\n }\r\n return this._state;\r\n }\r\n\r\n /**\r\n * Realize the gesture. In Keyman 15, this supports only\r\n * the Caps double-tap gesture on the Shift key.\r\n */\r\n public realize(): void {\r\n if(this._state != PendingMultiTapState.Waiting) {\r\n return;\r\n }\r\n this._state = PendingMultiTapState.Realized;\r\n this.cleanup();\r\n\r\n // In Keyman 15, only the K_SHIFT key supports multi-tap, so we can hack\r\n // in the switch to the caps layer.\r\n //\r\n // TODO: generalize this with double-tap key properties in touch layout\r\n // description.\r\n let e = KeyEvent.constructNullKeyEvent(this.vkbd.device);\r\n e.kNextLayer = this._destinationLayerId;\r\n e.Lstates = Codes.stateBitmasks.CAPS;\r\n e.LmodifierChange = true;\r\n this.vkbd.raiseKeyEvent(e, null);\r\n }\r\n}", + "import OSKKey, { OSKKeySpec } from '../../../keyboard-layout/oskKey.js';\r\nimport { KeyData, KeyElement, link } from '../../../keyElement.js';\r\nimport VisualKeyboard from '../../../visualKeyboard.js';\r\n\r\nexport default class OSKSubKey extends OSKKey {\r\n constructor(spec: OSKKeySpec, layer: string) {\r\n if(typeof(layer) != 'string' || layer == '') {\r\n throw \"The 'layer' parameter for subkey construction must be properly defined.\";\r\n }\r\n\r\n super(spec, layer);\r\n }\r\n\r\n getId(): string {\r\n // Create (temporarily) unique ID by prefixing 'popup-' to actual key ID\r\n return 'popup-'+this.layer+'-'+this.spec['id'];\r\n }\r\n\r\n construct(osk: VisualKeyboard, baseKey: KeyElement, topMargin: boolean): HTMLDivElement {\r\n let spec = this.spec;\r\n\r\n let kDiv=document.createElement('div');\r\n let tKey = osk.getDefaultKeyObject();\r\n let ks=kDiv.style;\r\n\r\n for(var tp in tKey) {\r\n if(typeof spec[tp] != 'string') {\r\n spec[tp]=tKey[tp];\r\n }\r\n }\r\n\r\n kDiv.className='kmw-key-square-ex';\r\n if(topMargin) {\r\n ks.marginTop='5px';\r\n }\r\n\r\n if(typeof spec['width'] != 'undefined') {\r\n ks.width=(spec['width']*baseKey.offsetWidth/100)+'px';\r\n } else {\r\n ks.width=baseKey.offsetWidth+'px';\r\n }\r\n ks.height=baseKey.offsetHeight+'px';\r\n\r\n let btnEle=document.createElement('div');\r\n let btn = this.btn = link(btnEle, new KeyData(this, spec['id']));\r\n\r\n this.setButtonClass();\r\n btn.id = this.getId();\r\n\r\n // Must set button size (in px) dynamically, not from CSS\r\n let bs=btn.style;\r\n bs.height=ks.height;\r\n bs.lineHeight=baseKey.style.lineHeight;\r\n bs.width=ks.width;\r\n\r\n // Must set position explicitly, at least for Android\r\n bs.position='absolute';\r\n\r\n btn.appendChild(this.label = this.generateKeyText(osk));\r\n kDiv.appendChild(btn);\r\n\r\n return this.square = kDiv;\r\n }\r\n\r\n public allowsKeyTip(): boolean {\r\n return false;\r\n }\r\n}", + "import OSKSubKey from './oskSubKey.js';\r\nimport RealizedGesture from '../realizedGesture.interface.js';\r\nimport { OSKKeySpec } from '../../../keyboard-layout/oskKey.js';\r\nimport { type KeyElement } from '../../../keyElement.js';\r\nimport OSKBaseKey from '../../../keyboard-layout/oskBaseKey.js';\r\nimport VisualKeyboard from '../../../visualKeyboard.js';\r\nimport InputEventCoordinate from '../../../input/inputEventCoordinate.js';\r\n\r\nimport { DeviceSpec, KeyEvent } from '@keymanapp/keyboard-processor';\r\n\r\n/**\r\n * Represents a 'realized' longpress gesture's default implementation\r\n * within KeymanWeb. Once a touch sequence has been confirmed to\r\n * correspond to a longpress gesture, implementations of this class\r\n * provide the following:\r\n * * The UI needed to present a subkey menu\r\n * * The state management needed to present feedback about the\r\n * currently-selected subkey to the user\r\n * * A `Promise` that will resolve to the user's selected subkey\r\n * once the longpress operation is complete.\r\n *\r\n * As selection of the subkey occurs after the subkey popup is\r\n * displayed, selection of the subkey is inherently asynchronous.\r\n * The `Promise` may also resolve to `null` if the user indicates\r\n * the desire to cancel subkey selection.\r\n */\r\nexport default class SubkeyPopup implements RealizedGesture {\r\n public readonly element: HTMLDivElement;\r\n public readonly shim: HTMLDivElement;\r\n\r\n private vkbd: VisualKeyboard;\r\n private currentSelection: KeyElement;\r\n\r\n private callout: HTMLDivElement;\r\n\r\n public readonly baseKey: KeyElement;\r\n public readonly promise: Promise;\r\n\r\n private initialX: number;\r\n private initialY: number;\r\n\r\n // Resolves the promise that generated this SubkeyPopup.\r\n private resolver: (keyEvent: KeyEvent) => void;\r\n\r\n constructor(vkbd: VisualKeyboard, e: KeyElement) {\r\n let _this = this;\r\n\r\n this.promise = new Promise(function(resolve) {\r\n _this.resolver = resolve;\r\n })\r\n\r\n this.vkbd = vkbd;\r\n this.baseKey = e;\r\n\r\n // If the user doesn't move their finger and releases, we'll output the base key\r\n // by default.\r\n this.currentSelection = e;\r\n e.key.highlight(true);\r\n\r\n // A tag we directly set on a key element during its construction.\r\n let subKeySpec: OSKKeySpec[] = e['subKeys'];\r\n\r\n // The holder is position:fixed, but the keys do not need to be, as no scrolling\r\n // is possible while the array is visible. So it is simplest to let the keys have\r\n // position:static and display:inline-block\r\n var subKeys = this.element = document.createElement('div');\r\n\r\n var i;\r\n subKeys.id='kmw-popup-keys';\r\n\r\n // #3718: No longer prepend base key to popup array\r\n\r\n // Must set position dynamically, not in CSS\r\n var ss=subKeys.style;\r\n\r\n // Set key font according to layout, or defaulting to OSK font\r\n // (copied, not inherited, since OSK is not a parent of popup keys)\r\n ss.fontFamily=vkbd.fontFamily;\r\n\r\n // Copy the font size from the parent key, allowing for style inheritance\r\n const computedStyle = getComputedStyle(e);\r\n ss.fontSize=computedStyle.fontSize;\r\n ss.visibility='hidden';\r\n\r\n var nKeys=subKeySpec.length,nRows,nCols;\r\n nRows=Math.min(Math.ceil(nKeys/9),2);\r\n nCols=Math.ceil(nKeys/nRows);\r\n ss.width=(nCols*e.offsetWidth+nCols*5)+'px';\r\n\r\n // Add nested button elements for each sub-key\r\n for(i=0; i 1 && nRow > 0) {\r\n needsTopMargin = true;\r\n }\r\n\r\n let layer = e['key'].layer;\r\n if(typeof(layer) != 'string' || layer == '') {\r\n // Use the currently-active layer.\r\n layer = vkbd.layerId;\r\n }\r\n let keyGenerator = new OSKSubKey(subKeySpec[i], layer);\r\n let kDiv = keyGenerator.construct(vkbd, e, needsTopMargin);\r\n\r\n subKeys.appendChild(kDiv);\r\n }\r\n\r\n // And add a filter to fade main keyboard\r\n this.shim = document.createElement('div');\r\n this.shim.id = 'kmw-popup-shim';\r\n\r\n // Highlight the duplicated base key or ideal subkey (if a phone)\r\n if(vkbd.device.formFactor == DeviceSpec.FormFactor.Phone) {\r\n this.selectDefaultSubkey(vkbd, e, subKeys /* == this.element */);\r\n }\r\n }\r\n\r\n finalize(input: InputEventCoordinate) {\r\n if(this.resolver) {\r\n let keyEvent: KeyEvent = null;\r\n if(this.currentSelection) {\r\n keyEvent = this.vkbd.initKeyEvent(this.currentSelection, input);\r\n this.currentSelection.key.highlight(false);\r\n }\r\n this.resolver(keyEvent);\r\n }\r\n this.resolver = null;\r\n }\r\n\r\n reposition(vkbd: VisualKeyboard) {\r\n let subKeys = this.element;\r\n let e = this.baseKey;\r\n\r\n // And correct its position with respect to that element\r\n const _Box = vkbd.topContainer;\r\n let rowElement = (e.key as OSKBaseKey).row.element;\r\n let ss=subKeys.style;\r\n var x = e.offsetLeft + (e.offsetParent).offsetLeft + 0.5*(e.offsetWidth-subKeys.offsetWidth);\r\n var xMax = vkbd.width - subKeys.offsetWidth;\r\n\r\n if(x > xMax) {\r\n x=xMax;\r\n }\r\n if(x < 0) {\r\n x=0;\r\n }\r\n ss.left=x+'px';\r\n\r\n let _BoxRect = _Box.getBoundingClientRect();\r\n let rowElementRect = rowElement.getBoundingClientRect();\r\n ss.top = (rowElementRect.top - _BoxRect.top - subKeys.offsetHeight - 3) + 'px';\r\n\r\n // Make the popup keys visible\r\n ss.visibility='visible';\r\n\r\n // For now, should only be true (in production) when keyman.isEmbedded == true.\r\n let constrainPopup = vkbd.isEmbedded;\r\n\r\n let cs = getComputedStyle(subKeys);\r\n let topY = parseFloat(cs.top);\r\n\r\n // Adjust the vertical position of the popup to keep it within the\r\n // bounds of the keyboard rectangle, when on iPhone (system keyboard)\r\n const topOffset = 0; // Set this when testing constrainPopup, e.g. to -80px\r\n let delta = 0;\r\n if(topY < topOffset && constrainPopup) {\r\n delta = topOffset - topY;\r\n ss.top = topOffset + 'px';\r\n }\r\n\r\n // Add the callout\r\n if(vkbd.device.formFactor == DeviceSpec.FormFactor.Phone && vkbd.device.OS == DeviceSpec.OperatingSystem.iOS) {\r\n this.callout = this.addCallout(e, delta);\r\n }\r\n }\r\n\r\n /**\r\n * Add a callout for popup keys (if KeymanWeb on a phone device)\r\n *\r\n * @param {Object} key HTML key element\r\n * @return {Object} callout object\r\n */\r\n addCallout(key: KeyElement, delta?: number): HTMLDivElement {\r\n const _Box = this.vkbd.topContainer;\r\n\r\n delta = delta || 0;\r\n\r\n let calloutHeight = key.offsetHeight - delta + 6;\r\n\r\n if(calloutHeight > 0) {\r\n var cc = document.createElement('div'), ccs = cc.style;\r\n cc.id = 'kmw-popup-callout';\r\n _Box.appendChild(cc);\r\n\r\n // Create the callout\r\n let keyRect = key.getBoundingClientRect();\r\n let _BoxRect = _Box.getBoundingClientRect();\r\n\r\n // Set position and style\r\n // We're going to adjust the top of the box to ensure it stays\r\n // pixel aligned, otherwise we can get antialiasing artifacts\r\n // that look ugly\r\n let top = Math.floor(keyRect.top - _BoxRect.top - 9 + delta);\r\n ccs.top = top + 'px';\r\n ccs.left = (keyRect.left - _BoxRect.left) + 'px';\r\n ccs.width = keyRect.width + 'px';\r\n ccs.height = (keyRect.bottom - _BoxRect.top - top - 1) + 'px'; //(height - 1) + 'px';\r\n\r\n // Return callout element, to allow removal later\r\n return cc;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n selectDefaultSubkey(vkbd: VisualKeyboard, baseKey: KeyElement, popupBase: HTMLElement) {\r\n var bk: KeyElement;\r\n let subkeys = baseKey['subKeys'];\r\n for(let i=0; i < subkeys.length; i++) {\r\n let skSpec = subkeys[i];\r\n let skElement = popupBase.childNodes[i].firstChild;\r\n\r\n // Preference order:\r\n // #1: if a default subkey has been specified, select it.\r\n // #2: if no default subkey is specified, default to a subkey with the same\r\n // key ID and layer / modifier spec.\r\n if(skSpec.default) {\r\n bk = skElement;\r\n break;\r\n } else if(!baseKey.key || !baseKey.key.spec) {\r\n continue;\r\n }\r\n\r\n if(skSpec.elementID == baseKey.key.spec.elementID) {\r\n bk = skElement;\r\n }\r\n }\r\n\r\n if(bk) {\r\n // Prevent sticky-highlighting should the default key be selected.\r\n vkbd.keyPending?.key.highlight(false);\r\n vkbd.keyPending = bk;\r\n this.currentSelection = bk;\r\n // Subkeys never get key previews, so we can directly highlight the subkey.\r\n bk.key.highlight(true);\r\n }\r\n }\r\n\r\n isVisible(): boolean {\r\n return this.element.style.visibility == 'visible';\r\n }\r\n\r\n clear() {\r\n // Discard the reference to the Promise's resolve method, allowing\r\n // GC to clean it up. The corresponding Promise's contract allows\r\n // passive cancellation.\r\n this.resolver = null;\r\n\r\n // Remove the displayed subkey array, if any\r\n if(this.element.parentNode) {\r\n this.element.parentNode.removeChild(this.element);\r\n }\r\n\r\n if(this.shim.parentNode) {\r\n this.shim.parentNode.removeChild(this.shim);\r\n }\r\n\r\n if(this.callout && this.callout.parentNode) {\r\n this.callout.parentNode.removeChild(this.callout);\r\n }\r\n }\r\n\r\n updateTouch(input: InputEventCoordinate) {\r\n // For 'default' subkey handling, we want a small fudge factor.\r\n if(this.initialX === undefined || this.initialY === undefined) {\r\n this.initialX = input.x;\r\n this.initialY = input.y;\r\n }\r\n\r\n const deltaX = this.initialX - input.x;\r\n const deltaY = this.initialY - input.y;\r\n const dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r\n\r\n if(dist > 5) {\r\n this.initialX = Number.MAX_SAFE_INTEGER; // it'll always exceed the threshold hereafter.\r\n this.currentSelection = null;\r\n } else {\r\n // The function that calls this to perform subkey updates auto-unhighlights the active selection;\r\n // make sure that highlighting is maintained if no new key was selected, but we haven't cancelled\r\n // default-selection mode yet.\r\n this.currentSelection.key.highlight(true);\r\n\r\n // Even if we technically have a different subkey underneath the touchpoint, we're still in\r\n // default-selection mode. Require more movement before cancelling default-selection mode.\r\n //\r\n // Can occur for large subkey menus or when subkey menus are \"constrained\" within OSK bounds,\r\n // as with the iOS app.\r\n return;\r\n }\r\n\r\n this.baseKey.key.highlight(false);\r\n\r\n for(let i=0; i < this.baseKey['subKeys'].length; i++) {\r\n try {\r\n let sk = this.element.childNodes[i].firstChild as KeyElement;\r\n\r\n let onKey = sk.key.isUnderTouch(input);\r\n if(onKey) {\r\n this.currentSelection = sk;\r\n }\r\n sk.key.highlight(onKey);\r\n } catch(ex) {\r\n if(ex.message) {\r\n console.error(\"Unexpected error when attempting to update selected subkey:\" + ex.message);\r\n } else {\r\n console.error(\"Unexpected error (and error type) when attempting to update selected subkey.\");\r\n }\r\n }\r\n }\r\n\r\n // Use the popup duplicate of the base key if a phone with a visible popup array\r\n if(!this.currentSelection && this.baseKey.key.isUnderTouch(input)) {\r\n this.baseKey.key.highlight(true);\r\n this.currentSelection = this.baseKey;\r\n }\r\n }\r\n}\r\n", + "import { type KeyElement } from '../../../keyElement.js';\r\nimport VisualKeyboard from '../../../visualKeyboard.js';\r\nimport PendingGesture from '../pendingGesture.interface.js';\r\nimport SubkeyPopup from './subkeyPopup.js';\r\n\r\n/**\r\n * (Conceptually) represents a finite-state-machine that determines\r\n * whether or not a series of touch events corresponds to a longpress\r\n * touch input. The `resolve` method may be used to trigger the\r\n * subkey menu early, as with the upward quick-display shortcut.\r\n *\r\n * This is the default implementation of longpress behavior for KMW.\r\n * Alterate implementations are modeled through the `embedded`\r\n * namespace's equivalent, which is designed to facilitate custom\r\n * modeling for such gestures.\r\n *\r\n * Once the conditions to recognize a longpress gesture have been\r\n * fulfilled, this class's `promise` will resolve with a `SubkeyPopup`\r\n * matching the gesture's 'base' key, which itself provides a\r\n * `promise` field that will resolve to a `KeyEvent` once the touch\r\n * sequence is completed.\r\n */\r\nexport default class PendingLongpress implements PendingGesture {\r\n public readonly baseKey: KeyElement;\r\n public readonly promise: Promise;\r\n\r\n public readonly subkeyUI: SubkeyPopup;\r\n\r\n private readonly vkbd: VisualKeyboard;\r\n private resolver: (subkeyPopup: SubkeyPopup) => void;\r\n\r\n private timerId: number;\r\n private popupDelay: number = 500;\r\n\r\n constructor(vkbd: VisualKeyboard, baseKey: KeyElement) {\r\n this.vkbd = vkbd;\r\n this.baseKey = baseKey;\r\n\r\n let _this = this;\r\n this.promise = new Promise(function(resolve, reject) {\r\n _this.resolver = resolve;\r\n // After the timeout, it's no longer deferred; it's being fulfilled.\r\n // Even if the actual subkey itself is still async.\r\n _this.timerId = window.setTimeout(_this.resolve.bind(_this), _this.popupDelay);\r\n });\r\n }\r\n\r\n public cancel() {\r\n if(this.timerId) {\r\n window.clearTimeout(this.timerId);\r\n this.timerId = null;\r\n }\r\n\r\n if(this.resolver) {\r\n this.resolver(null);\r\n this.resolver = null;\r\n }\r\n }\r\n\r\n public resolve() {\r\n // User has flicked up to get to the longpress, before\r\n // the timeout has expired. We need to cancel the timeout.\r\n // See #5950\r\n if(this.timerId) {\r\n window.clearTimeout(this.timerId);\r\n this.timerId = null;\r\n }\r\n\r\n if(this.resolver) {\r\n this.resolver(new SubkeyPopup(this.vkbd, this.baseKey));\r\n }\r\n }\r\n}\r\n", + "import OSKBaseKey from '../../../keyboard-layout/oskBaseKey.js';\r\nimport { KeyElement } from '../../../keyElement.js';\r\nimport KeyTipInterface from '../../../keytip.interface.js';\r\nimport VisualKeyboard from '../../../visualKeyboard.js';\r\n\r\nexport default class KeyTip implements KeyTipInterface {\r\n public readonly element: HTMLDivElement;\r\n public key: KeyElement;\r\n public state: boolean = false;\r\n\r\n // -----\r\n // | | <-- tip\r\n // | x | <-- label\r\n // |_ _|\r\n // | |\r\n // | | <-- cap\r\n // |___|\r\n\r\n private readonly cap: HTMLDivElement;\r\n private readonly tip: HTMLDivElement;\r\n private readonly label: HTMLSpanElement;\r\n\r\n private readonly constrain: boolean;\r\n\r\n /**\r\n *\r\n * @param constrain keep the keytip within the bounds of the overall OSK.\r\n * Will probably be handled via function in a later pass.\r\n */\r\n constructor(constrain: boolean) {\r\n let tipElement = this.element=document.createElement('div');\r\n tipElement.className='kmw-keytip';\r\n tipElement.id = 'kmw-keytip';\r\n\r\n // The following style is critical, so do not rely on external CSS\r\n tipElement.style.pointerEvents='none';\r\n tipElement.style.display='none';\r\n\r\n tipElement.appendChild(this.tip = document.createElement('div'));\r\n tipElement.appendChild(this.cap = document.createElement('div'));\r\n this.tip.appendChild(this.label = document.createElement('span'));\r\n\r\n this.tip.className = 'kmw-keytip-tip';\r\n this.cap.className = 'kmw-keytip-cap';\r\n this.label.className = 'kmw-keytip-label';\r\n\r\n this.constrain = constrain;\r\n }\r\n\r\n show(key: KeyElement, on: boolean, vkbd: VisualKeyboard) {\r\n // Create and display the preview\r\n // If !key.offsetParent, the OSK is probably hidden. Either way, it's a half-\r\n // decent null-guard check.\r\n if(on && key.offsetParent) {\r\n // The key element is positioned relative to its key-square, which is,\r\n // in turn, relative to its row. Rows take 100% width, so this is sufficient.\r\n //\r\n let rowElement = (key.key as OSKBaseKey).row.element;\r\n\r\n // May need adjustment for borders if ever enabled for the desktop form-factor target.\r\n let rkey = key.getClientRects()[0], rrow = rowElement.getClientRects()[0];\r\n let xLeft = rkey.left - rrow.left,\r\n xWidth = rkey.width,\r\n xHeight = rkey.height,\r\n kc = key.key.label,\r\n previewFontScale = 1.8;\r\n\r\n let kts = this.element.style;\r\n\r\n // Roughly matches how the subkey positioning is set.\r\n const _Box = vkbd.topContainer as HTMLDivElement;\r\n const _BoxRect = _Box.getBoundingClientRect();\r\n const keyRect = key.getBoundingClientRect();\r\n let y = (keyRect.bottom - _BoxRect.top + 1);\r\n let ySubPixelPadding = y - Math.floor(y);\r\n\r\n // Canvas dimensions must be set explicitly to prevent clipping\r\n // This gives us exactly the same number of pixels on left and right\r\n let canvasWidth = xWidth + Math.ceil(xWidth * 0.3) * 2;\r\n let canvasHeight = Math.ceil(2.3 * xHeight) + (ySubPixelPadding); //\r\n\r\n kts.top = 'auto';\r\n kts.bottom = Math.floor(_BoxRect.height - y) + 'px';\r\n kts.textAlign = 'center';\r\n kts.overflow = 'visible';\r\n kts.width = canvasWidth+'px';\r\n kts.height = canvasHeight+'px';\r\n\r\n const ckts = getComputedStyle(vkbd.element);\r\n kts.fontFamily = ckts.fontFamily;\r\n\r\n var px=parseInt(ckts.fontSize,10);\r\n if(px == Number.NaN) {\r\n px = 0;\r\n }\r\n\r\n if(px != 0) {\r\n let popupFS = previewFontScale * px;\r\n let scaleStyle = {\r\n fontFamily: kts.fontFamily,\r\n fontSize: popupFS + 'px',\r\n height: 1.6 * xHeight + 'px' // as opposed to the canvas height of 2.3 * xHeight.\r\n };\r\n\r\n kts.fontSize = key.key.getIdealFontSize(vkbd, key.key.keyText, scaleStyle, true);\r\n }\r\n\r\n this.label.textContent = kc.textContent;\r\n\r\n // Adjust shape if at edges\r\n var xOverflow = (canvasWidth - xWidth) / 2;\r\n if(xLeft < xOverflow) {\r\n this.cap.style.left = '1px';\r\n xLeft += xOverflow - 1;\r\n } else if(xLeft > window.innerWidth - xWidth - xOverflow) {\r\n this.cap.style.left = (canvasWidth - xWidth - 1) + 'px';\r\n xLeft -= xOverflow - 1;\r\n } else {\r\n this.cap.style.left = xOverflow + 'px';\r\n }\r\n\r\n kts.left=(xLeft - xOverflow) + 'px';\r\n\r\n let cs = getComputedStyle(this.element);\r\n let oskHeight = _BoxRect.height;\r\n let bottomY = parseFloat(cs.bottom);\r\n let tipHeight = parseFloat(cs.height);\r\n let halfHeight = Math.ceil(canvasHeight / 2);\r\n\r\n this.cap.style.width = xWidth + 'px';\r\n this.tip.style.height = halfHeight + 'px';\r\n\r\n this.cap.style.top = (halfHeight - 3) + 'px';\r\n this.cap.style.height = (keyRect.bottom - _BoxRect.top - Math.floor(y - canvasHeight) - (halfHeight)) + 'px'; //(halfHeight + 3 + ySubPixelPadding) + 'px';\r\n\r\n if(this.constrain && tipHeight + bottomY > oskHeight) {\r\n const delta = tipHeight + bottomY - oskHeight;\r\n kts.height = (canvasHeight-delta) + 'px';\r\n const hx = Math.max(0, (canvasHeight-delta)-(canvasHeight/2) + 2);\r\n this.cap.style.height = hx + 'px';\r\n }\r\n\r\n kts.display = 'block';\r\n } else { // Hide the key preview\r\n this.element.style.display = 'none';\r\n }\r\n\r\n // Save the key preview state\r\n this.key = key;\r\n this.state = on;\r\n }\r\n}", + "import { landscapeView } from \"keyman/engine/dom-utils\";\r\n\r\n/**\r\n * Get viewport scale factor for this document\r\n *\r\n * @return {number}\r\n */\r\nexport function getViewportScale(): number {\r\n // This can sometimes fail with some browsers if called before document defined,\r\n // so catch the exception\r\n try {\r\n // For emulation of iOS on a desktop device, use a default value\r\n if(this.device.formFactor == 'desktop') {\r\n return 1;\r\n }\r\n\r\n // Get viewport width\r\n var viewportWidth = document.documentElement.clientWidth;\r\n\r\n // Return a default value if screen width is greater than the viewport width (not fullscreen).\r\n if(screen.width > viewportWidth) {\r\n return 1;\r\n }\r\n\r\n // Get the orientation corrected screen width\r\n var screenWidth = screen.width;\r\n if(landscapeView()) {\r\n // Take larger of the two dimensions\r\n if(screen.width < screen.height) {\r\n screenWidth = screen.height;\r\n }\r\n } else {\r\n // Take smaller of the two dimensions\r\n if(screen.width > screen.height) {\r\n screenWidth = screen.height;\r\n }\r\n }\r\n // Calculate viewport scale\r\n return Math.round(100*screenWidth / viewportWidth)/100;\r\n } catch(ex) {\r\n return 1;\r\n }\r\n}", + "import EventEmitter from 'eventemitter3';\r\n\r\ninterface EventMap {\r\n activate: (flag: boolean) => void;\r\n}\r\n\r\n/**\r\n * Used to encapsulate activation logic for the on-screen keyboadr, conditionally activating\r\n * and deactivating it based on specified conditions.\r\n */\r\nexport default abstract class Activator extends EventEmitter {\r\n /**\r\n * For certain sub-types, this may be set to `false` to \"turn activation off\", putting\r\n * the `Activator` in a state that ignores changes to any other conditions.\r\n */\r\n abstract get enabled(): boolean;\r\n\r\n abstract set enabled(flag: boolean);\r\n\r\n /**\r\n * When `true`, indicates that the listener should activate / become visible.\r\n */\r\n abstract get activate(): boolean;\r\n\r\n /**\r\n * When `true` and `activate` is `false`, indicates that changing the value of `enabled`\r\n * will result in activation.\r\n */\r\n abstract get conditionsMet(): boolean;\r\n}\r\n\r\nexport class StaticActivator extends Activator {\r\n get enabled(): boolean {\r\n return true;\r\n }\r\n\r\n get activate(): boolean {\r\n return true;\r\n }\r\n\r\n get conditionsMet(): boolean {\r\n return true;\r\n }\r\n}", + "import { ManagedPromise } from \"@keymanapp/web-utils\";\r\n\r\nexport default class TouchEventPromiseMap {\r\n private map: Record> = {};\r\n\r\n // Used to\r\n public promiseForTouchpoint(id: number): ManagedPromise {\r\n if(!this.map[id]) {\r\n this.map[id] = new ManagedPromise();\r\n }\r\n\r\n return this.map[id]; // touchpoint identifiers are unique during a page's lifetime.\r\n }\r\n\r\n public maintainTouches(list: TouchList) {\r\n let keys = Object.keys(this.map);\r\n\r\n for(let i=0; i < list.length; i++) {\r\n let pos = keys.indexOf('' + list.item(i).identifier);\r\n if(pos != -1) {\r\n keys.splice(pos, 1);\r\n }\r\n }\r\n\r\n // Any remaining entries of `keys` are no longer in the map!\r\n for(let endedKey of keys) {\r\n (this.map[endedKey] as ManagedPromise).resolve();\r\n delete this.map[endedKey];\r\n }\r\n }\r\n}", + "import EventEmitter from 'eventemitter3';\r\n\r\nimport { Keyboard } from '@keymanapp/keyboard-processor';\r\n\r\nimport OSKViewComponent from './oskViewComponent.interface.js';\r\nimport { ParsedLengthStyle } from '../lengthStyle.js';\r\nimport MouseDragOperation from '../input/mouseDragOperation.js';\r\n\r\nimport { createUnselectableElement } from 'keyman/engine/dom-utils';\r\n\r\ninterface EventMap {\r\n /**\r\n * The close button (to request that the OSK hide) has been clicked.\r\n */\r\n close: () => void,\r\n\r\n /**\r\n * The config button has been clicked.\r\n */\r\n config: () => void,\r\n\r\n /**\r\n * The help button has been clicked.\r\n */\r\n help: () => void,\r\n\r\n /**\r\n * The pin button was visible and has been clicked.\r\n */\r\n unpin: () => void\r\n}\r\n\r\nexport default class TitleBar extends EventEmitter implements OSKViewComponent {\r\n private _element: HTMLDivElement;\r\n private _unpinButton: HTMLDivElement;\r\n private _closeButton: HTMLDivElement;\r\n private _helpButton: HTMLDivElement;\r\n private _configButton: HTMLDivElement;\r\n private _caption: HTMLSpanElement;\r\n\r\n private _helpEnabled: boolean;\r\n private _configEnabled: boolean;\r\n\r\n public get helpEnabled(): boolean {\r\n return this._helpEnabled;\r\n }\r\n\r\n public set helpEnabled(val) {\r\n this._helpEnabled = val;\r\n\r\n this._helpButton.style.display = val ? 'inline' : 'none';\r\n }\r\n\r\n public get configEnabled(): boolean {\r\n return this._configEnabled;\r\n }\r\n\r\n public set configEnabled(val) {\r\n this._configEnabled = val;\r\n\r\n this._configButton.style.display = val ? 'inline' : 'none';\r\n }\r\n\r\n private static readonly DISPLAY_HEIGHT = ParsedLengthStyle.inPixels(20); // As set in kmwosk.css\r\n\r\n public constructor(dragHandler?: MouseDragOperation) {\r\n super();\r\n\r\n this._element = this.buildTitleBar();\r\n\r\n this.helpEnabled = false;\r\n this.configEnabled = false;\r\n\r\n if(dragHandler) {\r\n this.element.onmousedown = dragHandler.mouseDownHandler;\r\n }\r\n }\r\n\r\n public get layoutHeight(): ParsedLengthStyle {\r\n return TitleBar.DISPLAY_HEIGHT;\r\n }\r\n\r\n private mouseCancellingHandler: (ev: MouseEvent) => boolean = function(ev: MouseEvent) {\r\n ev.preventDefault();\r\n ev.cancelBubble = true;\r\n return false;\r\n };\r\n\r\n public get element(): HTMLDivElement {\r\n return this._element;\r\n }\r\n\r\n public setPinCJKOffset() {\r\n this._unpinButton.style.left = '15px';\r\n }\r\n\r\n public showPin(visible: boolean) {\r\n this._unpinButton.style.display = visible ? 'block' : 'none';\r\n }\r\n\r\n public setTitle(str: string) {\r\n this._caption.innerHTML = str;\r\n }\r\n\r\n public setTitleFromKeyboard(keyboard: Keyboard) {\r\n let title = \"\" + keyboard?.name + ''; // I1972 // I2186\r\n this._caption.innerHTML = title;\r\n }\r\n\r\n /**\r\n * Create a control bar with title and buttons for the desktop OSK\r\n */\r\n buildTitleBar(): HTMLDivElement {\r\n let bar = createUnselectableElement('div');\r\n bar.id='keymanweb_title_bar';\r\n bar.className='kmw-title-bar';\r\n\r\n var Ltitle = this._caption = createUnselectableElement('span');\r\n Ltitle.className='kmw-title-bar-caption';\r\n Ltitle.style.color='#fff';\r\n bar.appendChild(Ltitle);\r\n\r\n var Limg = this._closeButton = this.buildCloseButton();\r\n this._closeButton.onclick = () => {\r\n this.emit('close');\r\n return false;\r\n };\r\n bar.appendChild(Limg);\r\n\r\n Limg = this._helpButton = this.buildHelpButton()\r\n this._helpButton.onclick = () => {\r\n this.emit('help');\r\n return false;\r\n }\r\n bar.appendChild(Limg);\r\n\r\n Limg = this._configButton = this.buildConfigButton();\r\n this._configButton.onclick = () => {\r\n this.emit('config');\r\n return false;\r\n }\r\n bar.appendChild(Limg);\r\n\r\n Limg = this._unpinButton = this.buildUnpinButton();\r\n this._unpinButton.onclick = () => {\r\n this.emit('unpin');\r\n return false;\r\n }\r\n bar.appendChild(Limg);\r\n\r\n return bar;\r\n }\r\n\r\n private buildCloseButton(): HTMLDivElement {\r\n var Limg = createUnselectableElement('div');\r\n\r\n Limg.id='kmw-close-button';\r\n Limg.className='kmw-title-bar-image';\r\n Limg.onmousedown = this.mouseCancellingHandler;\r\n\r\n return Limg;\r\n }\r\n\r\n private buildHelpButton(): HTMLDivElement {\r\n let Limg = createUnselectableElement('div');\r\n Limg.id='kmw-help-image';\r\n Limg.className='kmw-title-bar-image';\r\n Limg.title='KeymanWeb Help';\r\n Limg.onmousedown = this.mouseCancellingHandler;\r\n return Limg;\r\n }\r\n\r\n private buildConfigButton(): HTMLDivElement {\r\n let Limg = createUnselectableElement('div');\r\n\r\n Limg.id='kmw-config-image';\r\n Limg.className='kmw-title-bar-image';\r\n Limg.title='KeymanWeb Configuration Options';\r\n Limg.onmousedown = this.mouseCancellingHandler;\r\n\r\n return Limg;\r\n }\r\n\r\n /**\r\n * Builds an 'unpin' button for restoring OSK to default location, handle mousedown and click events\r\n */\r\n private buildUnpinButton(): HTMLDivElement {\r\n let Limg = createUnselectableElement('div'); //I2186\r\n\r\n Limg.id = 'kmw-pin-image';\r\n Limg.className = 'kmw-title-bar-image';\r\n Limg.title='Pin the On Screen Keyboard to its default location on the active text box';\r\n\r\n Limg.onmousedown = this.mouseCancellingHandler;\r\n\r\n return Limg;\r\n }\r\n\r\n public refreshLayout() {\r\n // The title bar is adaptable as it is and needs no adjustments.\r\n }\r\n}", + "import EventEmitter from 'eventemitter3';\r\n\r\nimport OSKViewComponent from './oskViewComponent.interface.js';\r\nimport { ParsedLengthStyle } from '../lengthStyle.js';\r\nimport MouseDragOperation from '../input/mouseDragOperation.js';\r\n\r\nimport { createUnselectableElement } from 'keyman/engine/dom-utils';\r\n\r\ninterface EventMap {\r\n /**\r\n * Triggered when the user inputs a special command to show the engine's current version number.\r\n */\r\n showbuild: () => void;\r\n}\r\n\r\nexport default class ResizeBar extends EventEmitter implements OSKViewComponent {\r\n private _element: HTMLDivElement;\r\n private _resizeHandle: HTMLDivElement;\r\n\r\n private static readonly DISPLAY_HEIGHT = ParsedLengthStyle.inPixels(16); // As set in kmwosk.css\r\n\r\n private mouseCancellingHandler: (ev: MouseEvent) => boolean = function(ev: MouseEvent) {\r\n ev.preventDefault();\r\n ev.cancelBubble = true;\r\n return false;\r\n };\r\n\r\n public constructor(dragHandler?: MouseDragOperation) {\r\n super();\r\n this._element = this.buildResizeBar();\r\n\r\n if(dragHandler) {\r\n this._resizeHandle.onmousedown = dragHandler.mouseDownHandler;\r\n }\r\n }\r\n\r\n public get layoutHeight(): ParsedLengthStyle {\r\n return ResizeBar.DISPLAY_HEIGHT;\r\n }\r\n\r\n public get element(): HTMLDivElement {\r\n return this._element;\r\n }\r\n\r\n public get handle(): HTMLDivElement {\r\n return this._resizeHandle;\r\n }\r\n\r\n public allowResizing(flag: boolean) {\r\n this._resizeHandle.style.display = flag ? 'block' : 'none';\r\n }\r\n\r\n /**\r\n * Create a bottom bar with a resizing icon for the desktop OSK\r\n */\r\n buildResizeBar(): HTMLDivElement {\r\n var bar = createUnselectableElement('div');\r\n bar.className='kmw-footer';\r\n bar.onmousedown = this.mouseCancellingHandler;\r\n\r\n // Add caption\r\n var Ltitle=createUnselectableElement('div');\r\n Ltitle.className='kmw-footer-caption';\r\n Ltitle.innerHTML='KeymanWeb';\r\n Ltitle.id='keymanweb-osk-footer-caption';\r\n\r\n // Display build number on shift+double click\r\n Ltitle.addEventListener('dblclick', (e) => {\r\n this.emit('showbuild');\r\n\r\n return false;\r\n }, false);\r\n\r\n bar.appendChild(Ltitle);\r\n\r\n var Limg = createUnselectableElement('div');\r\n Limg.className='kmw-footer-resize';\r\n bar.appendChild(Limg);\r\n this._resizeHandle=Limg;\r\n\r\n return bar;\r\n }\r\n\r\n public refreshLayout() {\r\n // The title bar is adaptable as it is and needs no adjustments.\r\n }\r\n}", + "import InputEventCoordinate from './inputEventCoordinate.js';\r\n\r\ntype MouseHandler = (this: GlobalEventHandlers, ev: MouseEvent) => any;\r\n\r\n/**\r\n * Used to store the page's original mouse handlers and properties\r\n * when temporarily overridden by OSK moving or resizing handlers due\r\n * to user interaction.\r\n */\r\nclass MouseStartSnapshot {\r\n private readonly _VPreviousMouseMove: MouseHandler;\r\n private readonly _VPreviousMouseUp: MouseHandler;\r\n private readonly _VPreviousCursor: string;\r\n private readonly _VPreviousMouseButton: number;\r\n\r\n constructor(e: MouseEvent) {\r\n this._VPreviousMouseMove = document.onmousemove;\r\n this._VPreviousMouseUp = document.onmouseup;\r\n\r\n this._VPreviousCursor = document.body.style.cursor;\r\n this._VPreviousMouseButton = (typeof(e.which)=='undefined' ? e.button : e.which);\r\n }\r\n\r\n restore() {\r\n document.onmousemove = this._VPreviousMouseMove;\r\n document.onmouseup = this._VPreviousMouseUp;\r\n\r\n if(document.body.style.cursor) {\r\n document.body.style.cursor = this._VPreviousCursor;\r\n }\r\n }\r\n\r\n matchesCausingClick(e: MouseEvent): boolean {\r\n return this._VPreviousMouseButton == (typeof(e.which)=='undefined' ? e.button : e.which);\r\n }\r\n}\r\n\r\nexport default abstract class MouseDragOperation {\r\n private _enabled: boolean;\r\n private _startCoord: InputEventCoordinate;\r\n private _mouseStartSnapshot: MouseStartSnapshot;\r\n\r\n private startHandler: (e: MouseEvent) => void;\r\n private cursorType: string;\r\n\r\n public constructor(cursorType?: string) {\r\n this.startHandler = this._VMoveMouseDown.bind(this);\r\n this.cursorType = cursorType;\r\n }\r\n\r\n /**\r\n * Denotes whether or not this object should handle incoming events.\r\n */\r\n public get enabled(): boolean {\r\n return this._enabled;\r\n }\r\n\r\n public set enabled(flag: boolean) {\r\n this._enabled = flag;\r\n }\r\n\r\n /**\r\n * Denotes whether or not this object is currently handling an ongoing drag event.\r\n */\r\n public get isActive(): boolean {\r\n return !!this._mouseStartSnapshot;\r\n }\r\n\r\n public get mouseDownHandler(): (e: MouseEvent) => void {\r\n return this.startHandler;\r\n }\r\n\r\n /**\r\n * Function _VMoveMouseDown\r\n * Scope Private\r\n * @param {Object} e event\r\n * Description Process mouse down on OSK\r\n */\r\n private _VMoveMouseDown(e: MouseEvent) {\r\n if(!e) {\r\n return true;\r\n }\r\n\r\n if(!this._enabled) {\r\n return true;\r\n }\r\n\r\n if(!this._mouseStartSnapshot) { // I1472 - Dragging off edge of browser window causes muckup\r\n this._mouseStartSnapshot = new MouseStartSnapshot(e);\r\n }\r\n\r\n this._startCoord = InputEventCoordinate.fromEvent(e);\r\n\r\n document.onmousemove = this._VMoveMouseMove.bind(this);\r\n document.onmouseup = this._VMoveMouseUp.bind(this);\r\n if(document.body.style.cursor) {\r\n document.body.style.cursor = this.cursorType;\r\n }\r\n\r\n e.preventDefault();\r\n e.cancelBubble = true;\r\n\r\n this.onDragStart();\r\n return false;\r\n }\r\n\r\n protected abstract onDragStart();\r\n\r\n /**\r\n * Process mouse drag on OSK\r\n *\r\n * @param {Object} e event\r\n */\r\n private _VMoveMouseMove(e: MouseEvent) {\r\n if(!e) {\r\n return true;\r\n }\r\n\r\n if(!this.enabled) {\r\n return true;\r\n }\r\n\r\n e.preventDefault();\r\n e.cancelBubble = true;\r\n\r\n if(!this._mouseStartSnapshot.matchesCausingClick(e)) { // I1472 - Dragging off edge of browser window causes muckup\r\n return this._VMoveMouseUp(e);\r\n } else {\r\n const coord = InputEventCoordinate.fromEvent(e);\r\n const deltaX = coord.x - this._startCoord.x;\r\n const deltaY = coord.y - this._startCoord.y;\r\n\r\n this.onDragMove(deltaX, deltaY);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @param deltaX The total horizontal distance moved, in pixels, since the start of the drag\r\n * @param deltaY The total vertical distance moved, in pixels, since the start of the drag\r\n */\r\n protected abstract onDragMove(deltaX: number, deltaY: number);\r\n\r\n /**\r\n * Function _VMoveMouseUp\r\n * Scope Private\r\n * @param {Object} e event\r\n * Description Process mouse up during movement of KMW OSK UI\r\n */\r\n private _VMoveMouseUp(e: MouseEvent) {\r\n if(!e) {\r\n return true;\r\n }\r\n\r\n this._mouseStartSnapshot.restore();\r\n this._mouseStartSnapshot = null;\r\n\r\n e.preventDefault();\r\n e.cancelBubble = true;\r\n\r\n this.onDragRelease();\r\n return false;\r\n }\r\n\r\n protected abstract onDragRelease();\r\n}", + "import Activator from './activator.js';\r\n\r\ninterface TriggerEventMap {\r\n triggerchange: (trigger: Type) => void;\r\n}\r\n\r\nexport default class TwoStateActivator extends Activator> {\r\n private _enabled: boolean = true;\r\n private actValue: Type = null;\r\n\r\n get activate(): boolean {\r\n return this._enabled && !!this.actValue;\r\n }\r\n\r\n private checkState(oldValue: boolean) {\r\n if(this.activate != oldValue) {\r\n this.emit('activate', this.activate);\r\n }\r\n }\r\n\r\n get enabled(): boolean {\r\n return this._enabled;\r\n }\r\n\r\n set enabled(flag: boolean) {\r\n const oldState = this.activate;\r\n this._enabled = flag; // may change this.value!\r\n\r\n this.checkState(oldState);\r\n }\r\n\r\n get activationTrigger(): Type {\r\n return this.actValue;\r\n }\r\n\r\n set activationTrigger(value: Type) {\r\n const oldState = this.activate;\r\n const oldValue = this.actValue;\r\n this.actValue = value; // may change this.value!\r\n\r\n this.checkState(oldState);\r\n if(oldValue != value) {\r\n this.emit('triggerchange', value);\r\n }\r\n }\r\n\r\n get conditionsMet(): boolean {\r\n return !!this.activationTrigger;\r\n }\r\n}", + "import { CookieSerializer } from 'keyman/engine/dom-utils';\r\n\r\nexport interface FloatingOSKCookie {\r\n /**\r\n * Notes whether or not the OSK was hidden at the end of the previous session.\r\n */\r\n visible: 0 | 1;\r\n\r\n /**\r\n * Notes whether or not the OSK was pinned (located by the user) at the end\r\n * of the previous session.\r\n */\r\n userSet: 0 | 1;\r\n\r\n /**\r\n * Denotes the left-position of the OSK at the end of the previous session if pinned.\r\n * Defaults to -1 if the value was undefined.\r\n */\r\n left: number;\r\n\r\n /**\r\n * Denotes the left-position of the OSK at the end of the previous session if pinned.\r\n * Defaults to -1 if the value was undefined.\r\n */\r\n top: number;\r\n\r\n /**\r\n * The previously-set OSK width.\r\n */\r\n width?: number;\r\n\r\n /**\r\n * The previously-set OSK height.\r\n */\r\n height?: number;\r\n\r\n /**\r\n * The version of KeymanWeb active when this cookie was generated.\r\n */\r\n _version: string;\r\n}\r\n\r\nexport class FloatingOSKCookieSerializer extends CookieSerializer> {\r\n constructor() {\r\n super('KeymanWeb_OnScreenKeyboard');\r\n }\r\n\r\n loadWithDefaults(defaults: Required) {\r\n return {...defaults, ...this.load()};\r\n }\r\n\r\n load() {\r\n const cookie = super.load((value, key) => {\r\n switch(key) {\r\n case 'version':\r\n return value;\r\n default:\r\n return Number.parseInt(value, 10);\r\n }\r\n });\r\n\r\n if(!cookie.width) {\r\n delete cookie.width; // in case of a '' entry.\r\n }\r\n if(!cookie.height) {\r\n delete cookie.height; // in case of a '' entry.\r\n }\r\n\r\n return cookie;\r\n }\r\n\r\n save(cookie: Required) {\r\n super.save(cookie);\r\n }\r\n}", + "import { Codes, DeviceSpec, ManagedPromise, Version } from '@keymanapp/keyboard-processor';\r\nimport { getAbsoluteX, getAbsoluteY, landscapeView } from 'keyman/engine/dom-utils';\r\nimport { EmitterListenerSpy, LegacyEventMap } from 'keyman/engine/events';\r\n\r\nimport OSKView, { EventMap, type LegacyOSKEventMap, OSKPos, OSKRect } from './oskView.js';\r\nimport TitleBar from '../components/titleBar.js';\r\nimport ResizeBar from '../components/resizeBar.js';\r\n\r\nimport MouseDragOperation from '../input/mouseDragOperation.js';\r\nimport { getViewportScale } from '../screenUtils.js';\r\nimport Configuration from '../config/viewConfiguration.js';\r\nimport TwoStateActivator from './twoStateActivator.js';\r\nimport { FloatingOSKCookie, FloatingOSKCookieSerializer } from './floatingOskCookie.js';\r\n\r\n/***\r\n KeymanWeb 10.0\r\n Copyright 2017 SIL International\r\n***/\r\n\r\nexport interface FloatingOSKViewConfiguration extends Configuration {\r\n activator?: TwoStateActivator;\r\n}\r\n\r\nexport default class FloatingOSKView extends OSKView {\r\n // OSK positioning fields\r\n userPositioned: boolean = false;\r\n specifiedPosition: boolean = false;\r\n x: number;\r\n y: number;\r\n noDrag: boolean = false;\r\n dfltX: string;\r\n dfltY: string;\r\n\r\n layoutSerializer = new FloatingOSKCookieSerializer();\r\n\r\n private titleBar: TitleBar;\r\n private resizeBar: ResizeBar;\r\n\r\n // Encapsulations of the drag behaviors for OSK movement & resizing\r\n private _moveHandler: MouseDragOperation;\r\n private _resizeHandler: MouseDragOperation;\r\n\r\n public constructor(config: FloatingOSKViewConfiguration) {\r\n config.activator = config.activator || new TwoStateActivator();\r\n\r\n super(config);\r\n\r\n this.typedActivationModel.on('triggerchange', () => this.setDisplayPositioning());\r\n\r\n document.body.appendChild(this._Box);\r\n\r\n // Add header element to OSK only for desktop browsers\r\n this.titleBar = new TitleBar(this.titleDragHandler);\r\n this.titleBar.on('help', () => {\r\n this.legacyEvents.callEvent('helpclick', {});\r\n });\r\n this.titleBar.on('config', () => {\r\n this.legacyEvents.callEvent('configclick', {});\r\n });\r\n this.titleBar.on('close', () => this.startHide(true));\r\n this.titleBar.on('unpin', () => this.restorePosition(true));\r\n\r\n this.resizeBar = new ResizeBar(this.resizeDragHandler);\r\n this.resizeBar.on('showbuild', () => this.emit('showbuild'));\r\n\r\n this.headerView = this.titleBar;\r\n\r\n const onListenedEvent = (eventName: keyof EventMap | keyof LegacyOSKEventMap) => {\r\n // As the following title bar buttons (for desktop / FloatingOSKView) do nothing unless a site\r\n // designer uses these events, we disable / hide them unless an event-handler is attached.\r\n let titleBar = this.headerView;\r\n if(titleBar && titleBar instanceof TitleBar) {\r\n switch(eventName) {\r\n case 'configclick':\r\n titleBar.configEnabled = this.legacyEvents.listenerCount('configclick') > 0;\r\n break;\r\n case 'helpclick':\r\n titleBar.helpEnabled = this.legacyEvents.listenerCount('helpclick') > 0;\r\n break;\r\n default:\r\n return;\r\n }\r\n }\r\n }\r\n\r\n const listenerSpyNew = new EmitterListenerSpy(this);\r\n const listenerSpyOld = new EmitterListenerSpy(this.legacyEvents);\r\n for(let listenerSpy of [listenerSpyNew, listenerSpyOld]) {\r\n listenerSpy.on('listeneradded', onListenedEvent);\r\n listenerSpy.on('listenerremoved', onListenedEvent);\r\n }\r\n\r\n this.loadPersistedLayout();\r\n }\r\n\r\n private get typedActivationModel(): TwoStateActivator {\r\n return this.activationModel as TwoStateActivator;\r\n }\r\n\r\n /**\r\n * Function _Unload\r\n * Scope Private\r\n * Description Clears OSK variables prior to exit (JMD 1.9.1 - relocation of local variables 3/9/10)\r\n */\r\n _Unload() {\r\n this.keyboardView = null;\r\n this.bannerView = null;\r\n this._Box = null;\r\n }\r\n\r\n protected setBoxStyling() {\r\n const s = this._Box.style;\r\n\r\n s.zIndex = '9999';\r\n s.display = 'none';\r\n s.width = 'auto';\r\n s.position = 'absolute';\r\n }\r\n\r\n protected postKeyboardAdjustments() {\r\n // Add header element to OSK only for desktop browsers\r\n this.enableMoveResizeHandlers();\r\n if(this.activeKeyboard) {\r\n this.titleBar.setTitleFromKeyboard(this.activeKeyboard.keyboard);\r\n }\r\n\r\n if(this.vkbd) {\r\n this.footerView = this.resizeBar;\r\n this._Box.appendChild(this.footerView.element);\r\n } else {\r\n if(this.footerView) {\r\n this._Box.removeChild(this.footerView.element);\r\n }\r\n this.footerView = null;\r\n }\r\n\r\n this.loadPersistedLayout();\r\n this.setNeedsLayout();\r\n }\r\n\r\n /**\r\n * Function restorePosition\r\n * Scope Public\r\n * @param {boolean?} keepDefaultPosition If true, does not reset the default x,y set by `setRect`.\r\n * If false or omitted, resets the default x,y as well.\r\n * Description Move OSK back to default position, floating under active input element\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/restorePosition\r\n */\r\n public restorePosition: (keepDefaultPosition?: boolean) => void = function(this: FloatingOSKView, keepDefaultPosition?: boolean) {\r\n let isVisible = this._Visible;\r\n\r\n let dragPromise = new ManagedPromise();\r\n this.emit('dragmove', dragPromise.corePromise);\r\n\r\n this.loadPersistedLayout();\r\n this.userPositioned=false;\r\n if(!keepDefaultPosition) {\r\n delete this.dfltX;\r\n delete this.dfltY;\r\n }\r\n this.savePersistedLayout();\r\n\r\n if(isVisible) {\r\n this.present();\r\n }\r\n\r\n this.titleBar.showPin(false);\r\n dragPromise.resolve();\r\n this.doResizeMove(); //allow the UI to respond to OSK movements\r\n }.bind(this);\r\n\r\n /**\r\n * Function enabled\r\n * Scope Public\r\n * @return {boolean|number} True if KMW OSK enabled\r\n * Description Test if KMW OSK is enabled\r\n */\r\n ['isEnabled'](): boolean {\r\n return this.displayIfActive;\r\n }\r\n\r\n /**\r\n * Function isVisible\r\n * Scope Public\r\n * @return {boolean|number} True if KMW OSK visible\r\n * Description Test if KMW OSK is actually visible\r\n * Note that this will usually return false after any UI event that results in (temporary) loss of input focus\r\n */\r\n ['isVisible'](): boolean {\r\n return this._Visible;\r\n }\r\n\r\n /**\r\n * Save size, position, font size and visibility of OSK\r\n */\r\n private savePersistedLayout() {\r\n var p = this.getPos();\r\n\r\n const c: FloatingOSKCookie = {\r\n visible: this.displayIfActive ? 1 : 0,\r\n userSet: this.userPositioned ? 1 : 0,\r\n left: p.left,\r\n top: p.top,\r\n _version: Version.CURRENT.toString()\r\n }\r\n\r\n if(this.vkbd) {\r\n c.width = this.width.val;\r\n c.height = this.height.val;\r\n }\r\n\r\n this.layoutSerializer.save(c as Required);\r\n }\r\n\r\n /**\r\n * Restore size, position, font size and visibility of desktop OSK\r\n *\r\n * @return {boolean}\r\n */\r\n private loadPersistedLayout(): void {\r\n let c = this.layoutSerializer.loadWithDefaults({\r\n visible: 1,\r\n userSet: 0,\r\n left: -1,\r\n top: -1,\r\n _version: undefined,\r\n width: 0.3*screen.width,\r\n height: 0.15*screen.height\r\n });\r\n\r\n this.activationModel.enabled = c.visible == 1;\r\n this.userPositioned = c.userSet == 1;\r\n this.x = c.left;\r\n this.y = c.top;\r\n const cookieVersionString = c._version;\r\n\r\n // Restore OSK size - font size now fixed in relation to OSK height, unless overridden (in em) by keyboard\r\n const isNewCookie = cookieVersionString === undefined;\r\n let newWidth = c.width;\r\n let newHeight = c.height;\r\n\r\n // Limit the OSK dimensions to reasonable values\r\n if(newWidth < 0.2*screen.width) {\r\n newWidth = 0.2*screen.width;\r\n }\r\n if(newHeight < 0.1*screen.height) {\r\n newHeight = 0.1*screen.height;\r\n }\r\n if(newWidth > 0.9*screen.width) {\r\n newWidth=0.9*screen.width;\r\n }\r\n if(newHeight > 0.5*screen.height) {\r\n newHeight=0.5*screen.height;\r\n }\r\n\r\n // if(!cookieVersionString) - this component was not tracked until 15.0.\r\n // Before that point, the OSK's title bar and resize bar heights were not included\r\n // in the OSK's cookie-persisted height.\r\n if(isNewCookie || !cookieVersionString) {\r\n // Adds some space to account for the OSK's header and footer, should they exist.\r\n if(this.headerView && this.headerView.layoutHeight.absolute) {\r\n newHeight += this.headerView.layoutHeight.val;\r\n }\r\n\r\n if(this.footerView && this.footerView.layoutHeight.absolute) {\r\n newHeight += this.footerView.layoutHeight.val;\r\n }\r\n }\r\n\r\n this.setSize(newWidth, newHeight);\r\n\r\n // and OSK position if user located\r\n if(this.x == -1 || this.y == -1 || (!this._Box)) {\r\n this.userPositioned = false;\r\n }\r\n\r\n if(this.x < window.pageXOffset-0.8*newWidth) {\r\n this.x=window.pageXOffset-0.8*newWidth;\r\n }\r\n if(this.y < 0) {\r\n this.x=-1;\r\n this.y=-1;\r\n this.userPositioned=false;\r\n }\r\n\r\n if(this.userPositioned && this._Box) {\r\n this.setPos({'left': this.x, 'top': this.y});\r\n }\r\n }\r\n\r\n /**\r\n * Get the wanted height of the OSK for touch devices (does not include banner height)\r\n * @return {number} height in pixels\r\n **/\r\n getDefaultKeyboardHeight(): number {\r\n // KeymanTouch - get OSK height from device\r\n if(this.configuration.heightOverride) {\r\n return this.configuration.heightOverride();\r\n }\r\n\r\n var oskHeightLandscapeView=Math.floor(Math.min(screen.availHeight,screen.availWidth)/2),\r\n height=oskHeightLandscapeView;\r\n\r\n if(this.targetDevice.formFactor == 'phone') {\r\n var sx=Math.min(screen.height,screen.width),\r\n sy=Math.max(screen.height,screen.width);\r\n\r\n if(!landscapeView())\r\n height=Math.floor(Math.max(screen.availHeight,screen.availWidth)/3);\r\n else\r\n height=height*(sy/sx)/1.6; //adjust for aspect ratio, increase slightly for iPhone 5\r\n }\r\n\r\n // Correct for viewport scaling (iOS - Android 4.2 does not want this, at least on Galaxy Tab 3))\r\n if(this.targetDevice.OS == DeviceSpec.OperatingSystem.iOS) {\r\n height=height/getViewportScale();\r\n }\r\n\r\n return height;\r\n }\r\n\r\n /**\r\n * Get the wanted width of the OSK for touch devices\r\n *\r\n * @return {number} height in pixels\r\n **/\r\n getDefaultWidth(): number {\r\n // KeymanTouch - get OSK height from device\r\n if(this.configuration.widthOverride) {\r\n return this.configuration.widthOverride();\r\n }\r\n\r\n var width: number;\r\n if(this.targetDevice.OS == DeviceSpec.OperatingSystem.iOS) {\r\n // iOS does not interchange these values when the orientation changes!\r\n //width = util.portraitView() ? screen.width : screen.height;\r\n width = window.innerWidth;\r\n } else if(this.targetDevice.OS == DeviceSpec.OperatingSystem.Android) {\r\n try {\r\n width=document.documentElement.clientWidth;\r\n } catch(ex) {\r\n width=screen.availWidth;\r\n }\r\n } else {\r\n width=screen.width;\r\n }\r\n\r\n return width;\r\n }\r\n\r\n /**\r\n * Allow UI to update OSK position and properties\r\n *\r\n * @param {Object=} p object with coordinates and userdefined flag\r\n *\r\n */\r\n doResizeMove(p?) {\r\n this.legacyEvents.callEvent('resizemove', p);\r\n }\r\n\r\n /**\r\n * Allow the UI or page to set the position and size of the OSK\r\n * and (optionally) override user repositioning or sizing\r\n *\r\n * @param {Object.} p Array object with position and size of OSK container\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/setRect\r\n **/\r\n public setRect(p: OSKRect) {\r\n if(this._Box == null || this.targetDevice.formFactor != 'desktop') {\r\n return;\r\n }\r\n\r\n var b = this._Box, bs = b.style;\r\n if('left' in p) {\r\n this.x = p['left'] - getAbsoluteX(b) + b.offsetLeft;\r\n bs.left= this.x + 'px';\r\n this.dfltX=bs.left;\r\n }\r\n\r\n if('top' in p) {\r\n this.y = p['top'] - getAbsoluteY(b) + b.offsetTop;\r\n bs.top = this.y + 'px';\r\n this.dfltY=bs.top;\r\n }\r\n\r\n //Do not allow user resizing for non-standard keyboards (e.g. EuroLatin)\r\n if(this.vkbd != null) {\r\n var d=this.vkbd.kbdDiv, ds=d.style;\r\n\r\n // Set width, but limit to reasonable value\r\n if('width' in p) {\r\n var w=(p['width']-(b.offsetWidth-d.offsetWidth));\r\n if(w < 0.2*screen.width) {\r\n w=0.2*screen.width;\r\n }\r\n if(w > 0.9*screen.width) {\r\n w=0.9*screen.width;\r\n }\r\n ds.width=w+'px';\r\n // Use of the `computed` variant is here temporary.\r\n // Shouldn't use `setSize` for this in the long-term.\r\n this.setSize(w, this.computedHeight, true);\r\n }\r\n\r\n // Set height, but limit to reasonable value\r\n // This sets the default font size for the OSK in px, but that\r\n // can be modified at the key text level by setting\r\n // the font size in em in the kmw-key-text class\r\n if('height' in p) {\r\n var h=(p['height']-(b.offsetHeight-d.offsetHeight));\r\n if(h < 0.1*screen.height) {\r\n h=0.1*screen.height;\r\n }\r\n if(h > 0.5*screen.height) {\r\n h=0.5*screen.height;\r\n }\r\n ds.height=h+'px'; ds.fontSize=(h/8)+'px';\r\n // Use of the `computed` variant is here temporary.\r\n // Shouldn't use `setSize` for this in the long-term.\r\n this.setSize(this.computedWidth, h, true);\r\n }\r\n\r\n // Fix or release user resizing\r\n if('nosize' in p) {\r\n this.resizingEnabled = !p['nosize'];\r\n }\r\n\r\n }\r\n // Fix or release user dragging\r\n if('nomove' in p) {\r\n this.noDrag=p['nomove'];\r\n this.movementEnabled = !this.noDrag;\r\n }\r\n // Save the user-defined OSK size\r\n this.savePersistedLayout();\r\n }\r\n\r\n /**\r\n * Get position of OSK window\r\n *\r\n * @return {Object.} Array object with OSK window position\r\n **/\r\n getPos(): OSKPos {\r\n var Lkbd=this._Box, p={\r\n left: this._Visible ? Lkbd.offsetLeft : this.x,\r\n top: this._Visible ? Lkbd.offsetTop : this.y\r\n };\r\n\r\n return p;\r\n }\r\n\r\n /**\r\n * Function setPos\r\n * Scope Private\r\n * @param {Object.} p Array object with OSK left, top\r\n * Description Set position of OSK window, but limit to screen\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/setPos\r\n */\r\n public setPos(p: OSKPos) {\r\n if(typeof(this._Box) == 'undefined') {\r\n return; // I3363 (Build 301)\r\n }\r\n\r\n if(this.userPositioned) {\r\n var Px=p['left'], Py=p['top'];\r\n\r\n if(typeof(Px) != 'undefined') {\r\n if(Px < -0.8*this._Box.offsetWidth) {\r\n Px = -0.8*this._Box.offsetWidth;\r\n }\r\n if(this.userPositioned) {\r\n this._Box.style.left=Px+'px';\r\n this.x = Px;\r\n }\r\n }\r\n // May not be needed - vertical positioning is handled differently and defaults to input field if off screen\r\n if(typeof(Py) != 'undefined') {\r\n if(Py < 0) {\r\n Py = 0;\r\n }\r\n\r\n if(this.userPositioned) {\r\n this._Box.style.top=Py+'px';\r\n this.y = Py;\r\n }\r\n }\r\n }\r\n\r\n this.titleBar.showPin(this.userPositioned);\r\n }\r\n\r\n public setDisplayPositioning() {\r\n var Ls = this._Box.style;\r\n\r\n Ls.position='absolute';\r\n // Keep it hidden if not currently displayed.\r\n if(this.activationModel.activate) {\r\n Ls.display='block'; //Ls.visibility='visible';\r\n }\r\n Ls.left='0px';\r\n if(this.specifiedPosition || this.userPositioned) {\r\n Ls.left = this.x+'px';\r\n Ls.top = this.y+'px';\r\n } else {\r\n let el: HTMLElement = this.typedActivationModel.activationTrigger || null;\r\n\r\n if(this.dfltX) {\r\n Ls.left=this.dfltX;\r\n } else if(typeof el != 'undefined' && el != null) {\r\n Ls.left=getAbsoluteX(el) + 'px';\r\n }\r\n\r\n if(this.dfltY) {\r\n Ls.top=this.dfltY;\r\n } else if(typeof el != 'undefined' && el != null) {\r\n Ls.top=(getAbsoluteY(el) + el.offsetHeight)+'px';\r\n }\r\n }\r\n\r\n // Unset the flag, keeping 'specified position' specific to single\r\n // presentAtPosition calls.\r\n this.specifiedPosition = false;\r\n }\r\n\r\n /**\r\n * Display KMW OSK at specified position (returns nothing)\r\n *\r\n * @param {number=} Px x-coordinate for OSK rectangle\r\n * @param {number=} Py y-coordinate for OSK rectangle\r\n */\r\n presentAtPosition(Px?: number, Py?: number) {\r\n if(!this.mayShow()) {\r\n return;\r\n }\r\n\r\n this.specifiedPosition = Px >= 0 || Py >= 0; //probably never happens, legacy support only\r\n if(this.specifiedPosition) {\r\n this.x = Px;\r\n this.y = Py;\r\n }\r\n\r\n // Combines the two paths with set positioning.\r\n this.specifiedPosition = this.specifiedPosition || this.userPositioned;\r\n\r\n this.present();\r\n }\r\n\r\n present() {\r\n if(!this.mayShow()) {\r\n return;\r\n }\r\n\r\n this.titleBar.showPin(this.userPositioned);\r\n\r\n super.present();\r\n\r\n // Allow desktop UI to execute code when showing the OSK\r\n var Lpos={};\r\n Lpos['x']=this._Box.offsetLeft;\r\n Lpos['y']=this._Box.offsetTop;\r\n Lpos['userLocated']=this.userPositioned;\r\n this.doShow(Lpos);\r\n }\r\n\r\n public startHide(hiddenByUser: boolean) {\r\n super.startHide(hiddenByUser);\r\n\r\n if(hiddenByUser) {\r\n this.savePersistedLayout(); // Save current OSK state, size and position (desktop only)\r\n }\r\n }\r\n\r\n ['show'](bShow?: boolean) {\r\n if(bShow !== undefined) {\r\n super['show'](bShow);\r\n } else {\r\n super['show']();\r\n }\r\n this.savePersistedLayout();\r\n }\r\n\r\n /**\r\n * Function userPositioned\r\n * Scope Public\r\n * @return {(boolean|number)} true if user located\r\n * Description Test if OSK window has been repositioned by user\r\n *\r\n * See https://help.keyman.com/developer/engine/web/current-version/reference/osk/userLocated\r\n */\r\n public userLocated() {\r\n return this.userPositioned;\r\n }\r\n\r\n public get movementEnabled(): boolean {\r\n return this.titleDragHandler.enabled;\r\n }\r\n\r\n public set movementEnabled(flag: boolean) {\r\n this.titleDragHandler.enabled = flag;\r\n this.titleBar.showPin(flag && this.userPositioned);\r\n }\r\n\r\n public get resizingEnabled(): boolean {\r\n return this.resizeDragHandler.enabled;\r\n }\r\n\r\n public set resizingEnabled(flag: boolean) {\r\n this.resizeDragHandler.enabled = flag;\r\n this.resizeBar.allowResizing(flag);\r\n }\r\n\r\n public get isBeingMoved(): boolean {\r\n return this.titleDragHandler.isActive;\r\n }\r\n\r\n public get isBeingResized(): boolean {\r\n return this.resizeDragHandler.isActive;\r\n }\r\n\r\n private enableMoveResizeHandlers() {\r\n this.titleDragHandler.enabled = !this.noDrag;\r\n this.resizeDragHandler.enabled = true; // by default.\r\n }\r\n\r\n private get titleDragHandler(): MouseDragOperation {\r\n const _this = this;\r\n\r\n if(this._moveHandler) {\r\n return this._moveHandler;\r\n }\r\n\r\n this._moveHandler = new class extends MouseDragOperation {\r\n startX: number;\r\n startY: number;\r\n\r\n dragPromise: ManagedPromise;\r\n\r\n constructor() {\r\n super('move'); // The type of cursor to use while 'active'.\r\n }\r\n\r\n onDragStart() {\r\n this.startX = _this._Box.offsetLeft;\r\n this.startY = _this._Box.offsetTop;\r\n\r\n if(_this.activeKeyboard.keyboard.isCJK) {\r\n _this.titleBar.setPinCJKOffset();\r\n }\r\n\r\n if(this.dragPromise) {\r\n // We got interrupted during the previous one; allow it to reset, at least!\r\n this.dragPromise.resolve();\r\n }\r\n\r\n this.dragPromise = new ManagedPromise();\r\n _this.emit('dragmove', this.dragPromise.corePromise);\r\n }\r\n\r\n onDragMove(cumulativeX: number, cumulativeY: number) {\r\n _this.titleBar.showPin(true);\r\n _this.userPositioned = true;\r\n\r\n _this._Box.style.left = (this.startX + cumulativeX) + 'px';\r\n _this._Box.style.top = (this.startY + cumulativeY) + 'px';\r\n\r\n var r=_this.getRect();\r\n _this.setSize(r.width, r.height, true);\r\n _this.x = r.left;\r\n _this.y = r.top;\r\n }\r\n\r\n onDragRelease() {\r\n if(_this.vkbd) {\r\n _this.vkbd.currentKey=null;\r\n }\r\n\r\n this.dragPromise.resolve();\r\n\r\n // Remainder should be done after anything else pending on the Promise.\r\n this.dragPromise.then(() => {\r\n _this.userPositioned = true;\r\n _this.doResizeMove();\r\n _this.savePersistedLayout();\r\n });\r\n this.dragPromise = null;\r\n }\r\n }\r\n\r\n return this._moveHandler;\r\n }\r\n\r\n private get resizeDragHandler(): MouseDragOperation {\r\n const _this = this;\r\n\r\n if(this._resizeHandler) {\r\n return this._resizeHandler;\r\n }\r\n\r\n this._resizeHandler = new class extends MouseDragOperation {\r\n startWidth: number;\r\n startHeight: number;\r\n\r\n dragPromise: ManagedPromise;\r\n\r\n constructor() {\r\n super('se-resize'); // The type of cursor to use while 'active'.\r\n }\r\n\r\n onDragStart() {\r\n this.startWidth = _this.computedWidth;\r\n this.startHeight = _this.computedHeight;\r\n\r\n if(this.dragPromise) {\r\n // We got interrupted during the previous one; allow it to reset, at least!\r\n this.dragPromise.resolve();\r\n }\r\n\r\n this.dragPromise = new ManagedPromise();\r\n _this.emit('resizemove', this.dragPromise.corePromise);\r\n }\r\n\r\n onDragMove(cumulativeX: number, cumulativeY: number) {\r\n let newWidth = this.startWidth + cumulativeX;\r\n let newHeight = this.startHeight + cumulativeY;\r\n\r\n // Set the smallest and largest OSK size\r\n if(newWidth < 0.2*screen.width) {\r\n newWidth = 0.2*screen.width;\r\n }\r\n if(newHeight < 0.1*screen.height) {\r\n newHeight = 0.1*screen.height;\r\n }\r\n if(newWidth > 0.9*screen.width) {\r\n newWidth = 0.9*screen.width;\r\n }\r\n if(newHeight > 0.5*screen.height) {\r\n newHeight = 0.5*screen.height;\r\n }\r\n\r\n // Explicitly set OSK width, height, and font size - cannot safely rely on scaling from font\r\n _this.setSize(newWidth, newHeight, true);\r\n }\r\n\r\n onDragRelease() {\r\n if(_this.vkbd) {\r\n _this.vkbd.currentKey=null;\r\n }\r\n\r\n if(_this.vkbd) {\r\n this.startWidth = _this.computedWidth;\r\n this.startHeight = _this.computedHeight;\r\n }\r\n\r\n _this.refreshLayout(); // Finalize the resize.\r\n\r\n this.dragPromise.resolve();\r\n\r\n // Remainder should be done after anything else pending on the Promise.\r\n this.dragPromise.then(() => {\r\n _this.doResizeMove();\r\n _this.savePersistedLayout();\r\n });\r\n this.dragPromise = null;\r\n }\r\n }\r\n\r\n return this._resizeHandler;\r\n }\r\n}\r\n", + "import { Codes, DeviceSpec } from '@keymanapp/keyboard-processor';\r\nimport { landscapeView } from 'keyman/engine/dom-utils';\r\n\r\nimport OSKView, { OSKPos, OSKRect } from './oskView.js';\r\nimport { getViewportScale } from '../screenUtils.js';\r\nimport Configuration from '../config/viewConfiguration.js';\r\nimport { StaticActivator } from './activator.js';\r\nimport TwoStateActivator from './twoStateActivator.js';\r\n\r\n/***\r\n KeymanWeb 10.0\r\n Copyright 2017 SIL International\r\n***/\r\n\r\nexport default class AnchoredOSKView extends OSKView {\r\n\r\n // OSK positioning fields\r\n x: number;\r\n y: number;\r\n\r\n private isResizing: boolean = false;\r\n\r\n public constructor(config: Configuration) {\r\n if(config.isEmbedded) {\r\n config.activator = config.activator || new StaticActivator();\r\n } else {\r\n config.activator = config.activator || new TwoStateActivator();\r\n }\r\n super(config);\r\n\r\n document.body.appendChild(this._Box);\r\n\r\n }\r\n\r\n /**\r\n * Function _Unload\r\n * Scope Private\r\n * Description Clears OSK variables prior to exit (JMD 1.9.1 - relocation of local variables 3/9/10)\r\n */\r\n _Unload() {\r\n this.keyboardView = null;\r\n this.bannerView = null;\r\n this._Box = null;\r\n }\r\n\r\n protected setBoxStyling() {\r\n const s = this._Box.style;\r\n\r\n s.zIndex = '9999';\r\n s.display = 'none';\r\n s.width = '100%';\r\n s.position = 'fixed';\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public refreshLayout(pending?: boolean): void {\r\n // This function is generally triggered whenever the OSK's dimensions change, among other\r\n // things.\r\n if(this.isResizing) {\r\n return;\r\n }\r\n\r\n try {\r\n this.isResizing = true;\r\n // This resizes the OSK to what is appropriate for the device's current orientation,\r\n // which will often trigger a resize event... which in turn triggers a layout refresh.\r\n //\r\n // So, we mark and unmark the `isResizing` flag to prevent triggering a circular\r\n // call-stack chain from this call.\r\n this.doResize();\r\n } finally {\r\n this.isResizing = false;\r\n }\r\n super.refreshLayout(pending);\r\n }\r\n\r\n protected doResize() {\r\n if(this.vkbd) {\r\n let targetOSKHeight = this.getDefaultKeyboardHeight();\r\n this.setSize(this.getDefaultWidth(), targetOSKHeight + this.banner.height);\r\n }\r\n }\r\n\r\n protected postKeyboardAdjustments() {\r\n // Initializes the size of a touch keyboard.\r\n this.doResize();\r\n }\r\n\r\n /**\r\n * Function restorePosition\r\n * Scope Public\r\n * @param {boolean?} keepDefaultPosition If true, does not reset the default x,y set by `setRect`.\r\n * If false or omitted, resets the default x,y as well.\r\n * Description Move OSK back to default position, floating under active input element\r\n */\r\n ['restorePosition']: (keepDefaultPosition?: boolean) => void = function(this: AnchoredOSKView, keepDefaultPosition?: boolean) {\r\n return;\r\n }.bind(this);\r\n\r\n /**\r\n * Get the wanted height of the OSK for touch devices (does not include banner height)\r\n * @return {number} height in pixels\r\n **/\r\n getDefaultKeyboardHeight(): number {\r\n let device = this.targetDevice;\r\n\r\n // KeymanTouch - get OSK height from device\r\n if(this.configuration.heightOverride) {\r\n return this.configuration.heightOverride();\r\n }\r\n\r\n /*\r\n * We've noticed some fairly inconsistent behavior in the past when attempting to base\r\n * this logic on window.innerWidth/Height, as there can be very unexpected behavior\r\n * on mobile devices during and after rotation.\r\n *\r\n * Online forums (such as https://stackoverflow.com/a/54812656) seem to indicate that\r\n * document.documentElement.clientWidth/Height seem to be the most stable analogues\r\n * to a window's size in the situations where it matters for Keyman Engine for Web.\r\n *\r\n * That said, an important note: this gets the dimensions of the _document element_,\r\n * not the screen or even the window.\r\n */\r\n let baseWidth = document?.documentElement?.clientWidth;\r\n let baseHeight = document?.documentElement?.clientHeight;\r\n if(typeof baseWidth == 'undefined') {\r\n /*\r\n * Fallback logic. We _shouldn't_ need this, but it's best to have _something_\r\n * for the sake of robustness.\r\n */\r\n baseWidth = Math.min(screen.height, screen.width);\r\n baseHeight = Math.max(screen.height, screen.width);\r\n\r\n if(landscapeView()) {\r\n let temp = baseWidth;\r\n baseWidth = baseHeight;\r\n baseHeight = temp;\r\n }\r\n }\r\n\r\n var oskHeightLandscapeView=Math.floor(Math.min(baseHeight, baseWidth)/2),\r\n height=oskHeightLandscapeView;\r\n\r\n if(device.formFactor == 'phone') {\r\n /**\r\n * Assuming the first-pass detection of width and height work correctly, note\r\n * that these calculations are based on the document's size, not the device's\r\n * resolution. This _particularly_ matters for height.\r\n *\r\n * - Is the mobile-device browser showing a URL bar? That's not included.\r\n * - The standard signal-strength, battery-strength, etc device status bar?\r\n * Also not included.\r\n */\r\n if(!landscapeView())\r\n height=Math.floor(baseHeight/2.4);\r\n else\r\n height=Math.floor(baseHeight/1.6); //adjust for aspect ratio, increase slightly for iPhone 5\r\n }\r\n\r\n // Correct for viewport scaling (iOS - Android 4.2 does not want this, at least on Galaxy Tab 3))\r\n if(this.targetDevice.OS == DeviceSpec.OperatingSystem.iOS) {\r\n height=height/getViewportScale();\r\n }\r\n\r\n return height;\r\n }\r\n\r\n /**\r\n * Get the wanted width of the OSK for touch devices\r\n *\r\n * @return {number} height in pixels\r\n **/\r\n getDefaultWidth(): number {\r\n let device = this.targetDevice;\r\n\r\n // KeymanTouch - get OSK height from device\r\n if(this.configuration.widthOverride) {\r\n return this.configuration.widthOverride();\r\n }\r\n\r\n var width: number;\r\n\r\n width = document?.documentElement?.clientWidth;\r\n if(typeof width == 'undefined') {\r\n if(this.targetDevice.OS == DeviceSpec.OperatingSystem.iOS) {\r\n width = window.innerWidth;\r\n } else if(device.OS == DeviceSpec.OperatingSystem.Android) {\r\n width=screen.availWidth;\r\n } else {\r\n width=screen.width;\r\n }\r\n }\r\n\r\n return width;\r\n }\r\n\r\n /**\r\n * Allow the UI or page to set the position and size of the OSK\r\n * and (optionally) override user repositioning or sizing\r\n *\r\n * @param {Object.} p Array object with position and size of OSK container\r\n **/\r\n ['setRect'](p: OSKRect) {\r\n return;\r\n }\r\n\r\n /**\r\n * Get position of OSK window\r\n *\r\n * @return {Object.} Array object with OSK window position\r\n **/\r\n getPos(): OSKPos {\r\n var Lkbd=this._Box, p={\r\n left: this._Visible ? Lkbd.offsetLeft : this.x,\r\n top: this._Visible ? Lkbd.offsetTop : this.y\r\n };\r\n\r\n return p;\r\n }\r\n\r\n /**\r\n * Function setPos\r\n * Scope Private\r\n * @param {Object.} p Array object with OSK left, top\r\n * Description Set position of OSK window, but limit to screen, and ignore if a touch input device\r\n */\r\n ['setPos'](p: OSKPos) {\r\n return; // I3363 (Build 301)\r\n }\r\n\r\n protected setDisplayPositioning() {\r\n let Ls = this._Box.style;\r\n\r\n // The following code will always be executed except for externally created OSK such as EuroLatin\r\n if(this.vkbd) {\r\n Ls.position='fixed';\r\n Ls.left=Ls.bottom='0px';\r\n Ls.border='none';\r\n Ls.borderTop='1px solid gray';\r\n }\r\n }\r\n\r\n public present() {\r\n super.present();\r\n this.legacyEvents.callEvent('show', {});\r\n }\r\n}\r\n", + "import Activator from './activator.js';\r\n\r\nexport default class SimpleActivator extends Activator {\r\n private flag: boolean = true;\r\n\r\n get enabled(): boolean {\r\n return this.flag;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n // Enabled + activated are the same thing for this class.\r\n this.activate = value;\r\n }\r\n\r\n get activate(): boolean {\r\n return this.flag;\r\n }\r\n\r\n set activate(value: boolean) {\r\n if(this.flag != value) {\r\n this.flag = value;\r\n this.emit('activate', value);\r\n }\r\n }\r\n\r\n get conditionsMet(): boolean {\r\n return true;\r\n }\r\n}", + "import { Codes, DeviceSpec } from '@keymanapp/keyboard-processor';\r\n\r\nimport OSKView, { OSKPos, OSKRect } from './oskView.js';\r\nimport VisualKeyboard from '../visualKeyboard.js';\r\nimport Configuration from '../config/viewConfiguration.js';\r\nimport SimpleActivator from './simpleActivator.js';\r\n\r\n/*\r\n * Keyman is copyright (c) SIL International. MIT License.\r\n */\r\n\r\n/**\r\n * Defines a version of the OSK that produces an element designed for site-controlled\r\n * insertion into the DOM. Rather than \"floating\" over the page, this version is inlined\r\n * as part of the host page's layout.\r\n */\r\nexport default class InlinedOSKView extends OSKView {\r\n public constructor(config: Configuration) {\r\n config.activator = config.activator || new SimpleActivator();\r\n super(config);\r\n }\r\n\r\n public get element(): HTMLDivElement {\r\n return this._Box;\r\n }\r\n\r\n /**\r\n * Clears OSK variables prior to exit (JMD 1.9.1 - relocation of local variables 3/9/10)\r\n *\r\n * This should probably be merged or incorporated into the `shutdown` method at some point.\r\n */\r\n _Unload() {\r\n this.keyboardView = null;\r\n this.bannerView = null;\r\n this._Box = null;\r\n }\r\n\r\n protected setBoxStyling() {\r\n const s = this._Box.style;\r\n s.display = 'none';\r\n // Positioned with no relative offset from its default position.\r\n // This allows _Box to still serve as an offsetParent for keytip & subkey menu positioning.\r\n s.position = 'relative';\r\n }\r\n\r\n protected postKeyboardAdjustments() {\r\n }\r\n\r\n /**\r\n * Moves the OSK back to default position, floating under active input element\r\n *\r\n * Is a long-published API intended solely for use with the FloatingOSKView use pattern.\r\n * @param keepDefaultPosition If true, does not reset the default x,y set by `setRect`.\r\n * If false or omitted, resets the default x,y as well.\r\n */\r\n ['restorePosition']: (keepDefaultPosition?: boolean) => void = function(this: InlinedOSKView, keepDefaultPosition?: boolean) {\r\n return;\r\n }.bind(this);\r\n\r\n /**\r\n * Get the default height for the OSK\r\n * @return height in pixels\r\n **/\r\n getDefaultKeyboardHeight(): number {\r\n if(this.keyboardView instanceof VisualKeyboard) {\r\n return this.keyboardView.height;\r\n } else {\r\n // Should probably refine, but it's a decent stopgap.\r\n return this.computedHeight;\r\n }\r\n }\r\n\r\n /**\r\n * Get the default width for the OSK\r\n * @return width in pixels\r\n **/\r\n getDefaultWidth(): number {\r\n return this.computedWidth;\r\n }\r\n\r\n /**\r\n * Allow the UI or page to set the position and size of the OSK\r\n * and (optionally) override user repositioning or sizing\r\n *\r\n * Designed solely for use with the FloatingOSKView use pattern, but is a\r\n * long-standing API endpoint that needs preservation.\r\n *\r\n * @param p Array object with position and size of OSK container\r\n **/\r\n ['setRect'](p: OSKRect) {\r\n return;\r\n }\r\n\r\n /**\r\n * Get position of OSK window\r\n *\r\n * @return Array object with OSK window position\r\n **/\r\n getPos(): OSKPos {\r\n var Lkbd=this._Box, p={\r\n left: this._Visible ? Lkbd.offsetLeft : undefined,\r\n top: this._Visible ? Lkbd.offsetTop : undefined\r\n };\r\n\r\n return p;\r\n }\r\n\r\n /**\r\n * Set position of OSK window, but limited to the screen.\r\n *\r\n * Designed solely for use with the FloatingOSKView use pattern, but is a\r\n * long-standing API endpoint that needs preservation.\r\n * @param p Array object with OSK left, top\r\n */\r\n ['setPos'](p: OSKPos) {\r\n return; // I3363 (Build 301)\r\n }\r\n\r\n public present() {\r\n super.present();\r\n\r\n this.legacyEvents.callEvent('show', {});\r\n }\r\n\r\n protected setDisplayPositioning() {\r\n // no-op; an inlined OSK cannot control its own positioning.\r\n }\r\n\r\n protected allowsDeviceChange(newSpec: DeviceSpec): boolean {\r\n return true;\r\n }\r\n}\r\n", + "import {\r\n ViewConfiguration,\r\n AnchoredOSKView,\r\n FloatingOSKView,\r\n FloatingOSKViewConfiguration,\r\n InlinedOSKView\r\n} from \"keyman/engine/osk\";\r\nimport KeymanEngine from \"./keymanEngine.js\";\r\n\r\nfunction buildBaseOskConfiguration(engine: KeymanEngine) {\r\n return {\r\n hostDevice: engine.config.hostDevice,\r\n pathConfig: engine.config.paths,\r\n predictionContextManager: engine.contextManager.predictionContext,\r\n isEmbedded: false\r\n };\r\n};\r\n\r\nclass PublishedAnchoredOSKView extends AnchoredOSKView {\r\n constructor(engine: KeymanEngine, config?: ViewConfiguration) {\r\n let finalConfig = {\r\n ...buildBaseOskConfiguration(engine),\r\n ...(config || {})\r\n };\r\n\r\n super(finalConfig);\r\n }\r\n}\r\n\r\nclass PublishedFloatingOSKView extends FloatingOSKView {\r\n constructor(engine: KeymanEngine, config?: FloatingOSKViewConfiguration) {\r\n let finalConfig: FloatingOSKViewConfiguration = {\r\n ...buildBaseOskConfiguration(engine),\r\n ...(config || {})\r\n };\r\n\r\n super(finalConfig);\r\n }\r\n}\r\n\r\nclass PublishedInlineOSKView extends InlinedOSKView {\r\n constructor(engine: KeymanEngine, config?: ViewConfiguration) {\r\n let finalConfig: ViewConfiguration = {\r\n ...buildBaseOskConfiguration(engine),\r\n ...(config || {})\r\n };\r\n\r\n super(finalConfig);\r\n }\r\n}\r\n\r\nexport { PublishedAnchoredOSKView as AnchoredOSKView };\r\nexport { PublishedFloatingOSKView as FloatingOSKView };\r\nexport { PublishedInlineOSKView as InlinedOSKView };\r\n\r\n", + "import { OutputTarget as OutputTargetBase } from \"@keymanapp/keyboard-processor\";\r\nimport EventEmitter from 'eventemitter3';\r\n\r\nexport default abstract class OutputTarget extends OutputTargetBase {\r\n // JS/TS can't do true multiple inheritance, so we maintain class events on a readonly field.\r\n public readonly events: EventEmitter = new EventEmitter();\r\n\r\n /**\r\n * A field that may be used to track whether or not the represented context has changed over an\r\n * arbitrary period of time.\r\n */\r\n public changed = false;\r\n\r\n /**\r\n * Returns the underlying element / document modeled by the wrapper.\r\n */\r\n abstract getElement(): HTMLElement;\r\n\r\n public focus(): void {\r\n const ele = this.getElement();\r\n if(ele.focus) {\r\n ele.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Denotes when the represented element is forcing a text scroll via focus manipulation.\r\n * As the intent is not to change the focused element, but just to have the browser update\r\n * the scroll location, standard focus handlers (for updating the active context) should\r\n * not deactivate the element while this state is active.\r\n */\r\n isForcingScroll(): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * A helper method for doInputEvent; creates a simple common event and default dispatching.\r\n * @param elem\r\n */\r\n protected dispatchInputEventOn(elem: HTMLElement) {\r\n let event: InputEvent;\r\n\r\n // `undefined` in pre-Chrome Edge and Chrome for Android before version 60.\r\n if(window['InputEvent']) { // can't condition on the type directly; TS optimizes that out.\r\n event = new InputEvent('input', {\"bubbles\": true, \"cancelable\": false});\r\n }\r\n\r\n if(elem && event) {\r\n elem.dispatchEvent(event);\r\n }\r\n }\r\n}", + "import OutputTarget from './outputTarget.js';\r\n\r\ninterface EventMap {\r\n /**\r\n * This event will be raised when a newline is received by wrapped elements not of\r\n * the 'search' or 'submit' types.\r\n *\r\n * Original code this is replacing:\r\n ```\r\n // Allows compiling this separately from the main body of KMW.\r\n // TODO: rework class to accept a class-static 'callback' from the DOM module that this can call.\r\n // Would eliminate the need for this 'static' reference.\r\n // Only strongly matters once we better modularize KMW, with web-dom vs web-dom-targets vs web-core, etc.\r\n if(com.keyman[\"singleton\"]) {\r\n com.keyman[\"singleton\"].domManager.moveToNext(false);\r\n }\r\n ```\r\n * This does not belong in a modularized version of this class; it must be supplied\r\n * by the consuming top-level products instead.\r\n */\r\n 'unhandlednewline': (element: HTMLInputElement) => void\r\n}\r\n\r\nexport default class Input extends OutputTarget {\r\n root: HTMLInputElement;\r\n\r\n /**\r\n * Tracks the most recently-cached selection start index.\r\n */\r\n private _cachedSelectionStart: number\r\n\r\n /**\r\n * Tracks the most recently processed, extended-string-based selection start index.\r\n * When the element's selectionStart value changes, this should be invalidated.\r\n */\r\n private processedSelectionStart: number;\r\n\r\n /**\r\n * Tracks the most recently processed, extended-string-based selection end index.\r\n * When the element's selectionEnd value changes, this should be invalidated.\r\n */\r\n private processedSelectionEnd: number;\r\n\r\n /**\r\n * Set, then unset within the `forceScroll` method in order to facilitate the\r\n * `isForcingScroll` flag.\r\n */\r\n private _activeForcedScroll: boolean;\r\n\r\n constructor(ele: HTMLInputElement) {\r\n super();\r\n\r\n this.root = ele;\r\n this._cachedSelectionStart = -1;\r\n }\r\n\r\n get isSynthetic(): boolean {\r\n return false;\r\n }\r\n\r\n getElement(): HTMLInputElement {\r\n return this.root;\r\n }\r\n\r\n clearSelection(): void {\r\n // Processes our codepoint-based variants of selectionStart and selectionEnd.\r\n this.getCaret(); // updates processedSelectionStart if required\r\n this.root.value = this.root.value._kmwSubstring(0, this.processedSelectionStart) + this.root.value._kmwSubstring(this.processedSelectionEnd); //I3319\r\n\r\n this.setCaret(this.processedSelectionStart);\r\n }\r\n\r\n isSelectionEmpty(): boolean {\r\n return this.root.selectionStart == this.root.selectionEnd;\r\n }\r\n\r\n hasSelection(): boolean {\r\n return true;\r\n }\r\n\r\n invalidateSelection() {\r\n // Since .selectionStart will never return this value, we use it to indicate\r\n // the need to refresh our processed indices.\r\n this._cachedSelectionStart = -1;\r\n }\r\n\r\n getCaret(): number {\r\n if(this.root.selectionStart != this._cachedSelectionStart) {\r\n this._cachedSelectionStart = this.root.selectionStart; // KMW-1\r\n this.processedSelectionStart = this.root.value._kmwCodeUnitToCodePoint(this.root.selectionStart); // I3319\r\n this.processedSelectionEnd = this.root.value._kmwCodeUnitToCodePoint(this.root.selectionEnd); // I3319\r\n }\r\n return this.root.selectionDirection == 'forward' ? this.processedSelectionEnd : this.processedSelectionStart;\r\n }\r\n\r\n getDeadkeyCaret(): number {\r\n return this.getCaret();\r\n }\r\n\r\n setCaret(caret: number) {\r\n this.setSelection(caret, caret, \"none\");\r\n }\r\n\r\n setSelection(start: number, end: number, direction: \"forward\" | \"backward\" | \"none\") {\r\n let domStart = this.root.value._kmwCodePointToCodeUnit(start);\r\n let domEnd = this.root.value._kmwCodePointToCodeUnit(end);\r\n this.root.setSelectionRange(domStart, domEnd, direction);\r\n\r\n this.processedSelectionStart = start;\r\n this.processedSelectionEnd = end;\r\n\r\n this.forceScroll();\r\n\r\n this.root.setSelectionRange(domStart, domEnd, direction);\r\n }\r\n\r\n forceScroll() {\r\n // Only executes when com.keyman.DOMEventHandlers is defined.\r\n //\r\n // We bypass this whenever operating in the embedded format.\r\n const element = this.getElement();\r\n\r\n let selectionStart = element.selectionStart;\r\n let selectionEnd = element.selectionEnd;\r\n\r\n this._activeForcedScroll = true;\r\n\r\n try {\r\n //Forces scrolling; the re-focus triggers the scroll, at least.\r\n element.blur();\r\n element.focus();\r\n } finally {\r\n // On Edge, it appears that the blur/focus combination will reset the caret position\r\n // under certain scenarios during unit tests. So, we re-set it afterward.\r\n element.selectionStart = selectionStart;\r\n element.selectionEnd = selectionEnd;\r\n this._activeForcedScroll = false;\r\n }\r\n }\r\n\r\n isForcingScroll(): boolean {\r\n return this._activeForcedScroll;\r\n }\r\n\r\n getSelectionDirection(): \"forward\" | \"backward\" | \"none\" {\r\n return this.root.selectionDirection;\r\n }\r\n\r\n getTextBeforeCaret(): string {\r\n this.getCaret();\r\n return this.getText()._kmwSubstring(0, this.processedSelectionStart);\r\n }\r\n\r\n getSelectedText(): string {\r\n this.getCaret();\r\n return this.getText()._kmwSubstring(this.processedSelectionStart, this.processedSelectionEnd);\r\n }\r\n\r\n setTextBeforeCaret(text: string) {\r\n this.getCaret();\r\n let selectionLength = this.processedSelectionEnd - this.processedSelectionStart;\r\n let direction = this.getSelectionDirection();\r\n let newCaret = text._kmwLength();\r\n this.root.value = text + this.getText()._kmwSubstring(this.processedSelectionStart);\r\n\r\n this.setSelection(newCaret, newCaret + selectionLength, direction);\r\n }\r\n\r\n protected setTextAfterCaret(s: string) {\r\n let c = this.getCaret();\r\n let direction = this.getSelectionDirection();\r\n\r\n this.root.value = this.getTextBeforeCaret() + s;\r\n this.setSelection(this.processedSelectionStart, this.processedSelectionEnd, direction);\r\n }\r\n\r\n getTextAfterCaret(): string {\r\n this.getCaret();\r\n return this.getText()._kmwSubstring(this.processedSelectionEnd);\r\n }\r\n\r\n getText(): string {\r\n return this.root.value;\r\n }\r\n\r\n deleteCharsBeforeCaret(dn: number) {\r\n if(dn > 0) {\r\n let curText = this.getTextBeforeCaret();\r\n let caret = this.processedSelectionStart;\r\n\r\n if(dn > caret) {\r\n dn = caret;\r\n }\r\n\r\n this.adjustDeadkeys(-dn);\r\n this.setTextBeforeCaret(curText.kmwSubstring(0, caret - dn));\r\n this.setCaret(caret - dn);\r\n }\r\n }\r\n\r\n insertTextBeforeCaret(s: string) {\r\n if(!s) {\r\n return;\r\n }\r\n\r\n let caret = this.getCaret();\r\n let front = this.getTextBeforeCaret();\r\n let back = this.getText()._kmwSubstring(this.processedSelectionStart);\r\n\r\n this.adjustDeadkeys(s._kmwLength());\r\n this.root.value = front + s + back;\r\n this.setCaret(caret + s._kmwLength());\r\n }\r\n\r\n handleNewlineAtCaret(): void {\r\n const inputEle = this.root;\r\n // Can't occur for Mocks - just Input types.\r\n if (inputEle && (inputEle.type == 'search' || inputEle.type == 'submit')) {\r\n inputEle.disabled=false;\r\n inputEle.form.submit();\r\n } else {\r\n this.events.emit('unhandlednewline', inputEle);\r\n }\r\n }\r\n\r\n doInputEvent() {\r\n this.dispatchInputEventOn(this.root);\r\n }\r\n}", + "import OutputTarget from './outputTarget.js';\r\n\r\nexport default class TextArea extends OutputTarget<{}> {\r\n root: HTMLTextAreaElement;\r\n\r\n /**\r\n * Tracks the most recently-cached selection start index.\r\n */\r\n private _cachedSelectionStart: number\r\n\r\n /**\r\n * Tracks the most recently processed, extended-string-based selection start index.\r\n * When the element's selectionStart value changes, this should be invalidated.\r\n */\r\n private processedSelectionStart: number;\r\n\r\n /**\r\n * Tracks the most recently processed, extended-string-based selection end index.\r\n * When the element's selectionEnd value changes, this should be invalidated.\r\n */\r\n private processedSelectionEnd: number;\r\n\r\n /**\r\n * Set, then unset within the `forceScroll` method in order to facilitate the\r\n * `isForcingScroll` flag.\r\n */\r\n private _activeForcedScroll: boolean;\r\n\r\n constructor(ele: HTMLTextAreaElement) {\r\n super();\r\n\r\n this.root = ele;\r\n this._cachedSelectionStart = -1;\r\n }\r\n\r\n get isSynthetic(): boolean {\r\n return false;\r\n }\r\n\r\n getElement(): HTMLTextAreaElement {\r\n return this.root;\r\n }\r\n\r\n clearSelection(): void {\r\n // Processes our codepoint-based variants of selectionStart and selectionEnd.\r\n this.getCaret(); // updates processedSelectionStart if required\r\n this.root.value = this.root.value._kmwSubstring(0, this.processedSelectionStart) + this.root.value._kmwSubstring(this.processedSelectionEnd); //I3319\r\n\r\n this.setCaret(this.processedSelectionStart);\r\n }\r\n\r\n isSelectionEmpty(): boolean {\r\n return this.root.selectionStart == this.root.selectionEnd;\r\n }\r\n\r\n hasSelection(): boolean {\r\n return true;\r\n }\r\n\r\n invalidateSelection() {\r\n // Since .selectionStart will never return this value, we use it to indicate\r\n // the need to refresh our processed indices.\r\n this._cachedSelectionStart = -1;\r\n }\r\n\r\n getCaret(): number {\r\n if(this.root.selectionStart != this._cachedSelectionStart) {\r\n this._cachedSelectionStart = this.root.selectionStart; // KMW-1\r\n this.processedSelectionStart = this.root.value._kmwCodeUnitToCodePoint(this.root.selectionStart); // I3319\r\n this.processedSelectionEnd = this.root.value._kmwCodeUnitToCodePoint(this.root.selectionEnd); // I3319\r\n }\r\n return this.root.selectionDirection == 'forward' ? this.processedSelectionEnd : this.processedSelectionStart;\r\n }\r\n\r\n getDeadkeyCaret(): number {\r\n return this.getCaret();\r\n }\r\n\r\n setCaret(caret: number) {\r\n this.setSelection(caret, caret, \"none\");\r\n }\r\n\r\n setSelection(start: number, end: number, direction: \"forward\" | \"backward\" | \"none\") {\r\n let domStart = this.root.value._kmwCodePointToCodeUnit(start);\r\n let domEnd = this.root.value._kmwCodePointToCodeUnit(end);\r\n this.root.setSelectionRange(domStart, domEnd, direction);\r\n\r\n this.processedSelectionStart = start;\r\n this.processedSelectionEnd = end;\r\n\r\n this.forceScroll();\r\n\r\n this.root.setSelectionRange(domStart, domEnd, direction);\r\n }\r\n\r\n forceScroll() {\r\n // Only executes when com.keyman.DOMEventHandlers is defined.\r\n //\r\n // We bypass this whenever operating in the embedded format.\r\n const element = this.getElement();\r\n\r\n let selectionStart = element.selectionStart;\r\n let selectionEnd = element.selectionEnd;\r\n\r\n this._activeForcedScroll = true;\r\n\r\n try {\r\n //Forces scrolling; the re-focus triggers the scroll, at least.\r\n element.blur();\r\n element.focus();\r\n } finally {\r\n // On Edge, it appears that the blur/focus combination will reset the caret position\r\n // under certain scenarios during unit tests. So, we re-set it afterward.\r\n element.selectionStart = selectionStart;\r\n element.selectionEnd = selectionEnd;\r\n this._activeForcedScroll = false;\r\n }\r\n }\r\n\r\n isForcingScroll(): boolean {\r\n return this._activeForcedScroll;\r\n }\r\n\r\n getSelectionDirection(): \"forward\" | \"backward\" | \"none\" {\r\n return this.root.selectionDirection;\r\n }\r\n\r\n getTextBeforeCaret(): string {\r\n this.getCaret();\r\n return this.getText()._kmwSubstring(0, this.processedSelectionStart);\r\n }\r\n\r\n setTextBeforeCaret(text: string) {\r\n this.getCaret();\r\n let selectionLength = this.processedSelectionEnd - this.processedSelectionStart;\r\n let direction = this.getSelectionDirection();\r\n let newCaret = text._kmwLength();\r\n this.root.value = text + this.getText()._kmwSubstring(this.processedSelectionStart);\r\n\r\n this.setSelection(newCaret, newCaret + selectionLength, direction);\r\n }\r\n\r\n protected setTextAfterCaret(s: string) {\r\n let c = this.getCaret();\r\n let direction = this.getSelectionDirection();\r\n\r\n this.root.value = this.getTextBeforeCaret() + s;\r\n this.setSelection(this.processedSelectionStart, this.processedSelectionEnd, direction);\r\n }\r\n\r\n getTextAfterCaret(): string {\r\n this.getCaret();\r\n return this.getText()._kmwSubstring(this.processedSelectionEnd);\r\n }\r\n\r\n getSelectedText(): string {\r\n this.getCaret();\r\n return this.getText()._kmwSubstring(this.processedSelectionStart, this.processedSelectionEnd);\r\n }\r\n\r\n getText(): string {\r\n return this.root.value;\r\n }\r\n\r\n deleteCharsBeforeCaret(dn: number) {\r\n if(dn > 0) {\r\n let curText = this.getTextBeforeCaret();\r\n let caret = this.processedSelectionStart;\r\n\r\n if(dn > caret) {\r\n dn = caret;\r\n }\r\n\r\n this.adjustDeadkeys(-dn);\r\n this.setTextBeforeCaret(curText.kmwSubstring(0, caret - dn));\r\n this.setCaret(caret - dn);\r\n }\r\n }\r\n\r\n insertTextBeforeCaret(s: string) {\r\n if(!s) {\r\n return;\r\n }\r\n\r\n let caret = this.getCaret();\r\n let front = this.getTextBeforeCaret();\r\n let back = this.getText()._kmwSubstring(this.processedSelectionStart);\r\n\r\n this.adjustDeadkeys(s._kmwLength());\r\n this.root.value = front + s + back;\r\n this.setCaret(caret + s._kmwLength());\r\n }\r\n\r\n handleNewlineAtCaret(): void {\r\n this.insertTextBeforeCaret('\\n');\r\n }\r\n\r\n doInputEvent() {\r\n this.dispatchInputEventOn(this.root);\r\n }\r\n}", + "import OutputTarget from './outputTarget.js';\r\n\r\nclass SelectionCaret {\r\n node: Node;\r\n offset: number;\r\n\r\n constructor(node, offset) {\r\n this.node = node;\r\n this.offset = offset;\r\n }\r\n}\r\n\r\nclass SelectionRange {\r\n start: SelectionCaret;\r\n end: SelectionCaret;\r\n\r\n constructor(start, end) {\r\n this.start = start;\r\n this.end = end;\r\n }\r\n}\r\n\r\nclass StyleCommand {\r\n cmd: string;\r\n stateType: number;\r\n cache: string|boolean;\r\n\r\n constructor(c: string, s:number) {\r\n this.cmd = c;\r\n this.stateType = s;\r\n }\r\n}\r\n\r\nexport default class DesignIFrame extends OutputTarget<{}> {\r\n root: HTMLIFrameElement;\r\n doc: Document;\r\n docRoot: HTMLElement;\r\n\r\n commandCache: StyleCommand[];\r\n\r\n constructor(ele: HTMLIFrameElement) {\r\n super();\r\n this.root = ele;\r\n\r\n if(ele.contentWindow && ele.contentWindow.document && ele.contentWindow.document.designMode == 'on') {\r\n this.doc = ele.contentWindow.document;\r\n this.docRoot = ele.contentWindow.document.documentElement;\r\n } else {\r\n throw \"Specified IFrame is not in design-mode!\";\r\n }\r\n }\r\n\r\n get isSynthetic(): boolean {\r\n return false;\r\n }\r\n\r\n getElement(): HTMLIFrameElement {\r\n return this.root;\r\n }\r\n\r\n focus(): void {\r\n this.doc.defaultView.focus(); // I3363 (Build 301)\r\n }\r\n\r\n isSelectionEmpty(): boolean {\r\n if(!this.hasSelection()) {\r\n return true;\r\n }\r\n\r\n return this.doc.getSelection().isCollapsed;\r\n }\r\n\r\n hasSelection(): boolean {\r\n let Lsel = this.doc.getSelection();\r\n let outerSel = document.getSelection();\r\n\r\n // If the outer doc's selection matches, we're active.\r\n if(outerSel.anchorNode == Lsel.anchorNode && outerSel.focusNode == Lsel.focusNode) {\r\n return true;\r\n } else {\r\n // Problem: for testing, we can't enforce the ideal (ie: first) condition.\r\n // Technically, the IFrame _will_ always have its own internal selection, though... so... it kinda works?\r\n return true;\r\n }\r\n }\r\n\r\n clearSelection(): void {\r\n if(this.hasSelection()) {\r\n let Lsel = this.doc.getSelection();\r\n\r\n if(!Lsel.isCollapsed) {\r\n Lsel.deleteFromDocument(); // I2134, I2192\r\n }\r\n } else {\r\n console.warn(\"Attempted to clear an unowned Selection!\");\r\n }\r\n }\r\n\r\n invalidateSelection(): void { /* No cache maintenance needed here, partly because\r\n * it's impossible to cache a Selection; it mutates.\r\n */ }\r\n\r\n getCarets(): SelectionRange {\r\n let Lsel = this.doc.getSelection();\r\n let code = Lsel.anchorNode.compareDocumentPosition(Lsel.focusNode);\r\n\r\n if(Lsel.isCollapsed) {\r\n let caret = new SelectionCaret(Lsel.anchorNode, Lsel.anchorOffset);\r\n return new SelectionRange(caret, caret);\r\n } else {\r\n let anchor = new SelectionCaret(Lsel.anchorNode, Lsel.anchorOffset);\r\n let focus = new SelectionCaret(Lsel.focusNode, Lsel.focusOffset);\r\n\r\n if(anchor.node == focus.node) {\r\n code = (focus.offset - anchor.offset > 0) ? 2 : 4;\r\n }\r\n\r\n if(code & 2) {\r\n return new SelectionRange(anchor, focus);\r\n } else { // Default\r\n // can test against code & 4 to ensure Focus is before anchor, though.\r\n return new SelectionRange(focus, anchor);\r\n }\r\n }\r\n }\r\n\r\n getDeadkeyCaret(): number {\r\n return this.getTextBeforeCaret().kmwLength();\r\n }\r\n\r\n getTextBeforeCaret(): string {\r\n if(!this.hasSelection()) {\r\n return this.getText();\r\n }\r\n\r\n let caret = this.getCarets().start;\r\n\r\n if(caret.node.nodeType != 3) {\r\n return ''; // Must be a text node to provide a context.\r\n }\r\n\r\n return caret.node.textContent.substr(0, caret.offset);\r\n }\r\n\r\n getSelectedText(): string {\r\n // TODO: figure out the proper implementation.\r\n // KMW 16 and before behavior may be maintained by just returning the empty string.\r\n return '';\r\n }\r\n\r\n getTextAfterCaret(): string {\r\n if(!this.hasSelection()) {\r\n return '';\r\n }\r\n\r\n let caret = this.getCarets().end;\r\n\r\n if(caret.node.nodeType != 3) {\r\n return ''; // Must be a text node to provide a context.\r\n }\r\n\r\n return caret.node.textContent.substr(caret.offset);\r\n }\r\n\r\n getText(): string {\r\n return this.docRoot.innerText;\r\n }\r\n\r\n deleteCharsBeforeCaret(dn: number) {\r\n if(!this.hasSelection() || dn <= 0) {\r\n return;\r\n }\r\n\r\n let start = this.getCarets().start;\r\n\r\n // Bounds-check on the number of chars to delete.\r\n if(dn > start.offset) {\r\n dn = start.offset;\r\n }\r\n\r\n if(start.node.nodeType != 3) {\r\n console.warn(\"Deletion of characters requested without available context!\");\r\n return; // No context to delete characters from.\r\n }\r\n\r\n let range = this.doc.createRange();\r\n let dnOffset = start.offset - start.node.nodeValue.substr(0, start.offset)._kmwSubstr(-dn).length;\r\n\r\n range.setStart(start.node, dnOffset);\r\n range.setEnd(start.node, start.offset);\r\n\r\n this.adjustDeadkeys(-dn);\r\n range.deleteContents();\r\n // No need to reposition the caret - the DOM will auto-move the selection accordingly, since\r\n // we didn't use the selection to delete anything.\r\n }\r\n\r\n insertTextBeforeCaret(s: string) {\r\n if(!this.hasSelection()) {\r\n return;\r\n }\r\n\r\n let start = this.getCarets().start;\r\n let delta = s._kmwLength();\r\n let Lsel = this.doc.getSelection();\r\n\r\n if(delta == 0) {\r\n return;\r\n }\r\n\r\n this.adjustDeadkeys(delta);\r\n\r\n // While Selection.extend() was really nice for this, IE didn't support it whatsoever.\r\n // However, IE (11, at least) DID support setting selections via ranges, so we were still\r\n // able to manage the caret properly.\r\n //\r\n // TODO: double-check that it was only IE-motivated, re-implement with Selection.extend().\r\n let finalCaret = this.root.ownerDocument.createRange();\r\n\r\n if(start.node.nodeType == 3) {\r\n let textStart = start.node;\r\n textStart.insertData(start.offset, s);\r\n finalCaret.setStart(textStart, start.offset + s.length);\r\n } else {\r\n // Create a new text node - empty control\r\n var n = this.doc.createTextNode(s);\r\n\r\n let range = this.doc.createRange();\r\n range.setStart(start.node, start.offset);\r\n range.collapse(true);\r\n range.insertNode(n);\r\n finalCaret.setStart(n, s.length);\r\n }\r\n\r\n finalCaret.collapse(true);\r\n Lsel.removeAllRanges();\r\n try {\r\n Lsel.addRange(finalCaret);\r\n } catch(e) {\r\n // Chrome (through 4.0 at least) throws an exception because it has not synchronised its content with the selection.\r\n // scrollIntoView synchronises the content for selection\r\n start.node.parentElement.scrollIntoView();\r\n Lsel.addRange(finalCaret);\r\n }\r\n Lsel.collapseToEnd();\r\n }\r\n\r\n handleNewlineAtCaret(): void {\r\n // TODO: Implement.\r\n //\r\n // As it turns out, we never had an implementation for handling newline inputs from the OSK for this element type.\r\n // At least this way, it's more explicit.\r\n //\r\n // Note: consult \"// Create a new text node - empty control\" case in insertTextBeforeCaret -\r\n // this helps to handle the browser-default implementation of newline handling. In particular,\r\n // entry of the first character after a newline.\r\n //\r\n // If raw newlines are entered into the HTML, but as with usual HTML, they're interpreted as excess whitespace and\r\n // have no effect. We need to add DOM elements for a functional newline.\r\n }\r\n\r\n protected setTextAfterCaret(s: string) {\r\n if(!this.hasSelection()) {\r\n return;\r\n }\r\n\r\n let caret = this.getCarets().end;\r\n let delta = s._kmwLength();\r\n let Lsel = this.doc.getSelection();\r\n\r\n if(delta == 0) {\r\n return;\r\n }\r\n\r\n // This is designed explicitly for use in direct-setting operations; deadkeys\r\n // will be handled after this method.\r\n\r\n if(caret.node.nodeType == 3) {\r\n let textStart = caret.node;\r\n textStart.replaceData(caret.offset, textStart.length, s);\r\n } else {\r\n // Create a new text node - empty control\r\n var n = caret.node.ownerDocument.createTextNode(s);\r\n\r\n let range = this.root.ownerDocument.createRange();\r\n range.setStart(caret.node, caret.offset);\r\n range.collapse(true);\r\n range.insertNode(n);\r\n }\r\n }\r\n\r\n /**\r\n * Function saveProperties\r\n * Scope Private\r\n * Description Build and create list of styles that can be applied in iframes\r\n */\r\n saveProperties() {\r\n // Formerly _CacheCommands.\r\n var _CacheableCommands=[\r\n new StyleCommand('backcolor',1), new StyleCommand('fontname',1), new StyleCommand('fontsize',1),\r\n new StyleCommand('forecolor',1), new StyleCommand('bold',0), new StyleCommand('italic',0),\r\n new StyleCommand('strikethrough',0), new StyleCommand('subscript',0),\r\n new StyleCommand('superscript',0), new StyleCommand('underline',0)\r\n ];\r\n\r\n if(this.doc.defaultView) {\r\n _CacheableCommands.push(new StyleCommand('hilitecolor',1));\r\n }\r\n\r\n for(var n=0; n < _CacheableCommands.length; n++) { // I1511 - array prototype extended\r\n let cmd = _CacheableCommands[n];\r\n //KeymanWeb._Debug('Command:'+_CacheableCommands[n][0]);\r\n if(cmd.stateType == 1) {\r\n cmd.cache = this.doc.queryCommandValue(cmd.cmd);\r\n } else {\r\n cmd.cache = this.doc.queryCommandState(cmd.cmd);\r\n }\r\n }\r\n this.commandCache = _CacheableCommands;\r\n }\r\n\r\n /**\r\n * Function restoreProperties\r\n * Scope Private\r\n * Description Restore styles in IFRAMEs (??)\r\n */\r\n restoreProperties(_func?: () => void): void {\r\n // Formerly _CacheCommandsReset.\r\n if(!this.commandCache) {\r\n console.error(\"No command cache exists to restore!\");\r\n }\r\n\r\n for(var n=0; n < this.commandCache.length; n++) { // I1511 - array prototype extended\r\n let cmd = this.commandCache[n];\r\n\r\n //KeymanWeb._Debug('ResetCacheCommand:'+_CacheableCommands[n][0]+'='+_CacheableCommands[n][2]);\r\n if(cmd.stateType == 1) {\r\n if(this.doc.queryCommandValue(cmd.cmd) != cmd.cache) {\r\n if(_func) {\r\n _func();\r\n }\r\n this.doc.execCommand(cmd.cmd, false, cmd.cache);\r\n }\r\n } else if(this.doc.queryCommandState(cmd.cmd) != cmd.cache) {\r\n if(_func) {\r\n _func();\r\n }\r\n //KeymanWeb._Debug('executing command '+_CacheableCommand[n][0]);\r\n this.doc.execCommand(cmd.cmd, false, null);\r\n }\r\n }\r\n }\r\n\r\n doInputEvent() {\r\n // Root = the iframe, the outermost component and the one we were originally told to attach to.\r\n this.dispatchInputEventOn(this.root);\r\n }\r\n}", + "import OutputTarget from './outputTarget.js';\r\n\r\nclass SelectionCaret {\r\n node: Node;\r\n offset: number;\r\n\r\n constructor(node, offset) {\r\n this.node = node;\r\n this.offset = offset;\r\n }\r\n}\r\n\r\nclass SelectionRange {\r\n start: SelectionCaret;\r\n end: SelectionCaret;\r\n\r\n constructor(start, end) {\r\n this.start = start;\r\n this.end = end;\r\n }\r\n}\r\n\r\nexport default class ContentEditable extends OutputTarget<{}> {\r\n root: HTMLElement;\r\n\r\n constructor(ele: HTMLElement) {\r\n if(ele.isContentEditable) {\r\n super();\r\n this.root = ele;\r\n } else {\r\n throw \"Specified element is not already content-editable!\";\r\n }\r\n }\r\n\r\n get isSynthetic(): boolean {\r\n return false;\r\n }\r\n\r\n getElement(): HTMLElement {\r\n return this.root;\r\n }\r\n\r\n isSelectionEmpty(): boolean {\r\n if(!this.hasSelection()) {\r\n return true;\r\n }\r\n\r\n return this.root.ownerDocument.getSelection().isCollapsed;\r\n }\r\n\r\n hasSelection(): boolean {\r\n let Lsel = this.root.ownerDocument.getSelection();\r\n\r\n if(this.root != Lsel.anchorNode && !this.root.contains(Lsel.anchorNode)) {\r\n return false;\r\n }\r\n\r\n if(this.root != Lsel.focusNode && !this.root.contains(Lsel.focusNode)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n clearSelection(): void {\r\n if(this.hasSelection()) {\r\n let Lsel = this.root.ownerDocument.getSelection();\r\n\r\n if(!Lsel.isCollapsed) {\r\n Lsel.deleteFromDocument(); // I2134, I2192\r\n }\r\n } else {\r\n console.warn(\"Attempted to clear an unowned Selection!\");\r\n }\r\n }\r\n\r\n invalidateSelection(): void { /* No cache maintenance needed here, partly because\r\n * it's impossible to cache a Selection; it mutates.\r\n */ }\r\n\r\n getCarets(): SelectionRange {\r\n let Lsel = this.root.ownerDocument.getSelection();\r\n let code = Lsel.anchorNode.compareDocumentPosition(Lsel.focusNode);\r\n\r\n if(Lsel.isCollapsed) {\r\n let caret = new SelectionCaret(Lsel.anchorNode, Lsel.anchorOffset);\r\n return new SelectionRange(caret, caret);\r\n } else {\r\n let anchor = new SelectionCaret(Lsel.anchorNode, Lsel.anchorOffset);\r\n let focus = new SelectionCaret(Lsel.focusNode, Lsel.focusOffset);\r\n\r\n if(anchor.node == focus.node) {\r\n code = (focus.offset - anchor.offset > 0) ? 2 : 4;\r\n }\r\n\r\n if(code & 2) {\r\n return new SelectionRange(anchor, focus);\r\n } else { // Default\r\n // can test against code & 4 to ensure Focus is before anchor, though.\r\n return new SelectionRange(focus, anchor);\r\n }\r\n }\r\n }\r\n\r\n getDeadkeyCaret(): number {\r\n return this.getTextBeforeCaret().kmwLength();\r\n }\r\n\r\n getTextBeforeCaret(): string {\r\n if(!this.hasSelection()) {\r\n return this.getText();\r\n }\r\n\r\n let caret = this.getCarets().start;\r\n\r\n if(caret.node.nodeType != 3) {\r\n return ''; // Must be a text node to provide a context.\r\n }\r\n\r\n return caret.node.textContent.substr(0, caret.offset);\r\n }\r\n\r\n getSelectedText(): string {\r\n // TODO: figure out the proper implementation.\r\n // KMW 16 and before behavior may be maintained by just returning the empty string.\r\n return '';\r\n }\r\n\r\n getTextAfterCaret(): string {\r\n if(!this.hasSelection()) {\r\n return '';\r\n }\r\n\r\n let caret = this.getCarets().end;\r\n\r\n if(caret.node.nodeType != 3) {\r\n return ''; // Must be a text node to provide a context.\r\n }\r\n\r\n return caret.node.textContent.substr(caret.offset);\r\n }\r\n\r\n getText(): string {\r\n return this.root.innerText;\r\n }\r\n\r\n deleteCharsBeforeCaret(dn: number) {\r\n if(!this.hasSelection() || dn <= 0) {\r\n return;\r\n }\r\n\r\n let start = this.getCarets().start;\r\n\r\n // Bounds-check on the number of chars to delete.\r\n if(dn > start.offset) {\r\n dn = start.offset;\r\n }\r\n\r\n if(start.node.nodeType != 3) {\r\n console.warn(\"Deletion of characters requested without available context!\");\r\n return; // No context to delete characters from.\r\n }\r\n\r\n let range = this.root.ownerDocument.createRange();\r\n let dnOffset = start.offset - start.node.nodeValue.substr(0, start.offset)._kmwSubstr(-dn).length;\r\n\r\n range.setStart(start.node, dnOffset);\r\n range.setEnd(start.node, start.offset);\r\n\r\n this.adjustDeadkeys(-dn);\r\n range.deleteContents();\r\n // No need to reposition the caret - the DOM will auto-move the selection accordingly, since\r\n // we didn't use the selection to delete anything.\r\n }\r\n\r\n insertTextBeforeCaret(s: string) {\r\n if(!this.hasSelection()) {\r\n return;\r\n }\r\n\r\n let start = this.getCarets().start;\r\n let delta = s._kmwLength();\r\n let Lsel = this.root.ownerDocument.getSelection();\r\n\r\n if(delta == 0) {\r\n return;\r\n }\r\n\r\n this.adjustDeadkeys(delta);\r\n\r\n // While Selection.extend() was really nice for this, IE didn't support it whatsoever.\r\n // However, IE (11, at least) DID support setting selections via ranges, so we were still\r\n // able to manage the caret properly.\r\n //\r\n // TODO: double-check that it was only IE-motivated, re-implement with Selection.extend().\r\n let finalCaret = this.root.ownerDocument.createRange();\r\n\r\n if(start.node.nodeType == 3) {\r\n let textStart = start.node;\r\n textStart.insertData(start.offset, s);\r\n finalCaret.setStart(textStart, start.offset + s.length);\r\n } else {\r\n // Create a new text node - empty control\r\n var n = start.node.ownerDocument.createTextNode(s);\r\n\r\n let range = this.root.ownerDocument.createRange();\r\n range.setStart(start.node, start.offset);\r\n range.collapse(true);\r\n range.insertNode(n);\r\n finalCaret.setStart(n, s.length);\r\n }\r\n\r\n finalCaret.collapse(true);\r\n Lsel.removeAllRanges();\r\n try {\r\n Lsel.addRange(finalCaret);\r\n } catch(e) {\r\n // Chrome (through 4.0 at least) throws an exception because it has not synchronised its content with the selection.\r\n // scrollIntoView synchronises the content for selection\r\n start.node.parentElement.scrollIntoView();\r\n Lsel.addRange(finalCaret);\r\n }\r\n Lsel.collapseToEnd();\r\n }\r\n\r\n handleNewlineAtCaret(): void {\r\n // TODO: Implement.\r\n //\r\n // As it turns out, we never had an implementation for handling newline inputs from the OSK for this element type.\r\n // At least this way, it's more explicit.\r\n //\r\n // Note: consult \"// Create a new text node - empty control\" case in insertTextBeforeCaret -\r\n // this helps to handle the browser-default implementation of newline handling. In particular,\r\n // entry of the first character after a newline.\r\n //\r\n // If raw newlines are entered into the HTML, but as with usual HTML, they're interpreted as excess whitespace and\r\n // have no effect. We need to add DOM elements for a functional newline.\r\n }\r\n\r\n protected setTextAfterCaret(s: string) {\r\n if(!this.hasSelection()) {\r\n return;\r\n }\r\n\r\n let caret = this.getCarets().end;\r\n let delta = s._kmwLength();\r\n let Lsel = this.root.ownerDocument.getSelection();\r\n\r\n if(delta == 0) {\r\n return;\r\n }\r\n\r\n // This is designed explicitly for use in direct-setting operations; deadkeys\r\n // will be handled after this method.\r\n\r\n if(caret.node.nodeType == 3) {\r\n let textStart = caret.node;\r\n textStart.replaceData(caret.offset, textStart.length, s);\r\n } else {\r\n // Create a new text node - empty control\r\n var n = caret.node.ownerDocument.createTextNode(s);\r\n\r\n let range = this.root.ownerDocument.createRange();\r\n range.setStart(caret.node, caret.offset);\r\n range.collapse(true);\r\n range.insertNode(n);\r\n }\r\n }\r\n\r\n doInputEvent() {\r\n this.dispatchInputEventOn(this.root);\r\n }\r\n}", + "/**\r\n * Checks the type of an input DOM-related object while ensuring that it is checked against the correct prototype,\r\n * as class prototypes are (by specification) scoped upon the owning Window.\r\n *\r\n * See https://stackoverflow.com/questions/43587286/why-does-instanceof-return-false-on-chrome-safari-and-edge-and-true-on-firefox\r\n * for more details.\r\n *\r\n * @param {Element|Event} Pelem An element of the web page or one of its IFrame-based subdocuments.\r\n * @param {string} className The plain-text name of the expected Element type.\r\n * @return {boolean}\r\n */\r\nexport function nestedInstanceOf(Pelem: Event|EventTarget, className: string): boolean {\r\n var scopedClass;\r\n\r\n if(!Pelem) {\r\n // If we're bothering to check something's type, null references don't match\r\n // what we're looking for.\r\n return false;\r\n }\r\n if (Pelem['Window']) { // Window objects contain the class definitions for types held within them. So, we can check for those.\r\n return className == 'Window';\r\n } else if (Pelem['defaultView']) { // Covers Document.\r\n scopedClass = Pelem['defaultView'][className];\r\n } else if(Pelem['ownerDocument']) {\r\n scopedClass = (Pelem as Node).ownerDocument.defaultView[className];\r\n } else if(Pelem['target']) {\r\n var event = Pelem as Event;\r\n\r\n if(this.instanceof(event.target, 'Window')) {\r\n scopedClass = event.target[className];\r\n } else if(this.instanceof(event.target, 'Document')) {\r\n scopedClass = (event.target as Document).defaultView[className];\r\n } else if(this.instanceof(event.target, 'HTMLElement')) {\r\n scopedClass = (event.target as HTMLElement).ownerDocument.defaultView[className];\r\n }\r\n }\r\n\r\n if(scopedClass) {\r\n return Pelem instanceof scopedClass;\r\n } else {\r\n return false;\r\n }\r\n}", + "import type OutputTarget from './outputTarget.js';\r\nimport Input from './input.js';\r\nimport TextArea from './textarea.js';\r\nimport DesignIFrame from './designIFrame.js';\r\nimport ContentEditable from './contentEditable.js';\r\nimport { nestedInstanceOf } from './utils.js';\r\n\r\nexport default function wrapElement(e: HTMLElement): OutputTarget {\r\n // Complex type scoping is implemented here so that kmwutils.ts is not a dependency for test compilations.\r\n\r\n if(nestedInstanceOf(e, \"HTMLInputElement\")) {\r\n return new Input( e);\r\n } else if(nestedInstanceOf(e, \"HTMLTextAreaElement\")) {\r\n return new TextArea( e);\r\n } else if(nestedInstanceOf(e, \"HTMLIFrameElement\")) {\r\n let iframe = e;\r\n\r\n if(iframe.contentWindow && iframe.contentWindow.document && iframe.contentWindow.document.designMode == \"on\") {\r\n return new DesignIFrame(iframe);\r\n } else if (e.isContentEditable) {\r\n // Do content-editable