diff --git a/developer/docs/help/reference/kmc/cli/reference.md b/developer/docs/help/reference/kmc/cli/reference.md index bff696d0d0d..51a28f4fc58 100644 --- a/developer/docs/help/reference/kmc/cli/reference.md +++ b/developer/docs/help/reference/kmc/cli/reference.md @@ -280,6 +280,14 @@ Note: paths shown above may vary. : Result file to write to (.json, .md, or .txt) +`-i, --input-mapping-file ` + +: Merge result file with existing mapping file. If supplied, existing + codepoint mappings will be kept, to ensure that updated fonts are + backwardly compatible with deployed keyboards. The + `--include-counts` flag will be set according to the format of + the input mapping file. + For more information on the purpose of `analyze osk-char-use` and `analyze rewrite-osk-from-char-use`, see [`&displayMap`](/developer/language/reference/displaymap). diff --git a/developer/src/kmc-analyze/build.sh b/developer/src/kmc-analyze/build.sh index cb7b79449be..a4844c6afc9 100755 --- a/developer/src/kmc-analyze/build.sh +++ b/developer/src/kmc-analyze/build.sh @@ -27,10 +27,11 @@ builder_parse "$@" function do_test() { eslint . - # TODO: enable tests - # cd test && tsc --build && cd .. && mocha - # TODO: enable c8 (disabled because no coverage at present) - # c8 --reporter=lcov --reporter=text --exclude-after-remap mocha + cd test + tsc --build + cd .. + readonly C8_THRESHOLD=70 + c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha } builder_run_action clean rm -rf ./build/ diff --git a/developer/src/kmc-analyze/package.json b/developer/src/kmc-analyze/package.json index 8577ed25b33..6299bf3a58c 100644 --- a/developer/src/kmc-analyze/package.json +++ b/developer/src/kmc-analyze/package.json @@ -36,6 +36,12 @@ "mocha": "^8.4.0", "typescript": "^5.4.5" }, + "mocha": { + "spec": "build/test/**/test-*.js", + "require": [ + "source-map-support/register" + ] + }, "repository": { "type": "git", "url": "git+https://github.com/keymanapp/keyman.git" diff --git a/developer/src/kmc-analyze/src/analyzer-messages.ts b/developer/src/kmc-analyze/src/analyzer-messages.ts index c895a2f3675..28e280b8082 100644 --- a/developer/src/kmc-analyze/src/analyzer-messages.ts +++ b/developer/src/kmc-analyze/src/analyzer-messages.ts @@ -1,9 +1,12 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m, CompilerMessageDef as def, CompilerMessageSpecWithException, KeymanUrls } from "@keymanapp/developer-utils"; const Namespace = CompilerErrorNamespace.Analyzer; const SevInfo = CompilerErrorSeverity.Info | Namespace; // const SevHint = CompilerErrorSeverity.Hint | Namespace; -// const SevWarn = CompilerErrorSeverity.Warn | Namespace; +const SevWarn = CompilerErrorSeverity.Warn | Namespace; // const SevError = CompilerErrorSeverity.Error | Namespace; const SevFatal = CompilerErrorSeverity.Fatal | Namespace; @@ -28,4 +31,29 @@ export class AnalyzerMessages { `Scanning ${def(o.type)} file ${def(o.name)}`, `Informative message reporting on the current file being scanned` ); + + static readonly WARN_PreviousMapFileCouldNotBeLoaded = SevWarn | 0x0003; + static readonly Warn_PreviousMapFileCouldNotBeLoaded = (o:{filename: string}) => m( + this.WARN_PreviousMapFileCouldNotBeLoaded, + `The map file ${def(o.filename)} is missing or not a valid JSON map file`, + ); + + static readonly WARN_PreviousMapFileCouldNotBeLoadedDueToError = SevWarn | 0x0004; + static readonly Warn_PreviousMapFileCouldNotBeLoadedDueToError = (o:{filename: string, e: any}) => m( + this.WARN_PreviousMapFileCouldNotBeLoadedDueToError, + `The map file ${def(o.filename)} could not be loaded due to ${def(o.e ?? 'unknown error')}`, + ); + + static readonly WARN_PreviousMapDidNotIncludeCounts = SevWarn | 0x0005; + static readonly Warn_PreviousMapDidNotIncludeCounts = (o:{filename: string}) => m( + this.WARN_PreviousMapDidNotIncludeCounts, + `The map file ${def(o.filename)} did not include counts. Changing includeCounts option to 'false' to match`, + ); + + static readonly WARN_PreviousMapDidIncludeCounts = SevWarn | 0x0006; + static readonly Warn_PreviousMapDidIncludeCounts = (o:{filename: string}) => m( + this.WARN_PreviousMapDidIncludeCounts, + `The map file ${def(o.filename)} did include counts. Changing includeCounts option to 'true' to match`, + ); + }; diff --git a/developer/src/kmc-analyze/src/osk-character-use/index.ts b/developer/src/kmc-analyze/src/osk-character-use/index.ts index 36fbf0e78cd..ad97a32e45a 100644 --- a/developer/src/kmc-analyze/src/osk-character-use/index.ts +++ b/developer/src/kmc-analyze/src/osk-character-use/index.ts @@ -1,3 +1,6 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ import { KeymanFileTypes, TouchLayout } from "@keymanapp/common-types"; import { KmnCompilerMessages, Osk } from '@keymanapp/kmc-kmn'; import { CompilerCallbacks, escapeMarkdownChar, KvksFile, KvksFileReader, TouchLayoutFileReader } from '@keymanapp/developer-utils'; @@ -26,6 +29,10 @@ export interface AnalyzeOskCharacterUseOptions { * source file */ includeCounts?: boolean; + /** + * Filename of an existing mapping file to merge the results into + */ + mergeMapFile?: string; } const defaultOptions: AnalyzeOskCharacterUseOptions = { @@ -233,17 +240,45 @@ export class AnalyzeOskCharacterUse { // Results reporting // - private prepareResults(strings: StringRefUsageMap): Osk.StringResult[] { - let result: Osk.StringResult[] = []; - let pua = this.options.puaBase; + private prepareResults(previousMap: Osk.StringResult[], strings: StringRefUsageMap): Osk.StringResult[] { + + // https://stackoverflow.com/a/1584377/1836776 - because we need to compare + // objects, we can't use Set + const mergeArrays = (a: any, b: any, predicate = (a:any, b:any) => a === b) => { + const c = [...a]; // copy to avoid side effects + // add all items from B to copy C if they're not already present + b.forEach((bItem: any) => (c.some((cItem) => predicate(bItem, cItem)) ? null : c.push(bItem))) + return c; + } + + if(!previousMap) { + previousMap = []; + } + + let result: Osk.StringResult[] = [...previousMap]; + + // Note: we are assuming same base as previous runs + let pua = Math.max(this.options.puaBase, ...previousMap.map(item => parseInt(item.pua,16) + 1)); + for(let str of Object.keys(strings)) { - result.push({ - pua: pua.toString(16).toUpperCase(), - str, - unicode: AnalyzeOskCharacterUse.stringToUnicodeSequence(str, false), - usages: this.options.includeCounts ? strings[str] : strings[str].map(item => item.filename) - }); - pua++; + const r = result.find(item => item.str == str); + if(!r) { + result.push({ + pua: pua.toString(16).toUpperCase(), + str, + unicode: AnalyzeOskCharacterUse.stringToUnicodeSequence(str, false), + usages: this.options.includeCounts ? strings[str] : strings[str].map(item => item.filename) + }); + pua++; + } else { + if(this.options.includeCounts) { + // merge StringUsageRefs + r.usages = mergeArrays(r.usages, strings[str], (a: Osk.StringRefUsage, b: Osk.StringRefUsage) => a.filename === b.filename); + } else { + // merge strings + r.usages = mergeArrays(r.usages, strings[str].map(item => item.filename)); + } + } } return result; } @@ -273,7 +308,8 @@ export class AnalyzeOskCharacterUse { * parameter. */ public getStrings(format?: '.txt'|'.md'|'.json'): string[] { - const final = this.prepareResults(this._strings); + const previousMap = this.loadPreviousMap(this.options.mergeMapFile); + const final = this.prepareResults(previousMap, this._strings); switch(format) { case '.md': return AnalyzeOskCharacterUse.getStringsAsMarkdown(final); @@ -283,6 +319,49 @@ export class AnalyzeOskCharacterUse { return AnalyzeOskCharacterUse.getStringsAsText(final); } + /** + * Load a JSON-format result file to merge from + * @param filename + * @returns + */ + private loadPreviousMap(filename: string): Osk.StringResult[] { + if(!filename) { + return null; + } + + const data = this.callbacks.loadFile(filename); + if(!data) { + this.callbacks.reportMessage(AnalyzerMessages.Warn_PreviousMapFileCouldNotBeLoaded({filename})); + return null; + } + let json: any; + try { + json = JSON.parse(new TextDecoder().decode(data)); + if(!json || typeof json != 'object' || !Array.isArray(json.map)) { + this.callbacks.reportMessage(AnalyzerMessages.Warn_PreviousMapFileCouldNotBeLoaded({filename})); + return null; + } + } catch(e) { + this.callbacks.reportMessage(AnalyzerMessages.Warn_PreviousMapFileCouldNotBeLoadedDueToError({filename, e})); + return null; + } + + const map: Osk.StringResult[] = json.map; + const usages = map.find(item => item?.usages?.length).usages; + if(usages) { + if(typeof usages[0] == 'string' && this.options.includeCounts) { + this.callbacks.reportMessage(AnalyzerMessages.Warn_PreviousMapDidNotIncludeCounts({filename})); + this.options.includeCounts = false; + } else if(typeof usages[0] != 'string' && !this.options.includeCounts) { + this.callbacks.reportMessage(AnalyzerMessages.Warn_PreviousMapDidIncludeCounts({filename})); + this.options.includeCounts = true; + } + } + + return map; + } + + // Following functions are static so that we can keep them pure // and potentially refactor into separate reporting class later diff --git a/developer/src/kmc-analyze/test/fixtures/khmer/KbdKhmr-with-sil_khmer.json b/developer/src/kmc-analyze/test/fixtures/khmer/KbdKhmr-with-sil_khmer.json new file mode 100644 index 00000000000..71e31deff97 --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/khmer/KbdKhmr-with-sil_khmer.json @@ -0,0 +1,2697 @@ +{ + "map": [ + { + "pua": "F100", + "str": "0", + "unicode": "0030", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F101", + "str": "1", + "unicode": "0031", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F102", + "str": "2", + "unicode": "0032", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F103", + "str": "3", + "unicode": "0033", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F104", + "str": "4", + "unicode": "0034", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F105", + "str": "5", + "unicode": "0035", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F106", + "str": "6", + "unicode": "0036", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F107", + "str": "7", + "unicode": "0037", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F108", + "str": "8", + "unicode": "0038", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F109", + "str": "9", + "unicode": "0039", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F10A", + "str": "ឆ", + "unicode": "1786", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F10B", + "str": "ឈ", + "unicode": "1788", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F10C", + "str": "្ឆ", + "unicode": "17D2 1786", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F10D", + "str": "្ឈ", + "unicode": "17D2 1788", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F10E", + "str": "ឹ", + "unicode": "17B9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F10F", + "str": "ឺ", + "unicode": "17BA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F110", + "str": "េ", + "unicode": "17C1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F111", + "str": "ែ", + "unicode": "17C2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F112", + "str": "ៃ", + "unicode": "17C3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F113", + "str": "េះ", + "unicode": "17C1 17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F114", + "str": "ឯ", + "unicode": "17AF", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F115", + "str": "ឰ", + "unicode": "17B0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F116", + "str": "រ", + "unicode": "179A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F117", + "str": "្រ", + "unicode": "17D2 179A", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F118", + "str": "ឫ", + "unicode": "17AB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F119", + "str": "ឬ", + "unicode": "17AC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F11A", + "str": "ត", + "unicode": "178F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F11B", + "str": "ទ", + "unicode": "1791", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F11C", + "str": "្ត", + "unicode": "17D2 178F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F11D", + "str": "្ទ", + "unicode": "17D2 1791", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F11E", + "str": "យ", + "unicode": "1799", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F11F", + "str": "្យ", + "unicode": "17D2 1799", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F120", + "str": "ុ", + "unicode": "17BB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F121", + "str": "ូ", + "unicode": "17BC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F122", + "str": "ួ", + "unicode": "17BD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F123", + "str": "ឧ", + "unicode": "17A7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F124", + "str": "ឪ", + "unicode": "17AA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F125", + "str": "ឩ", + "unicode": "17A9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F126", + "str": "ឨ", + "unicode": "17A8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F127", + "str": "ិ", + "unicode": "17B7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F128", + "str": "ី", + "unicode": "17B8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F129", + "str": "ឥ", + "unicode": "17A5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F12A", + "str": "ឦ", + "unicode": "17A6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F12B", + "str": "ោ", + "unicode": "17C4", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F12C", + "str": "ៅ", + "unicode": "17C5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F12D", + "str": "ៀ", + "unicode": "17C0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F12E", + "str": "ឿ", + "unicode": "17BF", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F12F", + "str": "ោះ", + "unicode": "17C4 17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F130", + "str": "ឱ", + "unicode": "17B1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F131", + "str": "ឲ", + "unicode": "17B2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F132", + "str": "ឳ", + "unicode": "17B3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F133", + "str": "ផ", + "unicode": "1795", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F134", + "str": "ភ", + "unicode": "1797", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F135", + "str": "្ផ", + "unicode": "17D2 1795", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F136", + "str": "្ភ", + "unicode": "17D2 1797", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F137", + "str": "ា", + "unicode": "17B6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F138", + "str": "ាំ", + "unicode": "17B6 17C6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F139", + "str": "ស", + "unicode": "179F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F13A", + "str": "្ស", + "unicode": "17D2 179F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F13B", + "str": "ឝ", + "unicode": "179D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F13C", + "str": "ឞ", + "unicode": "179E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F13D", + "str": "ដ", + "unicode": "178A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F13E", + "str": "ឌ", + "unicode": "178C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F13F", + "str": "្ដ", + "unicode": "17D2 178A", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F140", + "str": "្ឌ", + "unicode": "17D2 178C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F141", + "str": "ថ", + "unicode": "1790", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F142", + "str": "ធ", + "unicode": "1792", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F143", + "str": "្ថ", + "unicode": "17D2 1790", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F144", + "str": "្ធ", + "unicode": "17D2 1792", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F145", + "str": "ង", + "unicode": "1784", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F146", + "str": "អ", + "unicode": "17A2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F147", + "str": "្ង", + "unicode": "17D2 1784", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F148", + "str": "្អ", + "unicode": "17D2 17A2", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F149", + "str": "ហ", + "unicode": "17A0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F14A", + "str": "្ហ", + "unicode": "17D2 17A0", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F14B", + "str": "ះ", + "unicode": "17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F14C", + "str": "ៈ", + "unicode": "17C8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F14D", + "str": "ញ", + "unicode": "1789", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F14E", + "str": "្ញ", + "unicode": "17D2 1789", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F14F", + "str": "ក", + "unicode": "1780", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F150", + "str": "គ", + "unicode": "1782", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F151", + "str": "្ក", + "unicode": "17D2 1780", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F152", + "str": "្គ", + "unicode": "17D2 1782", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F153", + "str": "ល", + "unicode": "179B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F154", + "str": "ឡ", + "unicode": "17A1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F155", + "str": "្ល", + "unicode": "17D2 179B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F156", + "str": "ឭ", + "unicode": "17AD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F157", + "str": "ឮ", + "unicode": "17AE", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F158", + "str": "ើ", + "unicode": "17BE", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F159", + "str": "ឋ", + "unicode": "178B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F15A", + "str": "ឍ", + "unicode": "178D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F15B", + "str": "្ឋ", + "unicode": "17D2 178B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F15C", + "str": "្ឍ", + "unicode": "17D2 178D", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F15D", + "str": "ខ", + "unicode": "1781", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F15E", + "str": "ឃ", + "unicode": "1783", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F15F", + "str": "្ខ", + "unicode": "17D2 1781", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F160", + "str": "្ឃ", + "unicode": "17D2 1783", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F161", + "str": "ច", + "unicode": "1785", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F162", + "str": "ជ", + "unicode": "1787", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F163", + "str": "្ច", + "unicode": "17D2 1785", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F164", + "str": "្ជ", + "unicode": "17D2 1787", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F165", + "str": "វ", + "unicode": "179C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F166", + "str": "្វ", + "unicode": "17D2 179C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F167", + "str": "ប", + "unicode": "1794", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F168", + "str": "ព", + "unicode": "1796", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F169", + "str": "្ប", + "unicode": "17D2 1794", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16A", + "str": "្ព", + "unicode": "17D2 1796", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16B", + "str": "ន", + "unicode": "1793", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F16C", + "str": "ណ", + "unicode": "178E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F16D", + "str": "្ន", + "unicode": "17D2 1793", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16E", + "str": "្ណ", + "unicode": "17D2 178E", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16F", + "str": "ម", + "unicode": "1798", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F170", + "str": "្ម", + "unicode": "17D2 1798", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F171", + "str": "ំ", + "unicode": "17C6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F172", + "str": "ុំ", + "unicode": "17BB 17C6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F173", + "str": "ុះ", + "unicode": "17BB 17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F174", + "str": "៍", + "unicode": "17CD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F175", + "str": "័", + "unicode": "17D0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F176", + "str": "៏", + "unicode": "17CF", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F177", + "str": "៌", + "unicode": "17CC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F178", + "str": "៑", + "unicode": "17D1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F179", + "str": "៝", + "unicode": "17DD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F17A", + "str": "៎", + "unicode": "17CE", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F17B", + "str": "់", + "unicode": "17CB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F17C", + "str": "៉", + "unicode": "17C9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F17D", + "str": "៊", + "unicode": "17CA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F17E", + "str": "១២៣", + "unicode": "17E1 17E2 17E3", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F17F", + "str": "*ZWSp*​", + "unicode": "002A 005A 0057 0053 0070 002A 200B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F180", + "str": "។", + "unicode": "17D4", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F181", + "str": "៕", + "unicode": "17D5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F182", + "str": "!", + "unicode": "0021", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F183", + "str": "?", + "unicode": "003F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F184", + "str": "១", + "unicode": "17E1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F185", + "str": "២", + "unicode": "17E2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F186", + "str": "៣", + "unicode": "17E3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F187", + "str": "៤", + "unicode": "17E4", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F188", + "str": "៥", + "unicode": "17E5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F189", + "str": "៦", + "unicode": "17E6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F18A", + "str": "៧", + "unicode": "17E7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F18B", + "str": "៨", + "unicode": "17E8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F18C", + "str": "៩", + "unicode": "17E9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F18D", + "str": "០", + "unicode": "17E0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F18E", + "str": "៓", + "unicode": "17D3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F18F", + "str": "@", + "unicode": "0040", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F190", + "str": "©", + "unicode": "00A9", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F191", + "str": "®", + "unicode": "00AE", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F192", + "str": "#", + "unicode": "0023", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F193", + "str": "№", + "unicode": "2116", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F194", + "str": "~", + "unicode": "007E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F195", + "str": "៛", + "unicode": "17DB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F196", + "str": "$", + "unicode": "0024", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F197", + "str": "฿", + "unicode": "0E3F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F198", + "str": "¢", + "unicode": "00A2", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F199", + "str": "£", + "unicode": "00A3", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19A", + "str": "¥", + "unicode": "00A5", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19B", + "str": "&", + "unicode": "0026", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F19C", + "str": "%", + "unicode": "0025", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F19D", + "str": "‰", + "unicode": "2030", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19E", + "str": "‱", + "unicode": "2031", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19F", + "str": "+", + "unicode": "002B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A0", + "str": "-", + "unicode": "002D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1A1", + "str": "×", + "unicode": "00D7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A2", + "str": "÷", + "unicode": "00F7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A3", + "str": "±", + "unicode": "00B1", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A4", + "str": "=", + "unicode": "003D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1A5", + "str": "_", + "unicode": "005F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A6", + "str": "≠", + "unicode": "2260", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A7", + "str": "*", + "unicode": "002A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1A8", + "str": "^", + "unicode": "005E", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A9", + "str": "¿", + "unicode": "00BF", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AA", + "str": "¡", + "unicode": "00A1", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AB", + "str": "‘", + "unicode": "2018", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1AC", + "str": "’", + "unicode": "2019", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1AD", + "str": "“", + "unicode": "201C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AE", + "str": "”", + "unicode": "201D", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AF", + "str": "«", + "unicode": "00AB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B0", + "str": "»", + "unicode": "00BB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B1", + "str": "/", + "unicode": "002F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B2", + "str": "\\", + "unicode": "005C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1B3", + "str": "|", + "unicode": "007C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1B4", + "str": "¦", + "unicode": "00A6", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1B5", + "str": "(", + "unicode": "0028", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1B6", + "str": ")", + "unicode": "0029", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1B7", + "str": "[", + "unicode": "005B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1B8", + "str": "]", + "unicode": "005D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1B9", + "str": "{", + "unicode": "007B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1BA", + "str": "}", + "unicode": "007D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1BB", + "str": "៙", + "unicode": "17D9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1BC", + "str": "៚", + "unicode": "17DA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1BD", + "str": "ៜ", + "unicode": "17DC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1BE", + "str": "§", + "unicode": "00A7", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1BF", + "str": "Ø", + "unicode": "00D8", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C0", + "str": "ៗ", + "unicode": "17D7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1C1", + "str": "<", + "unicode": "003C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C2", + "str": "≤", + "unicode": "2264", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C3", + "str": ">", + "unicode": "003E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C4", + "str": "≥", + "unicode": "2265", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C5", + "str": "៖", + "unicode": "17D6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1C6", + "str": ":", + "unicode": "003A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C7", + "str": ";", + "unicode": "003B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1C8", + "str": "…", + "unicode": "2026", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C9", + "str": "*Sp*​", + "unicode": "002A 0053 0070 002A 200B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1CA", + "str": "្", + "unicode": "17D2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1CB", + "str": "​", + "unicode": "200B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CC", + "str": "‌", + "unicode": "200C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CD", + "str": "€", + "unicode": "20AC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CE", + "str": "≈", + "unicode": "2248", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CF", + "str": "‍", + "unicode": "200D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D0", + "str": "៘", + "unicode": "17D8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1D1", + "str": ",", + "unicode": "002C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1D2", + "str": ".", + "unicode": "002E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D3", + "str": "", + "unicode": "", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D4", + "str": "\"", + "unicode": "0022", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D5", + "str": "៸", + "unicode": "17F8", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1D6", + "str": "៰", + "unicode": "17F0", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1D7", + "str": "៱", + "unicode": "17F1", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1D8", + "str": "៲", + "unicode": "17F2", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1D9", + "str": "៳", + "unicode": "17F3", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1DA", + "str": "៴", + "unicode": "17F4", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1DB", + "str": "៵", + "unicode": "17F5", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1DC", + "str": "៶", + "unicode": "17F6", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1DD", + "str": "៷", + "unicode": "17F7", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1DE", + "str": "៹", + "unicode": "17F9", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1DF", + "str": "᧿", + "unicode": "19FF", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E0", + "str": "᧾", + "unicode": "19FE", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E1", + "str": "᧪", + "unicode": "19EA", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E2", + "str": "᧫", + "unicode": "19EB", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E3", + "str": "᧶", + "unicode": "19F6", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E4", + "str": "᧵", + "unicode": "19F5", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E5", + "str": "᧬", + "unicode": "19EC", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E6", + "str": "᧷", + "unicode": "19F7", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E7", + "str": "᧥", + "unicode": "19E5", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E8", + "str": "᧸", + "unicode": "19F8", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1E9", + "str": "᧡", + "unicode": "19E1", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1EA", + "str": "᧻", + "unicode": "19FB", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1EB", + "str": "᧹", + "unicode": "19F9", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1EC", + "str": "᧮", + "unicode": "19EE", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1ED", + "str": "᧢", + "unicode": "19E2", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1EE", + "str": "᧯", + "unicode": "19EF", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1EF", + "str": "᧰", + "unicode": "19F0", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F0", + "str": "᧦", + "unicode": "19E6", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F1", + "str": "᧱", + "unicode": "19F1", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F2", + "str": "᧤", + "unicode": "19E4", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F3", + "str": "᧭", + "unicode": "19ED", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F4", + "str": "᧣", + "unicode": "19E3", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F5", + "str": "᧧", + "unicode": "19E7", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F6", + "str": "᧠", + "unicode": "19E0", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F7", + "str": "᧺", + "unicode": "19FA", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F8", + "str": "᧲", + "unicode": "19F2", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1F9", + "str": "᧳", + "unicode": "19F3", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1FA", + "str": "᧴", + "unicode": "19F4", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1FB", + "str": "᧩", + "unicode": "19E9", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1FC", + "str": "᧨", + "unicode": "19E8", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1FD", + "str": "᧼", + "unicode": "19FC", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1FE", + "str": "᧽", + "unicode": "19FD", + "usages": [ + "khmer_angkor.kvks", + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F1FF", + "str": "ឲ្យ", + "unicode": "17B2 17D2 1799", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F200", + "str": "ខ្ញុំ", + "unicode": "1781 17D2 1789 17BB 17C6", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F201", + "str": "space", + "unicode": "0073 0070 0061 0063 0065", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F202", + "str": "hair", + "unicode": "0068 0061 0069 0072", + "usages": [ + "sil_khmer.keyman-touch-layout" + ] + }, + { + "pua": "F203", + "str": "ZWNJ", + "unicode": "005A 0057 004E 004A", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F204", + "str": "thin", + "unicode": "0074 0068 0069 006E", + "usages": [ + "sil_khmer.keyman-touch-layout" + ] + }, + { + "pua": "F205", + "str": "4em", + "unicode": "0034 0065 006D", + "usages": [ + "sil_khmer.keyman-touch-layout" + ] + }, + { + "pua": "F206", + "str": "en", + "unicode": "0065 006E", + "usages": [ + "sil_khmer.keyman-touch-layout" + ] + }, + { + "pua": "F207", + "str": "Zero width space", + "unicode": "005A 0065 0072 006F 0020 0077 0069 0064 0074 0068 0020 0073 0070 0061 0063 0065", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F208", + "str": "ZWJ", + "unicode": "005A 0057 004A", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F209", + "str": "ឣ", + "unicode": "17A3", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F20A", + "str": "ឤ", + "unicode": "17A4", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F20B", + "str": "឴", + "unicode": "17B4", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F20C", + "str": "឵", + "unicode": "17B5", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F20D", + "str": "‹", + "unicode": "2039", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F20E", + "str": "›", + "unicode": "203A", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F20F", + "str": "default", + "unicode": "0064 0065 0066 0061 0075 006C 0074", + "usages": [ + "sil_khmer.keyman-touch-layout" + ] + }, + { + "pua": "F210", + "str": "Four-per-em space", + "unicode": "0046 006F 0075 0072 002D 0070 0065 0072 002D 0065 006D 0020 0073 0070 0061 0063 0065", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F211", + "str": "En space", + "unicode": "0045 006E 0020 0073 0070 0061 0063 0065", + "usages": [ + "sil_khmer.keyman-touch-layout", + "sil_khmer.kvks" + ] + }, + { + "pua": "F212", + "str": "Hair space", + "unicode": "0048 0061 0069 0072 0020 0073 0070 0061 0063 0065", + "usages": [ + "sil_khmer.kvks" + ] + }, + { + "pua": "F213", + "str": "Thin space", + "unicode": "0054 0068 0069 006E 0020 0073 0070 0061 0063 0065", + "usages": [ + "sil_khmer.kvks" + ] + } + ] +} \ No newline at end of file diff --git a/developer/src/kmc-analyze/test/fixtures/khmer/KbdKhmr.json b/developer/src/kmc-analyze/test/fixtures/khmer/KbdKhmr.json new file mode 100644 index 00000000000..464507ed2ec --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/khmer/KbdKhmr.json @@ -0,0 +1,2187 @@ +{ + "map": [ + { + "pua": "F100", + "str": "0", + "unicode": "0030", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F101", + "str": "1", + "unicode": "0031", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F102", + "str": "2", + "unicode": "0032", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F103", + "str": "3", + "unicode": "0033", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F104", + "str": "4", + "unicode": "0034", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F105", + "str": "5", + "unicode": "0035", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F106", + "str": "6", + "unicode": "0036", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F107", + "str": "7", + "unicode": "0037", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F108", + "str": "8", + "unicode": "0038", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F109", + "str": "9", + "unicode": "0039", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F10A", + "str": "ឆ", + "unicode": "1786", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F10B", + "str": "ឈ", + "unicode": "1788", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F10C", + "str": "្ឆ", + "unicode": "17D2 1786", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F10D", + "str": "្ឈ", + "unicode": "17D2 1788", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F10E", + "str": "ឹ", + "unicode": "17B9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F10F", + "str": "ឺ", + "unicode": "17BA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F110", + "str": "េ", + "unicode": "17C1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F111", + "str": "ែ", + "unicode": "17C2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F112", + "str": "ៃ", + "unicode": "17C3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F113", + "str": "េះ", + "unicode": "17C1 17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F114", + "str": "ឯ", + "unicode": "17AF", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F115", + "str": "ឰ", + "unicode": "17B0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F116", + "str": "រ", + "unicode": "179A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F117", + "str": "្រ", + "unicode": "17D2 179A", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F118", + "str": "ឫ", + "unicode": "17AB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F119", + "str": "ឬ", + "unicode": "17AC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F11A", + "str": "ត", + "unicode": "178F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F11B", + "str": "ទ", + "unicode": "1791", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F11C", + "str": "្ត", + "unicode": "17D2 178F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F11D", + "str": "្ទ", + "unicode": "17D2 1791", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F11E", + "str": "យ", + "unicode": "1799", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F11F", + "str": "្យ", + "unicode": "17D2 1799", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F120", + "str": "ុ", + "unicode": "17BB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F121", + "str": "ូ", + "unicode": "17BC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F122", + "str": "ួ", + "unicode": "17BD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F123", + "str": "ឧ", + "unicode": "17A7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F124", + "str": "ឪ", + "unicode": "17AA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F125", + "str": "ឩ", + "unicode": "17A9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F126", + "str": "ឨ", + "unicode": "17A8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F127", + "str": "ិ", + "unicode": "17B7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F128", + "str": "ី", + "unicode": "17B8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F129", + "str": "ឥ", + "unicode": "17A5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F12A", + "str": "ឦ", + "unicode": "17A6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F12B", + "str": "ោ", + "unicode": "17C4", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F12C", + "str": "ៅ", + "unicode": "17C5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F12D", + "str": "ៀ", + "unicode": "17C0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F12E", + "str": "ឿ", + "unicode": "17BF", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F12F", + "str": "ោះ", + "unicode": "17C4 17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F130", + "str": "ឱ", + "unicode": "17B1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F131", + "str": "ឲ", + "unicode": "17B2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F132", + "str": "ឳ", + "unicode": "17B3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F133", + "str": "ផ", + "unicode": "1795", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F134", + "str": "ភ", + "unicode": "1797", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F135", + "str": "្ផ", + "unicode": "17D2 1795", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F136", + "str": "្ភ", + "unicode": "17D2 1797", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F137", + "str": "ា", + "unicode": "17B6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F138", + "str": "ាំ", + "unicode": "17B6 17C6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F139", + "str": "ស", + "unicode": "179F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F13A", + "str": "្ស", + "unicode": "17D2 179F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F13B", + "str": "ឝ", + "unicode": "179D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F13C", + "str": "ឞ", + "unicode": "179E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F13D", + "str": "ដ", + "unicode": "178A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F13E", + "str": "ឌ", + "unicode": "178C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F13F", + "str": "្ដ", + "unicode": "17D2 178A", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F140", + "str": "្ឌ", + "unicode": "17D2 178C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F141", + "str": "ថ", + "unicode": "1790", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F142", + "str": "ធ", + "unicode": "1792", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F143", + "str": "្ថ", + "unicode": "17D2 1790", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F144", + "str": "្ធ", + "unicode": "17D2 1792", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F145", + "str": "ង", + "unicode": "1784", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F146", + "str": "អ", + "unicode": "17A2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F147", + "str": "្ង", + "unicode": "17D2 1784", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F148", + "str": "្អ", + "unicode": "17D2 17A2", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F149", + "str": "ហ", + "unicode": "17A0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F14A", + "str": "្ហ", + "unicode": "17D2 17A0", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F14B", + "str": "ះ", + "unicode": "17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F14C", + "str": "ៈ", + "unicode": "17C8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F14D", + "str": "ញ", + "unicode": "1789", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F14E", + "str": "្ញ", + "unicode": "17D2 1789", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F14F", + "str": "ក", + "unicode": "1780", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F150", + "str": "គ", + "unicode": "1782", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F151", + "str": "្ក", + "unicode": "17D2 1780", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F152", + "str": "្គ", + "unicode": "17D2 1782", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F153", + "str": "ល", + "unicode": "179B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F154", + "str": "ឡ", + "unicode": "17A1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F155", + "str": "្ល", + "unicode": "17D2 179B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F156", + "str": "ឭ", + "unicode": "17AD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F157", + "str": "ឮ", + "unicode": "17AE", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F158", + "str": "ើ", + "unicode": "17BE", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F159", + "str": "ឋ", + "unicode": "178B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F15A", + "str": "ឍ", + "unicode": "178D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F15B", + "str": "្ឋ", + "unicode": "17D2 178B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F15C", + "str": "្ឍ", + "unicode": "17D2 178D", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F15D", + "str": "ខ", + "unicode": "1781", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F15E", + "str": "ឃ", + "unicode": "1783", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F15F", + "str": "្ខ", + "unicode": "17D2 1781", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F160", + "str": "្ឃ", + "unicode": "17D2 1783", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F161", + "str": "ច", + "unicode": "1785", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F162", + "str": "ជ", + "unicode": "1787", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F163", + "str": "្ច", + "unicode": "17D2 1785", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F164", + "str": "្ជ", + "unicode": "17D2 1787", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F165", + "str": "វ", + "unicode": "179C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F166", + "str": "្វ", + "unicode": "17D2 179C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F167", + "str": "ប", + "unicode": "1794", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F168", + "str": "ព", + "unicode": "1796", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F169", + "str": "្ប", + "unicode": "17D2 1794", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16A", + "str": "្ព", + "unicode": "17D2 1796", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16B", + "str": "ន", + "unicode": "1793", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F16C", + "str": "ណ", + "unicode": "178E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F16D", + "str": "្ន", + "unicode": "17D2 1793", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16E", + "str": "្ណ", + "unicode": "17D2 178E", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F16F", + "str": "ម", + "unicode": "1798", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F170", + "str": "្ម", + "unicode": "17D2 1798", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F171", + "str": "ំ", + "unicode": "17C6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F172", + "str": "ុំ", + "unicode": "17BB 17C6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F173", + "str": "ុះ", + "unicode": "17BB 17C7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F174", + "str": "៍", + "unicode": "17CD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F175", + "str": "័", + "unicode": "17D0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F176", + "str": "៏", + "unicode": "17CF", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F177", + "str": "៌", + "unicode": "17CC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F178", + "str": "៑", + "unicode": "17D1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F179", + "str": "៝", + "unicode": "17DD", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F17A", + "str": "៎", + "unicode": "17CE", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F17B", + "str": "់", + "unicode": "17CB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F17C", + "str": "៉", + "unicode": "17C9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F17D", + "str": "៊", + "unicode": "17CA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F17E", + "str": "១២៣", + "unicode": "17E1 17E2 17E3", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F17F", + "str": "*ZWSp*​", + "unicode": "002A 005A 0057 0053 0070 002A 200B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F180", + "str": "។", + "unicode": "17D4", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F181", + "str": "៕", + "unicode": "17D5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F182", + "str": "!", + "unicode": "0021", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F183", + "str": "?", + "unicode": "003F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F184", + "str": "១", + "unicode": "17E1", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F185", + "str": "២", + "unicode": "17E2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F186", + "str": "៣", + "unicode": "17E3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F187", + "str": "៤", + "unicode": "17E4", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F188", + "str": "៥", + "unicode": "17E5", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F189", + "str": "៦", + "unicode": "17E6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F18A", + "str": "៧", + "unicode": "17E7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F18B", + "str": "៨", + "unicode": "17E8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F18C", + "str": "៩", + "unicode": "17E9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F18D", + "str": "០", + "unicode": "17E0", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F18E", + "str": "៓", + "unicode": "17D3", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F18F", + "str": "@", + "unicode": "0040", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F190", + "str": "©", + "unicode": "00A9", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F191", + "str": "®", + "unicode": "00AE", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F192", + "str": "#", + "unicode": "0023", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F193", + "str": "№", + "unicode": "2116", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F194", + "str": "~", + "unicode": "007E", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F195", + "str": "៛", + "unicode": "17DB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F196", + "str": "$", + "unicode": "0024", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F197", + "str": "฿", + "unicode": "0E3F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F198", + "str": "¢", + "unicode": "00A2", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F199", + "str": "£", + "unicode": "00A3", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19A", + "str": "¥", + "unicode": "00A5", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19B", + "str": "&", + "unicode": "0026", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F19C", + "str": "%", + "unicode": "0025", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F19D", + "str": "‰", + "unicode": "2030", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19E", + "str": "‱", + "unicode": "2031", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F19F", + "str": "+", + "unicode": "002B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A0", + "str": "-", + "unicode": "002D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A1", + "str": "×", + "unicode": "00D7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A2", + "str": "÷", + "unicode": "00F7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A3", + "str": "±", + "unicode": "00B1", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A4", + "str": "=", + "unicode": "003D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A5", + "str": "_", + "unicode": "005F", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A6", + "str": "≠", + "unicode": "2260", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A7", + "str": "*", + "unicode": "002A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1A8", + "str": "^", + "unicode": "005E", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1A9", + "str": "¿", + "unicode": "00BF", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AA", + "str": "¡", + "unicode": "00A1", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AB", + "str": "‘", + "unicode": "2018", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1AC", + "str": "’", + "unicode": "2019", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1AD", + "str": "“", + "unicode": "201C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AE", + "str": "”", + "unicode": "201D", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1AF", + "str": "«", + "unicode": "00AB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B0", + "str": "»", + "unicode": "00BB", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B1", + "str": "/", + "unicode": "002F", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B2", + "str": "\\", + "unicode": "005C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B3", + "str": "|", + "unicode": "007C", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1B4", + "str": "¦", + "unicode": "00A6", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1B5", + "str": "(", + "unicode": "0028", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B6", + "str": ")", + "unicode": "0029", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B7", + "str": "[", + "unicode": "005B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B8", + "str": "]", + "unicode": "005D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1B9", + "str": "{", + "unicode": "007B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1BA", + "str": "}", + "unicode": "007D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1BB", + "str": "៙", + "unicode": "17D9", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1BC", + "str": "៚", + "unicode": "17DA", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1BD", + "str": "ៜ", + "unicode": "17DC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1BE", + "str": "§", + "unicode": "00A7", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1BF", + "str": "Ø", + "unicode": "00D8", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C0", + "str": "ៗ", + "unicode": "17D7", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C1", + "str": "<", + "unicode": "003C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C2", + "str": "≤", + "unicode": "2264", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C3", + "str": ">", + "unicode": "003E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C4", + "str": "≥", + "unicode": "2265", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C5", + "str": "៖", + "unicode": "17D6", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C6", + "str": ":", + "unicode": "003A", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C7", + "str": ";", + "unicode": "003B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1C8", + "str": "…", + "unicode": "2026", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1C9", + "str": "*Sp*​", + "unicode": "002A 0053 0070 002A 200B", + "usages": [ + "khmer_angkor.keyman-touch-layout" + ] + }, + { + "pua": "F1CA", + "str": "្", + "unicode": "17D2", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CB", + "str": "​", + "unicode": "200B", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CC", + "str": "‌", + "unicode": "200C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CD", + "str": "€", + "unicode": "20AC", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CE", + "str": "≈", + "unicode": "2248", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1CF", + "str": "‍", + "unicode": "200D", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D0", + "str": "៘", + "unicode": "17D8", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D1", + "str": ",", + "unicode": "002C", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D2", + "str": ".", + "unicode": "002E", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D3", + "str": "", + "unicode": "", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D4", + "str": "\"", + "unicode": "0022", + "usages": [ + "khmer_angkor.keyman-touch-layout", + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D5", + "str": "៸", + "unicode": "17F8", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D6", + "str": "៰", + "unicode": "17F0", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D7", + "str": "៱", + "unicode": "17F1", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D8", + "str": "៲", + "unicode": "17F2", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1D9", + "str": "៳", + "unicode": "17F3", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1DA", + "str": "៴", + "unicode": "17F4", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1DB", + "str": "៵", + "unicode": "17F5", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1DC", + "str": "៶", + "unicode": "17F6", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1DD", + "str": "៷", + "unicode": "17F7", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1DE", + "str": "៹", + "unicode": "17F9", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1DF", + "str": "᧿", + "unicode": "19FF", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E0", + "str": "᧾", + "unicode": "19FE", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E1", + "str": "᧪", + "unicode": "19EA", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E2", + "str": "᧫", + "unicode": "19EB", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E3", + "str": "᧶", + "unicode": "19F6", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E4", + "str": "᧵", + "unicode": "19F5", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E5", + "str": "᧬", + "unicode": "19EC", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E6", + "str": "᧷", + "unicode": "19F7", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E7", + "str": "᧥", + "unicode": "19E5", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E8", + "str": "᧸", + "unicode": "19F8", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1E9", + "str": "᧡", + "unicode": "19E1", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1EA", + "str": "᧻", + "unicode": "19FB", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1EB", + "str": "᧹", + "unicode": "19F9", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1EC", + "str": "᧮", + "unicode": "19EE", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1ED", + "str": "᧢", + "unicode": "19E2", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1EE", + "str": "᧯", + "unicode": "19EF", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1EF", + "str": "᧰", + "unicode": "19F0", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F0", + "str": "᧦", + "unicode": "19E6", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F1", + "str": "᧱", + "unicode": "19F1", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F2", + "str": "᧤", + "unicode": "19E4", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F3", + "str": "᧭", + "unicode": "19ED", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F4", + "str": "᧣", + "unicode": "19E3", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F5", + "str": "᧧", + "unicode": "19E7", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F6", + "str": "᧠", + "unicode": "19E0", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F7", + "str": "᧺", + "unicode": "19FA", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F8", + "str": "᧲", + "unicode": "19F2", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1F9", + "str": "᧳", + "unicode": "19F3", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1FA", + "str": "᧴", + "unicode": "19F4", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1FB", + "str": "᧩", + "unicode": "19E9", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1FC", + "str": "᧨", + "unicode": "19E8", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1FD", + "str": "᧼", + "unicode": "19FC", + "usages": [ + "khmer_angkor.kvks" + ] + }, + { + "pua": "F1FE", + "str": "᧽", + "unicode": "19FD", + "usages": [ + "khmer_angkor.kvks" + ] + } + ] +} \ No newline at end of file diff --git a/developer/src/kmc-analyze/test/fixtures/khmer/khmer_angkor.keyman-touch-layout b/developer/src/kmc-analyze/test/fixtures/khmer/khmer_angkor.keyman-touch-layout new file mode 100644 index 00000000000..71af4c108f9 --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/khmer/khmer_angkor.keyman-touch-layout @@ -0,0 +1,1938 @@ +{ + "tablet": { + "displayUnderlying": false, + "layer": [ + { + "id": "default", + "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": "ឲ" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "ឆ" + }, + { + "id": "K_W", + "text": "ឹ" + }, + { + "id": "K_E", + "text": "េ" + }, + { + "id": "K_R", + "text": "រ" + }, + { + "id": "K_T", + "text": "ត" + }, + { + "id": "K_Y", + "text": "យ" + }, + { + "id": "K_U", + "text": "ុ" + }, + { + "id": "K_I", + "text": "ិ" + }, + { + "id": "K_O", + "text": "ោ" + }, + { + "id": "K_P", + "text": "ផ" + }, + { + "id": "K_LBRKT", + "text": "ៀ" + }, + { + "id": "K_RBRKT", + "text": "ឪ" + }, + { + "id": "T_new_138", + "text": "", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "«" + }, + { + "id": "K_A", + "text": "ា" + }, + { + "id": "K_S", + "text": "ស" + }, + { + "id": "K_D", + "text": "ដ" + }, + { + "id": "K_F", + "text": "ថ" + }, + { + "id": "K_G", + "text": "ង" + }, + { + "id": "K_H", + "text": "ហ" + }, + { + "id": "K_J", + "text": "្" + }, + { + "id": "K_K", + "text": "ក" + }, + { + "id": "K_L", + "text": "ល" + }, + { + "id": "K_COLON", + "text": "ើ" + }, + { + "id": "K_QUOTE", + "text": "់" + }, + { + "id": "K_BKSLASH", + "text": "ឮ" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": 160, + "sp": 1, + "nextlayer": "shift" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "ឋ" + }, + { + "id": "K_X", + "text": "ខ" + }, + { + "id": "K_C", + "text": "ច" + }, + { + "id": "K_V", + "text": "វ" + }, + { + "id": "K_B", + "text": "ប" + }, + { + "id": "K_N", + "text": "ន" + }, + { + "id": "K_M", + "text": "ម" + }, + { + "id": "K_COMMA", + "text": "ុំ" + }, + { + "id": "K_PERIOD", + "text": "។" + }, + { + "id": "K_SLASH", + "text": "៊" + }, + { + "id": "T_new_164", + "text": "", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "*AltGr*", + "width": 160, + "sp": 1, + "nextlayer": "rightalt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 160, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "​", + "width": 930 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 160, + "sp": 1 + } + ] + } + ] + }, + { + "id": "rightalt", + "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": "៎" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "ៜ" + }, + { + "id": "K_W", + "text": "៝" + }, + { + "id": "K_E", + "text": "ឯ" + }, + { + "id": "K_R", + "text": "ឫ" + }, + { + "id": "K_T", + "text": "ឨ" + }, + { + "id": "K_Y", + "text": "[" + }, + { + "id": "K_U", + "text": "]" + }, + { + "id": "K_I", + "text": "ឦ" + }, + { + "id": "K_O", + "text": "ឱ" + }, + { + "id": "K_P", + "text": "ឰ" + }, + { + "id": "K_LBRKT", + "text": "ឩ" + }, + { + "id": "K_RBRKT", + "text": "ឳ" + }, + { + "id": "T_new_307", + "text": "", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "‍" + }, + { + "id": "K_A", + "text": "+" + }, + { + "id": "K_S", + "text": "-" + }, + { + "id": "K_D", + "text": "×" + }, + { + "id": "K_F", + "text": "÷" + }, + { + "id": "K_G", + "text": ":" + }, + { + "id": "K_H", + "text": "‘" + }, + { + "id": "K_J", + "text": "’" + }, + { + "id": "K_K", + "text": "ឝ" + }, + { + "id": "K_L", + "text": "៘" + }, + { + "id": "K_COLON", + "text": "៖" + }, + { + "id": "K_QUOTE", + "text": "ៈ" + }, + { + "id": "K_BKSLASH", + "text": "\\" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": 160, + "sp": 1, + "nextlayer": "shift" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "<" + }, + { + "id": "K_X", + "text": ">" + }, + { + "id": "K_C", + "text": "#" + }, + { + "id": "K_V", + "text": "&" + }, + { + "id": "K_B", + "text": "ឞ" + }, + { + "id": "K_N", + "text": ";" + }, + { + "id": "K_M", + "text": "៓" + }, + { + "id": "K_COMMA", + "text": "," + }, + { + "id": "K_PERIOD", + "text": "." + }, + { + "id": "K_SLASH", + "text": "/" + }, + { + "id": "T_new_333", + "text": "", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "*AltGr*", + "width": 160, + "sp": 2, + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 160, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": " ", + "width": 930 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 160, + "sp": 1 + } + ] + } + ] + }, + { + "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": "=" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "ឈ" + }, + { + "id": "K_W", + "text": "ឺ" + }, + { + "id": "K_E", + "text": "ែ" + }, + { + "id": "K_R", + "text": "ឬ" + }, + { + "id": "K_T", + "text": "ទ" + }, + { + "id": "K_Y", + "text": "ួ" + }, + { + "id": "K_U", + "text": "ូ" + }, + { + "id": "K_I", + "text": "ី" + }, + { + "id": "K_O", + "text": "ៅ" + }, + { + "id": "K_P", + "text": "ភ" + }, + { + "id": "K_LBRKT", + "text": "ឿ" + }, + { + "id": "K_RBRKT", + "text": "ឧ" + }, + { + "id": "T_new_364", + "text": "", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_BKQUOTE", + "text": "»" + }, + { + "id": "K_A", + "text": "ាំ" + }, + { + "id": "K_S", + "text": "ៃ" + }, + { + "id": "K_D", + "text": "ឌ" + }, + { + "id": "K_F", + "text": "ធ" + }, + { + "id": "K_G", + "text": "អ" + }, + { + "id": "K_H", + "text": "ះ" + }, + { + "id": "K_J", + "text": "ញ" + }, + { + "id": "K_K", + "text": "គ" + }, + { + "id": "K_L", + "text": "ឡ" + }, + { + "id": "K_COLON", + "text": "ោះ" + }, + { + "id": "K_QUOTE", + "text": "៉" + }, + { + "id": "K_BKSLASH", + "text": "ឭ" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": 160, + "sp": 2, + "nextlayer": "default" + }, + { + "id": "K_oE2", + "text": "" + }, + { + "id": "K_Z", + "text": "ឍ" + }, + { + "id": "K_X", + "text": "ឃ" + }, + { + "id": "K_C", + "text": "ជ" + }, + { + "id": "K_V", + "text": "េះ" + }, + { + "id": "K_B", + "text": "ព" + }, + { + "id": "K_N", + "text": "ណ" + }, + { + "id": "K_M", + "text": "ំ" + }, + { + "id": "K_COMMA", + "text": "ុះ" + }, + { + "id": "K_PERIOD", + "text": "៕" + }, + { + "id": "K_SLASH", + "text": "?" + }, + { + "id": "T_new_390", + "text": "", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "*AltGr*", + "width": 160, + "sp": 1, + "nextlayer": "rightalt" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 160, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "", + "width": 930 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 160, + "sp": 1 + } + ] + } + ] + } + ], + "font": "Khmer Mondulkiri", + "fontsize": "" + }, + "phone": { + "layer": [ + { + "id": "default", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_Q", + "text": "ឆ", + "sk": [ + { + "text": "ឈ", + "id": "K_Q", + "layer": "shift" + }, + { + "text": "្ឆ", + "id": "T_17D2_1786" + }, + { + "text": "្ឈ", + "id": "T_17D2_1788" + } + ] + }, + { + "id": "K_W", + "text": "ឹ", + "sk": [ + { + "text": "ឺ", + "id": "K_W", + "layer": "shift" + } + ] + }, + { + "id": "K_E", + "text": "េ", + "sk": [ + { + "text": "ែ", + "id": "K_E", + "layer": "shift" + }, + { + "text": "ៃ", + "id": "K_S", + "layer": "shift" + }, + { + "text": "េះ", + "id": "K_V", + "layer": "shift" + }, + { + "text": "ឯ", + "id": "U_17AF" + }, + { + "text": "ឰ", + "id": "U_17B0" + } + ] + }, + { + "id": "K_R", + "text": "រ", + "sk": [ + { + "text": "្រ", + "id": "T_17D2_179A" + }, + { + "text": "ឫ", + "id": "U_17AB" + }, + { + "text": "ឬ", + "id": "U_17AC" + } + ] + }, + { + "id": "K_T", + "text": "ត", + "sk": [ + { + "text": "ទ", + "id": "K_T", + "layer": "shift" + }, + { + "text": "្ត", + "id": "T_17D2_178F" + }, + { + "text": "្ទ", + "id": "T_17D2_1791", + "layer": "default" + } + ] + }, + { + "id": "K_Y", + "text": "យ", + "sk": [ + { + "text": "្យ", + "id": "T_17D2_1799" + } + ] + }, + { + "id": "K_U", + "text": "ុ", + "sk": [ + { + "text": "ូ", + "id": "K_U", + "layer": "shift" + }, + { + "text": "ួ", + "id": "K_Y", + "layer": "shift" + }, + { + "text": "ឧ", + "id": "U_17A7" + }, + { + "text": "ឪ", + "id": "U_17AA", + "layer": "shift" + }, + { + "text": "ឩ", + "id": "U_17A9", + "layer": "shift" + }, + { + "text": "ឨ", + "id": "U_17A8" + } + ] + }, + { + "id": "K_I", + "text": "ិ", + "sk": [ + { + "text": "ី", + "id": "K_I", + "layer": "shift" + }, + { + "text": "ឥ", + "id": "U_17A5" + }, + { + "text": "ឦ", + "id": "U_17A6", + "layer": "shift" + } + ] + }, + { + "id": "K_O", + "text": "ោ", + "sk": [ + { + "text": "ៅ", + "id": "K_O", + "layer": "shift" + }, + { + "text": "ៀ", + "id": "K_LBRKT" + }, + { + "text": "ឿ", + "id": "K_LBRKT", + "layer": "shift" + }, + { + "text": "ោះ", + "id": "K_COLON", + "layer": "shift" + }, + { + "text": "ឱ", + "id": "U_17B1" + }, + { + "text": "ឲ", + "id": "U_17B2" + }, + { + "text": "ឳ", + "id": "U_17B3", + "layer": "shift" + } + ] + }, + { + "id": "K_P", + "text": "ផ", + "sk": [ + { + "text": "ភ", + "id": "K_P", + "layer": "shift" + }, + { + "text": "្ផ", + "id": "T_17D2_1795" + }, + { + "text": "្ភ", + "id": "T_17D2_1797", + "layer": "default" + } + ] + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_A", + "text": "ា", + "width": 100, + "sk": [ + { + "text": "ាំ", + "id": "K_A", + "layer": "shift" + } + ] + }, + { + "id": "K_S", + "text": "ស", + "sk": [ + { + "text": "្ស", + "id": "T_17D2_179F" + }, + { + "text": "ឝ", + "id": "U_179D" + }, + { + "text": "ឞ", + "id": "U_179E" + } + ] + }, + { + "id": "K_D", + "text": "ដ", + "sk": [ + { + "text": "ឌ", + "id": "K_D", + "layer": "shift" + }, + { + "text": "្ដ", + "id": "T_17D2_178A" + }, + { + "text": "្ឌ", + "id": "T_17D2_178C", + "layer": "default" + } + ] + }, + { + "id": "K_F", + "text": "ថ", + "sk": [ + { + "text": "ធ", + "id": "K_F", + "layer": "shift" + }, + { + "text": "្ថ", + "id": "T_17D2_1790" + }, + { + "text": "្ធ", + "id": "T_17D2_1792", + "layer": "default" + } + ] + }, + { + "id": "K_G", + "text": "ង", + "sk": [ + { + "text": "អ", + "id": "K_G", + "layer": "shift" + }, + { + "text": "្ង", + "id": "T_17D2_1784" + }, + { + "text": "្អ", + "id": "T_17D2_17A2", + "layer": "default" + } + ] + }, + { + "id": "K_H", + "text": "ហ", + "sk": [ + { + "text": "្ហ", + "id": "T_17D2_17A0" + }, + { + "text": "ះ", + "id": "K_H", + "layer": "shift" + }, + { + "text": "ៈ", + "id": "U_17C8" + } + ] + }, + { + "id": "K_J", + "text": "ញ", + "layer": "shift", + "sk": [ + { + "text": "្ញ", + "id": "T_17D2_1789" + } + ] + }, + { + "id": "K_K", + "text": "ក", + "sk": [ + { + "text": "គ", + "id": "K_K", + "layer": "shift" + }, + { + "text": "្ក", + "id": "T_17D2_1780" + }, + { + "text": "្គ", + "id": "T_17D2_1782" + } + ] + }, + { + "id": "K_L", + "text": "ល", + "sk": [ + { + "text": "ឡ", + "id": "K_L", + "layer": "shift" + }, + { + "text": "្ល", + "id": "T_17D2_179B" + }, + { + "text": "ឭ", + "id": "U_17AD" + }, + { + "text": "ឮ", + "id": "U_17AE" + } + ] + }, + { + "id": "K_COLON", + "text": "ើ" + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_Z", + "text": "ឋ", + "sk": [ + { + "text": "ឍ", + "id": "K_Z", + "layer": "shift" + }, + { + "text": "្ឋ", + "id": "T_17D2_178B" + }, + { + "text": "្ឍ", + "id": "T_17D2_178D", + "layer": "default" + } + ] + }, + { + "id": "K_X", + "text": "ខ", + "sk": [ + { + "text": "ឃ", + "id": "K_X", + "layer": "shift" + }, + { + "text": "្ខ", + "id": "T_17D2_1781" + }, + { + "text": "្ឃ", + "id": "T_17D2_1783", + "layer": "default" + } + ] + }, + { + "id": "K_C", + "text": "ច", + "sk": [ + { + "text": "ជ", + "id": "K_C", + "layer": "shift" + }, + { + "text": "្ច", + "id": "T_17D2_1785" + }, + { + "text": "្ជ", + "id": "T_17D2_1787", + "layer": "default" + } + ] + }, + { + "id": "K_V", + "text": "វ", + "sk": [ + { + "text": "្វ", + "id": "T_17D2_179C" + } + ] + }, + { + "id": "K_B", + "text": "ប", + "sk": [ + { + "text": "ព", + "id": "K_B", + "layer": "shift" + }, + { + "text": "្ប", + "id": "T_17D2_1794" + }, + { + "text": "្ព", + "id": "T_17D2_1796", + "layer": "default" + } + ] + }, + { + "id": "K_N", + "text": "ន", + "sk": [ + { + "text": "ណ", + "id": "K_N", + "layer": "shift" + }, + { + "text": "្ន", + "id": "T_17D2_1793" + }, + { + "text": "្ណ", + "id": "T_17D2_178E", + "layer": "default" + } + ] + }, + { + "id": "K_M", + "text": "ម", + "sk": [ + { + "text": "្ម", + "id": "T_17D2_1798" + }, + { + "id": "K_M", + "text": "ំ", + "layer": "shift" + } + ] + }, + { + "id": "K_COMMA", + "text": "ុំ", + "sk": [ + { + "id": "K_COMMA", + "text": "ុះ", + "layer": "shift" + }, + { + "id": "K_6", + "text": "៍", + "layer": "shift" + }, + { + "id": "K_7", + "text": "័", + "layer": "shift" + }, + { + "id": "K_8", + "text": "៏", + "layer": "shift" + }, + { + "id": "K_HYPHEN", + "text": "៌", + "layer": "shift" + }, + { + "id": "U_17D1", + "text": "៑", + "layer": "shift" + }, + { + "id": "U_17DD", + "text": "៝", + "layer": "shift" + }, + { + "id": "U_17CE", + "text": "៎", + "layer": "shift" + } + ] + }, + { + "id": "K_QUOTE", + "text": "់", + "width": 100, + "sk": [ + { + "text": "៉", + "id": "K_QUOTE", + "layer": "shift" + }, + { + "text": "៊", + "id": "K_SLASH" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_NUMLOCK", + "text": "១២៣", + "width": 140, + "sp": 1, + "nextlayer": "numeric" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 120, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "*ZWSp*​", + "width": 555, + "sp": 0, + "sk": [ + { + "text": "*Sp*", + "id": "U_0020", + "layer": "default" + } + ] + }, + { + "id": "K_PERIOD", + "text": "។", + "width": 120, + "sk": [ + { + "text": "៕", + "id": "K_PERIOD", + "layer": "shift" + }, + { + "text": "!", + "id": "U_0021" + }, + { + "text": "?", + "id": "U_003F" + } + ] + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 140, + "sp": 1 + } + ] + } + ] + }, + { + "id": "numeric", + "row": [ + { + "id": 1, + "key": [ + { + "id": "K_1", + "text": "១", + "sk": [ + { + "text": "1", + "id": "U_0031" + } + ] + }, + { + "id": "K_2", + "text": "២", + "sk": [ + { + "text": "2", + "id": "U_0032" + } + ] + }, + { + "id": "K_3", + "text": "៣", + "sk": [ + { + "text": "3", + "id": "U_0033" + } + ] + }, + { + "id": "K_4", + "text": "៤", + "sk": [ + { + "text": "4", + "id": "U_0034" + } + ] + }, + { + "id": "K_5", + "text": "៥", + "sk": [ + { + "text": "5", + "id": "U_0035" + } + ] + }, + { + "id": "K_6", + "text": "៦", + "sk": [ + { + "text": "6", + "id": "U_0036" + } + ] + }, + { + "id": "K_7", + "text": "៧", + "sk": [ + { + "text": "7", + "id": "U_0037" + } + ] + }, + { + "id": "K_8", + "text": "៨", + "sk": [ + { + "text": "8", + "id": "U_0038" + } + ] + }, + { + "id": "K_9", + "text": "៩", + "sk": [ + { + "text": "9", + "id": "U_0039" + } + ] + }, + { + "id": "K_0", + "text": "០", + "sk": [ + { + "text": "0", + "id": "U_0030" + }, + { + "text": "៓", + "id": "U_17D3" + } + ] + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "U_0040", + "text": "@", + "sk": [ + { + "text": "©", + "id": "U_00A9" + }, + { + "text": "®", + "id": "U_00AE" + } + ] + }, + { + "id": "U_0023", + "text": "#", + "sk": [ + { + "text": "№", + "id": "U_2116" + }, + { + "text": "~", + "id": "U_007E" + } + ] + }, + { + "id": "U_17DB", + "text": "៛", + "sk": [ + { + "text": "$", + "id": "U_0024" + }, + { + "text": "฿", + "id": "U_0E3F" + }, + { + "text": "¢", + "id": "U_00A2" + }, + { + "text": "£", + "id": "U_00A3" + }, + { + "text": "¥", + "id": "U_00A5" + } + ] + }, + { + "id": "U_0026", + "text": "&" + }, + { + "id": "U_0025", + "text": "%", + "sk": [ + { + "text": "‰", + "id": "U_2030" + }, + { + "text": "‱", + "id": "U_2031" + } + ] + }, + { + "id": "U_002B", + "text": "+", + "sk": [ + { + "text": "-", + "id": "U_002D" + }, + { + "text": "×", + "id": "U_00D7" + }, + { + "text": "÷", + "id": "U_00F7" + }, + { + "text": "±", + "id": "U_00B1" + } + ] + }, + { + "id": "U_003D", + "text": "=", + "sk": [ + { + "text": "_", + "id": "U_005F" + }, + { + "text": "≠", + "id": "U_2260" + } + ] + }, + { + "id": "U_002A", + "text": "*", + "sk": [ + { + "text": "^", + "id": "U_005E" + } + ] + }, + { + "id": "U_003F", + "text": "?", + "sk": [ + { + "text": "¿", + "id": "U_00BF" + } + ] + }, + { + "id": "U_0021", + "text": "!", + "sk": [ + { + "text": "¡", + "id": "U_00A1" + } + ] + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "U_2018", + "text": "‘", + "sk": [ + { + "text": "’", + "id": "U_2019" + } + ] + }, + { + "id": "U_201C", + "text": "“", + "sk": [ + { + "text": "”", + "id": "U_201D" + } + ] + }, + { + "id": "U_00AB", + "text": "«", + "sk": [ + { + "text": "»", + "id": "U_00BB" + } + ] + }, + { + "id": "U_002F", + "text": "/", + "sk": [ + { + "text": "\\", + "id": "U_005C" + }, + { + "text": "|", + "id": "U_007C" + }, + { + "text": "¦", + "id": "U_00A6" + } + ] + }, + { + "id": "U_0028", + "text": "(", + "sk": [ + { + "text": ")", + "id": "U_0029" + }, + { + "text": "[", + "id": "U_005B" + }, + { + "text": "]", + "id": "U_005D" + }, + { + "text": "{", + "id": "U_007B" + }, + { + "text": "}", + "id": "U_007D" + } + ] + }, + { + "id": "U_17D9", + "text": "៙", + "sk": [ + { + "text": "៚", + "id": "U_17DA" + }, + { + "text": "ៜ", + "id": "U_17DC" + }, + { + "text": "§", + "id": "U_00A7" + }, + { + "text": "Ø", + "id": "U_00D8" + } + ] + }, + { + "id": "U_17D7", + "text": "ៗ" + }, + { + "id": "U_003C", + "text": "<", + "sk": [ + { + "text": "≤", + "id": "U_2264" + }, + { + "text": ">", + "id": "U_003E" + }, + { + "text": "≥", + "id": "U_2265" + } + ] + }, + { + "id": "U_17D6", + "text": "៖", + "sk": [ + { + "text": ":", + "id": "U_003A" + }, + { + "text": ";", + "id": "U_003B" + }, + { + "text": "…", + "id": "U_2026" + } + ] + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "sp": 1 + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_LCONTROL", + "text": "១២៣", + "width": 140, + "sp": 2, + "nextlayer": "default" + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 120, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "*Sp*​", + "width": 555, + "sp": 0, + "layer": "shift" + }, + { + "id": "K_PERIOD", + "text": "។", + "width": 120, + "sk": [ + { + "text": "៕", + "id": "K_PERIOD", + "layer": "shift" + }, + { + "text": "!", + "id": "U_0021" + }, + { + "text": "?", + "id": "U_003F" + } + ] + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 140, + "sp": 1 + } + ] + } + ] + } + ], + "displayUnderlying": false, + "font": "Khmer Mondulkiri", + "fontsize": "" + } +} \ No newline at end of file diff --git a/developer/src/kmc-analyze/test/fixtures/khmer/khmer_angkor.kvks b/developer/src/kmc-analyze/test/fixtures/khmer/khmer_angkor.kvks new file mode 100644 index 00000000000..f0f9bc775d2 --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/khmer/khmer_angkor.kvks @@ -0,0 +1,206 @@ + + +
+ 10.0 + khmer_angkor + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + ] + [ + / + . + + + + & + + * + @ + \ + } + { + - + ÷ + : + , + + ; + < + # + > + × + $ + +   + + + + + + + + + + + + + ᧿ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ុំ + + + + + + + + + + + + + + + + + + + « + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ! + + " + + % + + ( + ) + + = + ោះ + ុះ + + ? + + ាំ + + + + + + + + + + + + + + + + + + + + + េះ + + + + + + + + + + » + + +
diff --git a/developer/src/kmc-analyze/test/fixtures/khmer/sil_khmer.keyman-touch-layout b/developer/src/kmc-analyze/test/fixtures/khmer/sil_khmer.keyman-touch-layout new file mode 100644 index 00000000000..a28b323fc38 --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/khmer/sil_khmer.keyman-touch-layout @@ -0,0 +1,1125 @@ +{ + "tablet": { + "displayUnderlying": false, + "layer": [ + { + "id": "default", + "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": "=" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "ឆ", + "pad": 75 + }, + { + "id": "K_W", + "text": "ឹ" + }, + { + "id": "K_E", + "text": "េ" + }, + { + "id": "K_R", + "text": "រ" + }, + { + "id": "K_T", + "text": "ត" + }, + { + "id": "K_Y", + "text": "យ" + }, + { + "id": "K_U", + "text": "ុ" + }, + { + "id": "K_I", + "text": "ិ" + }, + { + "id": "K_O", + "text": "ៀ" + }, + { + "id": "K_P", + "text": "ផ" + }, + { + "id": "K_LBRKT", + "text": "ឲ្យ" + }, + { + "id": "K_RBRKT", + "text": "ខ្ញុំ" + }, + { + "id": "T_new_138", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_A", + "text": "ា" + }, + { + "id": "K_S", + "text": "ស" + }, + { + "id": "K_D", + "text": "ដ" + }, + { + "id": "K_F", + "text": "ថ" + }, + { + "id": "K_G", + "text": "ង" + }, + { + "id": "K_H", + "text": "ហ" + }, + { + "id": "K_J", + "text": "ញ" + }, + { + "id": "K_K", + "text": "ក" + }, + { + "id": "K_L", + "text": "ល" + }, + { + "id": "K_COLON", + "text": "្" + }, + { + "id": "K_QUOTE", + "text": "៊" + }, + { + "id": "K_BKSLASH", + "text": "ឮ" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": 160, + "sp": 1, + "nextlayer": "shift" + }, + { + "id": "K_Z", + "text": "ឋ" + }, + { + "id": "K_X", + "text": "ខ" + }, + { + "id": "K_C", + "text": "ច" + }, + { + "id": "K_V", + "text": "វ" + }, + { + "id": "K_B", + "text": "ប" + }, + { + "id": "K_N", + "text": "ន" + }, + { + "id": "K_M", + "text": "ម" + }, + { + "id": "K_COMMA", + "text": "," + }, + { + "id": "K_PERIOD", + "text": "space", + "sk": [ + { + "text": "hair", + "id": "U_200A" + }, + { + "text": "ZWNJ", + "id": "U_200C" + }, + { + "text": "thin", + "id": "U_2009" + }, + { + "text": "4em", + "id": "U_2005" + }, + { + "text": "en", + "id": "U_2002" + } + ] + }, + { + "id": "K_SLASH", + "text": "\\" + }, + { + "id": "K_BKQUOTE", + "text": "់" + }, + { + "id": "T_new_164", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "*Alt*", + "width": 130, + "sp": 1, + "nextlayer": "ctrl-alt", + "sk": [ + { + "text": "*AltShift*", + "id": "K_LCONTROL", + "sp": 1, + "nextlayer": "shift-ctrl-alt" + } + ] + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 140, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "Zero width space", + "width": 930 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 145, + "sp": 1 + } + ] + } + ] + }, + { + "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": "៎" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "ឈ", + "pad": 75 + }, + { + "id": "K_W", + "text": "ឺ" + }, + { + "id": "K_E", + "text": "ែ" + }, + { + "id": "K_R", + "text": "ើ" + }, + { + "id": "K_T", + "text": "ទ" + }, + { + "id": "K_Y", + "text": "ួ" + }, + { + "id": "K_U", + "text": "ូ" + }, + { + "id": "K_I", + "text": "ី" + }, + { + "id": "K_O", + "text": "ឿ" + }, + { + "id": "K_P", + "text": "ភ" + }, + { + "id": "K_LBRKT", + "text": "ឪ" + }, + { + "id": "K_RBRKT", + "text": "ឥ" + }, + { + "id": "T_new_309", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_A", + "text": "ៅ" + }, + { + "id": "K_S", + "text": "ឝ" + }, + { + "id": "K_D", + "text": "ឌ" + }, + { + "id": "K_F", + "text": "ធ" + }, + { + "id": "K_G", + "text": "អ" + }, + { + "id": "K_H", + "text": "៖" + }, + { + "id": "K_J", + "text": "ៜ" + }, + { + "id": "K_K", + "text": "គ" + }, + { + "id": "K_L", + "text": "ឡ" + }, + { + "id": "K_COLON", + "text": "ះ" + }, + { + "id": "K_QUOTE", + "text": "៉" + }, + { + "id": "K_BKSLASH", + "text": "ឬ" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": 160, + "sp": 2, + "nextlayer": "default" + }, + { + "id": "K_Z", + "text": "ឍ" + }, + { + "id": "K_X", + "text": "ឃ" + }, + { + "id": "K_C", + "text": "ជ" + }, + { + "id": "K_V", + "text": "ឞ" + }, + { + "id": "K_B", + "text": "ព" + }, + { + "id": "K_N", + "text": "ណ" + }, + { + "id": "K_M", + "text": "ំ" + }, + { + "id": "K_COMMA", + "text": "៝" + }, + { + "id": "K_PERIOD", + "text": "។" + }, + { + "id": "K_SLASH", + "text": "?" + }, + { + "id": "K_BKQUOTE", + "text": "~" + }, + { + "id": "T_new_335", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "*Alt*", + "width": 130, + "sp": 1, + "nextlayer": "ctrl-alt", + "sk": [ + { + "text": "*AltShift*", + "id": "K_LCONTROL", + "sp": 1, + "nextlayer": "shift-ctrl-alt" + } + ] + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 140, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "ZWJ", + "width": 930 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 145, + "sp": 1 + } + ] + } + ] + }, + { + "id": "ctrl-alt", + "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": "}" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "*", + "pad": 75 + }, + { + "id": "K_W" + }, + { + "id": "K_E", + "text": "ឯ" + }, + { + "id": "K_R", + "text": "ឫ" + }, + { + "id": "K_T", + "text": "ឦ" + }, + { + "id": "K_Y" + }, + { + "id": "K_U", + "text": "ឧ" + }, + { + "id": "K_I", + "text": "ឥ" + }, + { + "id": "K_O", + "text": "ឱ" + }, + { + "id": "K_P", + "text": "ឳ" + }, + { + "id": "K_LBRKT", + "text": "[" + }, + { + "id": "K_RBRKT", + "text": "]" + }, + { + "id": "T_new_1312", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_A", + "text": "ឩ" + }, + { + "id": "K_S", + "text": "ឪ" + }, + { + "id": "K_D", + "text": "ឣ" + }, + { + "id": "K_F", + "text": "ឤ" + }, + { + "id": "K_G", + "text": "឴" + }, + { + "id": "K_H", + "text": "឵" + }, + { + "id": "K_J", + "text": "ឮ" + }, + { + "id": "K_K", + "text": "ឭ" + }, + { + "id": "K_L", + "text": "ឰ" + }, + { + "id": "K_COLON", + "text": ";" + }, + { + "id": "K_QUOTE", + "text": "៝" + }, + { + "id": "K_BKSLASH", + "text": "៚" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": 160, + "sp": 1, + "nextlayer": "shift" + }, + { + "id": "K_Z", + "text": "#" + }, + { + "id": "K_X", + "text": "@" + }, + { + "id": "K_C", + "text": "&" + }, + { + "id": "K_V", + "text": "$" + }, + { + "id": "K_B", + "text": "%" + }, + { + "id": "K_N", + "text": "(" + }, + { + "id": "K_M", + "text": ")" + }, + { + "id": "K_COMMA", + "text": "‹" + }, + { + "id": "K_PERIOD", + "text": "›" + }, + { + "id": "K_SLASH", + "text": "៕" + }, + { + "id": "K_BKQUOTE", + "text": "៙" + }, + { + "id": "T_new_1338", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "default", + "width": 130, + "sp": 1, + "nextlayer": "default", + "sk": [ + { + "text": "*AltShift*", + "id": "K_LCONTROL", + "sp": 1, + "nextlayer": "shift-ctrl-alt" + } + ] + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 140, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "Four-per-em space", + "width": 930 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 145, + "sp": 1 + } + ] + } + ] + }, + { + "id": "shift-ctrl-alt", + "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": "᧬" + }, + { + "id": "K_BKSP", + "text": "*BkSp*", + "width": 100, + "sp": 1 + } + ] + }, + { + "id": 2, + "key": [ + { + "id": "K_Q", + "text": "᧭", + "pad": 75 + }, + { + "id": "K_W", + "text": "᧮" + }, + { + "id": "K_E", + "text": "᧯" + }, + { + "id": "K_R", + "text": "៰" + }, + { + "id": "K_T", + "text": "៱" + }, + { + "id": "K_Y", + "text": "៲" + }, + { + "id": "K_U", + "text": "៳" + }, + { + "id": "K_I", + "text": "៴" + }, + { + "id": "K_O", + "text": "៵" + }, + { + "id": "K_P", + "text": "៶" + }, + { + "id": "K_LBRKT", + "text": "៷" + }, + { + "id": "K_RBRKT", + "text": "៸" + }, + { + "id": "T_new_1743", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 3, + "key": [ + { + "id": "K_A", + "text": "᧰" + }, + { + "id": "K_S", + "text": "᧱" + }, + { + "id": "K_D", + "text": "᧲" + }, + { + "id": "K_F", + "text": "᧳" + }, + { + "id": "K_G", + "text": "᧴" + }, + { + "id": "K_H", + "text": "᧵" + }, + { + "id": "K_J", + "text": "᧶" + }, + { + "id": "K_K", + "text": "᧷" + }, + { + "id": "K_L", + "text": "᧸" + }, + { + "id": "K_COLON", + "text": "᧹" + }, + { + "id": "K_QUOTE", + "text": "᧺" + }, + { + "id": "K_BKSLASH", + "text": "៹" + } + ] + }, + { + "id": 4, + "key": [ + { + "id": "K_SHIFT", + "text": "*Shift*", + "width": 160, + "sp": 1, + "nextlayer": "shift" + }, + { + "id": "K_Z", + "text": "᧻" + }, + { + "id": "K_X", + "text": "᧼" + }, + { + "id": "K_C", + "text": "᧽" + }, + { + "id": "K_V", + "text": "᧾" + }, + { + "id": "K_B", + "text": "᧿" + }, + { + "id": "K_N", + "text": "៓" + }, + { + "id": "K_M", + "text": "៘" + }, + { + "id": "K_COMMA", + "text": "ៜ" + }, + { + "id": "K_PERIOD", + "text": "ឝ" + }, + { + "id": "K_SLASH", + "text": "ឞ" + }, + { + "id": "K_BKQUOTE", + "text": "᧠" + }, + { + "id": "T_new_1769", + "width": 10, + "sp": 10 + } + ] + }, + { + "id": 5, + "key": [ + { + "id": "K_LCONTROL", + "text": "default", + "width": 130, + "sp": 1, + "nextlayer": "default", + "sk": [ + { + "text": "*Alt*", + "id": "K_LCONTROL", + "sp": 1, + "nextlayer": "ctrl-alt" + } + ] + }, + { + "id": "K_LOPT", + "text": "*Menu*", + "width": 140, + "sp": 1 + }, + { + "id": "K_SPACE", + "text": "En space", + "width": 930 + }, + { + "id": "K_ENTER", + "text": "*Enter*", + "width": 145, + "sp": 1 + } + ] + } + ] + } + ], + "font": "Khmer Busra", + "fontsize": "" + } +} \ No newline at end of file diff --git a/developer/src/kmc-analyze/test/fixtures/khmer/sil_khmer.kvks b/developer/src/kmc-analyze/test/fixtures/khmer/sil_khmer.kvks new file mode 100644 index 00000000000..b88fe04b779 --- /dev/null +++ b/developer/src/kmc-analyze/test/fixtures/khmer/sil_khmer.kvks @@ -0,0 +1,217 @@ + + +
+ 10.0 + sil_khmer + +
+ + + ZWNJ + + + ZWJ + + + + ( + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ; + + + + + ? + ~ + ! + # + % + * + + + + Hair space + + + Thin space + + + Four-per-em space + + + { + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + ; + } + [ + + ] + + + % + & + + + + + + + + + + ) + ( + + + * + + + + + $ + @ + # + + + En space + + + + + + + + + + + + + + + + + ᧿ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Zero width space + + , + space + \ + + + + + + + + + + + + ឲ្យ + + ខ្ញុំ + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + = + + +
diff --git a/developer/src/kmc-analyze/test/helpers/index.ts b/developer/src/kmc-analyze/test/helpers/index.ts new file mode 100644 index 00000000000..2341396ee01 --- /dev/null +++ b/developer/src/kmc-analyze/test/helpers/index.ts @@ -0,0 +1,20 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * Helpers and utilities for the Mocha tests. + */ +import * as path from 'path'; +import { fileURLToPath } from 'url'; + +/** + * Builds a path to the fixture with the given path components. + * + * e.g., makePathToFixture('example.qaa.trivial') + * e.g., makePathToFixture('example.qaa.trivial', 'model.ts') + * + * @param components One or more path components. + */ + export function makePathToFixture(...components: string[]): string { + return fileURLToPath(new URL(path.join('..', '..', '..', 'test', 'fixtures', ...components), import.meta.url)); +} + diff --git a/developer/src/kmc-analyze/test/test-analyzer-messages.ts b/developer/src/kmc-analyze/test/test-analyzer-messages.ts new file mode 100644 index 00000000000..c6fced09454 --- /dev/null +++ b/developer/src/kmc-analyze/test/test-analyzer-messages.ts @@ -0,0 +1,29 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ +// import { assert } from 'chai'; +import 'mocha'; +import { AnalyzerMessages } from '../src/analyzer-messages.js'; +import { TestCompilerCallbacks, verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers'; +import { CompilerErrorNamespace } from '@keymanapp/developer-utils'; + +describe('AnalyzerMessages', function () { + + const callbacks = new TestCompilerCallbacks(); + + this.beforeEach(function() { + callbacks.clear(); + }); + + this.afterEach(function() { + if(this.currentTest?.isFailed()) { + callbacks.printMessages(); + } + }); + + it('should have a valid AnalyzerMessages object', function() { + return verifyCompilerMessagesObject(AnalyzerMessages, CompilerErrorNamespace.Analyzer); + }); + + // TODO: test each message +}); diff --git a/developer/src/kmc-analyze/test/test-osk-character-use.ts b/developer/src/kmc-analyze/test/test-osk-character-use.ts new file mode 100644 index 00000000000..dac60dcfb66 --- /dev/null +++ b/developer/src/kmc-analyze/test/test-osk-character-use.ts @@ -0,0 +1,108 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + */ +import * as fs from 'fs'; +import { assert } from 'chai'; +import 'mocha'; +import { makePathToFixture } from './helpers/index.js'; +import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js'; +import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; + +const KHMER_ANGKOR_TOUCH_LAYOUT = makePathToFixture('khmer', "khmer_angkor.keyman-touch-layout"); +const KHMER_ANGKOR_KVKS = makePathToFixture('khmer', "khmer_angkor.kvks"); +const KBDKHMR_JSON = makePathToFixture('khmer', "KbdKhmr.json"); + +const SIL_KHMER_TOUCH_LAYOUT = makePathToFixture('khmer', "sil_khmer.keyman-touch-layout"); +const SIL_KHMER_KVKS = makePathToFixture('khmer', "sil_khmer.kvks"); +const KBDKHMR_WITH_SIL_KHMER_JSON = makePathToFixture('khmer', "KbdKhmr-with-sil_khmer.json"); + +describe('AnalyzeOskCharacterUse', function () { + const callbacks = new TestCompilerCallbacks(); + + this.beforeEach(function() { + callbacks.clear(); + }); + + this.afterEach(function() { + if(this.currentTest?.isFailed()) { + callbacks.printMessages(); + } + }); + + it('generates a mapping file from 2 input files', async function() { + // functional test + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: false, + stripDottedCircle: true, + }); + + assert.isTrue(await a.analyze(KHMER_ANGKOR_TOUCH_LAYOUT)); + assert.isTrue(await a.analyze(KHMER_ANGKOR_KVKS)); + + const expected = JSON.parse(fs.readFileSync(KBDKHMR_JSON, 'utf-8')); + const actual = JSON.parse(a.getStrings(".json").join('')); + assert.deepEqual(actual, expected); + }); + + it('extends an existing mapping file with 2 more input files', async function() { + // functional test + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: false, + stripDottedCircle: true, + mergeMapFile: KBDKHMR_JSON, + }); + + assert.isTrue(await a.analyze(SIL_KHMER_TOUCH_LAYOUT)); + assert.isTrue(await a.analyze(SIL_KHMER_KVKS)); + + const expected = JSON.parse(fs.readFileSync(KBDKHMR_WITH_SIL_KHMER_JSON, 'utf-8')); + const actual = JSON.parse(a.getStrings(".json").join('')); + assert.deepEqual(actual, expected); + }); + + it('loads an existing mapping file round trip', async function() { + // functional test + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: false, + stripDottedCircle: true, + mergeMapFile: KBDKHMR_JSON, + }); + + const expected = JSON.parse(fs.readFileSync(KBDKHMR_JSON, 'utf-8')); + const actual = JSON.parse(a.getStrings(".json").join('')); + assert.deepEqual(actual, expected); + }); + + it('has no effect if the mapping has not changed', async function() { + // functional test + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: false, + stripDottedCircle: true, + mergeMapFile: KBDKHMR_JSON, + }); + + assert.isTrue(await a.analyze(KHMER_ANGKOR_TOUCH_LAYOUT)); + assert.isTrue(await a.analyze(KHMER_ANGKOR_KVKS)); + + const expected = JSON.parse(fs.readFileSync(KBDKHMR_JSON, 'utf-8')); + const actual = JSON.parse(a.getStrings(".json").join('')); + assert.deepEqual(actual, expected); + }); + + it('has no effect if the mapping has not changed, regardless of processing order', async function() { + // functional test + const a = new AnalyzeOskCharacterUse(callbacks, { + includeCounts: false, + stripDottedCircle: true, + mergeMapFile: KBDKHMR_JSON, + }); + + assert.isTrue(await a.analyze(KHMER_ANGKOR_KVKS)); + assert.isTrue(await a.analyze(KHMER_ANGKOR_TOUCH_LAYOUT)); + + const expected = JSON.parse(fs.readFileSync(KBDKHMR_JSON, 'utf-8')); + const actual = JSON.parse(a.getStrings(".json").join('')); + assert.deepEqual(actual, expected); + }); + +}); diff --git a/developer/src/kmc-analyze/test/tsconfig.json b/developer/src/kmc-analyze/test/tsconfig.json new file mode 100644 index 00000000000..01cc026dc10 --- /dev/null +++ b/developer/src/kmc-analyze/test/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../kmc/tsconfig.kmc-base.json", + + "compilerOptions": { + "rootDir": ".", + "rootDirs": ["./", "../src/"], + "outDir": "../build/test", + "baseUrl": ".", + }, + "include": [ + "**/test-*.ts", + "helpers/*.ts", + ], + "references": [ + { "path": "../" }, + { "path": "../../common/web/test-helpers/" }, + ] +} \ No newline at end of file diff --git a/developer/src/kmc/src/commands/analyze.ts b/developer/src/kmc/src/commands/analyze.ts index 5085262f07b..65119c30d93 100644 --- a/developer/src/kmc/src/commands/analyze.ts +++ b/developer/src/kmc/src/commands/analyze.ts @@ -19,6 +19,7 @@ interface AnalysisActivityOptions /* not inheriting from CompilerBaseOptions */ stripDottedCircle?: boolean; includeCounts?: boolean; mappingFile?: string; + inputMappingFile?: string; }; export function declareAnalyze(program: Command) { @@ -35,6 +36,7 @@ function declareOskCharUse(command: Command) { .option('-b, --base', 'First PUA codepoint to use, in hexadecimal (default F100)', 'F100') .option('--include-counts', 'Include number of times each character is referenced', false) .option('--strip-dotted-circle', 'Strip U+25CC (dotted circle base) from results', false) + .option('-i, --input-mapping-file ', 'Merge result file with existing mapping file') .addOption(new Option('-m, --mapping-file ', 'Result file to write to (.json, .md, or .txt)').makeOptionMandatory()) .action(async (filenames: string[], _options: any, commander: any): Promise => { const options = commander.optsWithGlobals(); @@ -95,6 +97,7 @@ async function analyzeOskCharUse(callbacks: CompilerCallbacks, filenames: string puaBase: parseInt(options.base, 16), stripDottedCircle: options.stripDottedCircle, includeCounts: options.includeCounts, + mergeMapFile: options.inputMappingFile }); if(!await runOnFiles(callbacks, filenames, analyzer.analyze.bind(analyzer))) {