mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-24 17:27:41 +00:00
Merge pull request #9075 from keymanapp/fix/developer/kmc-kmw-options-stores
fix(developer): support option stores in kmc-kmn/kmw 🗜
This commit is contained in:
commit
c3bb426ff0
15 changed files with 1049 additions and 149 deletions
|
|
@ -17,6 +17,22 @@ export interface CompilerResultFile {
|
|||
data: Uint8Array;
|
||||
};
|
||||
|
||||
//
|
||||
// Matches kmcmplibapi.h definitions
|
||||
//
|
||||
|
||||
export const STORETYPE_STORE = 0x01;
|
||||
export const STORETYPE_RESERVED = 0x02;
|
||||
export const STORETYPE_OPTION = 0x04;
|
||||
export const STORETYPE_DEBUG = 0x08;
|
||||
export const STORETYPE_CALL = 0x10;
|
||||
export const STORETYPE__MASK = 0x1F;
|
||||
|
||||
export interface CompilerResultExtraStore {
|
||||
storeType: number; // STORETYPE__MASK
|
||||
name: string; // when debug=false, the .kmx will not have store names
|
||||
};
|
||||
|
||||
export const COMPILETARGETS_KMX = 0x01;
|
||||
export const COMPILETARGETS_JS = 0x02;
|
||||
export const COMPILETARGETS__MASK = 0x03;
|
||||
|
|
@ -31,8 +47,13 @@ export interface CompilerResultExtra {
|
|||
targets: number;
|
||||
kvksFilename?: string;
|
||||
displayMapFilename?: string;
|
||||
stores?: CompilerResultExtraStore[];
|
||||
};
|
||||
|
||||
//
|
||||
// Internal in-memory result from a successful compilation
|
||||
//
|
||||
|
||||
export interface CompilerResult {
|
||||
kmx?: CompilerResultFile;
|
||||
kvk?: CompilerResultFile;
|
||||
|
|
@ -163,6 +184,24 @@ export class KmnCompiler implements UnicodeSetParser {
|
|||
return 1;
|
||||
}
|
||||
|
||||
private copyWasmResult(wasm_result: any): CompilerResult {
|
||||
let result: CompilerResult = {
|
||||
// We cannot Object.assign or {...} on a wasm-defined object, so...
|
||||
extra: {
|
||||
targets: wasm_result.extra.targets,
|
||||
displayMapFilename: wasm_result.extra.displayMapFilename,
|
||||
kvksFilename: wasm_result.extra.kvksFilename,
|
||||
stores: []
|
||||
},
|
||||
displayMap: null
|
||||
};
|
||||
for(let store of wasm_result.extra.stores) {
|
||||
result.extra.stores.push({storeType: store.storeType, name: store.name});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public runCompiler(infile: string, outfile: string, options: KmnCompilerOptions): CompilerResult {
|
||||
if(!this.verifyInitialized()) {
|
||||
/* c8 ignore next 2 */
|
||||
|
|
@ -191,15 +230,7 @@ export class KmnCompiler implements UnicodeSetParser {
|
|||
return null;
|
||||
}
|
||||
|
||||
const result: CompilerResult = {
|
||||
// We cannot Object.assign or {...} on a wasm-defined object, so...
|
||||
extra: {
|
||||
targets: wasm_result.extra.targets,
|
||||
displayMapFilename: wasm_result.extra.displayMapFilename,
|
||||
kvksFilename: wasm_result.extra.kvksFilename,
|
||||
},
|
||||
displayMap: null
|
||||
};
|
||||
const result: CompilerResult = this.copyWasmResult(wasm_result);
|
||||
|
||||
if(result.extra.targets & COMPILETARGETS_KMX) {
|
||||
result.kmx = {
|
||||
|
|
@ -234,15 +265,8 @@ export class KmnCompiler implements UnicodeSetParser {
|
|||
if(!wasm_result.result) {
|
||||
return null;
|
||||
}
|
||||
const kmw_result: CompilerResult = {
|
||||
extra: {
|
||||
// We cannot Object.assign or {...} on a wasm-defined object, so...
|
||||
targets: wasm_result.extra.targets,
|
||||
displayMapFilename: wasm_result.extra.displayMapFilename,
|
||||
kvksFilename: wasm_result.extra.kvksFilename,
|
||||
},
|
||||
displayMap: result.displayMap // we can safely re-use the kmx compile displayMap
|
||||
};
|
||||
const kmw_result: CompilerResult = this.copyWasmResult(wasm_result);
|
||||
kmw_result.displayMap = result.displayMap; // we can safely re-use the kmx compile displayMap
|
||||
|
||||
let web_kmx = new Uint8Array(Module.HEAP8.buffer, wasm_result.kmx, wasm_result.kmxSize)
|
||||
result.js = this.runWebCompiler(infile, outfile, web_kmx, result.kvk?.data, kmw_result, options);
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ KMXCodeNames: string[] = [
|
|||
|
||||
export const
|
||||
USEnglishUnshift: string = ' `' + '1234567890' + '-' + '=' + 'qwertyuiop' + '[' + ']' + '\\' + 'asdfghjkl' + ';' + '\'' + 'zxcvbnm' + ',' + '.' + '/',
|
||||
USEnglishShift: string = 0xFF + '~' + '!@#$%^&*()' + '_' + '+' + 'QWERTYUIOP' + '{' + '}' + '|' + 'ASDFGHJKL' + ':' + '"' + 'ZXCVBNM' + '<' + '>' + '?',
|
||||
USEnglishValues: string = 0x20 + 0xc0 + '1234567890' + 0xbd + 0xbb + 'QWERTYUIOP' + 0xdb + 0xdd + 0xdc + 'ASDFGHJKL' + 0xba + 0xde + 'ZXCVBNM' + 0xbc + 0xbe + 0xbf,
|
||||
USEnglishShift: string = '\u00FF' + '~' + '!@#$%^&*()' + '_' + '+' + 'QWERTYUIOP' + '{' + '}' + '|' + 'ASDFGHJKL' + ':' + '"' + 'ZXCVBNM' + '<' + '>' + '?',
|
||||
USEnglishValues: string = '\u0020' + '\u00c0' + '1234567890' + '\u00bd' + '\u00bb' + 'QWERTYUIOP' + '\u00db' + '\u00dd' + '\u00dc' + 'ASDFGHJKL' + '\u00ba' + '\u00de' + 'ZXCVBNM' + '\u00bc' + '\u00be' + '\u00bf',
|
||||
UnreachableKeyCodes: number[] = [ // I4141
|
||||
0x00, // &H0
|
||||
0x01, //VK_LBUTTON, // &H1
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { JavaScript_ContextMatch, JavaScript_KeyAsString, JavaScript_Name, JavaS
|
|||
import { KmwCompilerMessages } from "./messages.js";
|
||||
import { ValidateLayoutFile } from "./validate-layout-file.js";
|
||||
import { VisualKeyboardFromFile } from "./visual-keyboard-compiler.js";
|
||||
import { CompilerResult } from "src/compiler/compiler.js";
|
||||
import { CompilerResult, STORETYPE_DEBUG, STORETYPE_OPTION, STORETYPE_RESERVED } from "../compiler/compiler.js";
|
||||
|
||||
function requote(s: string): string {
|
||||
return "'" + s.replaceAll(/(['\\])/, "\\$1") + "'";
|
||||
|
|
@ -34,7 +34,14 @@ export function RequotedString(s: string, RequoteSingleQuotes: boolean = false):
|
|||
return s;
|
||||
}
|
||||
|
||||
export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: string, keyboardData: Uint8Array, kvkData: Uint8Array, kmxResult: CompilerResult, FDebug: boolean = false): string {
|
||||
export function WriteCompiledKeyboard(
|
||||
callbacks: CompilerCallbacks,
|
||||
kmnfile: string,
|
||||
keyboardData: Uint8Array,
|
||||
kvkData: Uint8Array,
|
||||
kmxResult: CompilerResult,
|
||||
FDebug: boolean = false
|
||||
): string {
|
||||
let opts: CompilerOptions = {
|
||||
shouldAddCompilerVersion: false,
|
||||
saveDebug: FDebug
|
||||
|
|
@ -217,18 +224,10 @@ export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: str
|
|||
result += `${FTabStop}this.KCSS="${RequotedString(sEmbedCSS)}";${nl}`;
|
||||
}
|
||||
|
||||
function isDebugStore(fsp: KMX.STORE) {
|
||||
return fsp.dwSystemID == KMX.KMXFile.TSS_DEBUG_LINE;
|
||||
}
|
||||
|
||||
function isReservedStore(fsp: KMX.STORE) {
|
||||
return fsp.dwSystemID != KMX.KMXFile.TSS_NONE;
|
||||
}
|
||||
|
||||
function isOptionStore(fsp: KMX.STORE) {
|
||||
// TODO: how do we determine this, see CheckStoreUsage()
|
||||
return false;
|
||||
}
|
||||
const isStoreType = (index:number, type: number) => !!(kmxResult.extra.stores[index].storeType & type);
|
||||
const isDebugStore = (index: number) => isStoreType(index, STORETYPE_DEBUG);
|
||||
const isReservedStore = (index: number) => isStoreType(index, STORETYPE_RESERVED);
|
||||
const isOptionStore = (index: number) => isStoreType(index, STORETYPE_OPTION);
|
||||
|
||||
// Write the stores out
|
||||
FOptionStores = '';
|
||||
|
|
@ -236,7 +235,7 @@ export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: str
|
|||
let fsp = keyboard.stores[i];
|
||||
// I3438 - Save all system stores to the keyboard, for now // I3684
|
||||
|
||||
if (!isDebugStore(fsp)) { // and not (fsp.dwSystemID in [TSS_BITMAP, TSS_NAME, TSS_VERSION, TSS_CUSTOMKEYMANEDITION, TSS_CUSTOMKEYMANEDITIONNAME, TSS_KEYMANCOPYRIGHT]) then
|
||||
if (!isDebugStore(i)) { // and not (fsp.dwSystemID in [TSS_BITMAP, TSS_NAME, TSS_VERSION, TSS_CUSTOMKEYMANEDITION, TSS_CUSTOMKEYMANEDITIONNAME, TSS_KEYMANCOPYRIGHT]) then
|
||||
if (fsp.dwSystemID == KMX.KMXFile.TSS_COMPARISON) {
|
||||
result += `${FTabStop}this.s${JavaScript_Name(i, fsp.dpName)}=${JavaScript_Store(keyboard, 0/*fsp.line*/, fsp.dpString)};${nl}`;
|
||||
}
|
||||
|
|
@ -245,14 +244,14 @@ export function WriteCompiledKeyboard(callbacks: CompilerCallbacks, kmnfile: str
|
|||
}
|
||||
//else if fsp.dwSystemID = TSS_VKDICTIONARY then // I3438, required for vkdictionary
|
||||
// Result := Result + Format('%sthis.s%s=%s;%s', [FTabStop, JavaScript_Name(i, fsp.szName), JavaScript_Store(fsp.line, fsp.dpString), nl])
|
||||
else if (isOptionStore(fsp) && !isReservedStore(fsp)) {
|
||||
else if (isOptionStore(i) && !isReservedStore(i)) {
|
||||
result += `${FTabStop}this.s${JavaScript_Name(i,fsp.dpName)}=KeymanWeb.KLOAD(this.KI,"${JavaScript_Name(i,fsp.dpName,true)}",`+
|
||||
`${JavaScript_Store(keyboard, 0/*fsp.line*/, fsp.dpString)});${nl}`;
|
||||
|
||||
if (FOptionStores != '') {
|
||||
FOptionStores += ',';
|
||||
}
|
||||
FOptionStores += `'s${JavaScript_Name(i, fsp.dpName)}`;
|
||||
FOptionStores += `'s${JavaScript_Name(i, fsp.dpName)}'`;
|
||||
}
|
||||
else if (fsp.dwSystemID == KMX.KMXFile.TSS_NONE /* aka not fsp.fIsReserved */) {
|
||||
result += `${FTabStop}this.s${JavaScript_Name(i, fsp.dpName)}=${JavaScript_Store(keyboard, 0/*fsp.line*/, fsp.dpString)};${nl}`; // I3681
|
||||
|
|
|
|||
17
developer/src/kmc-kmn/test/fixtures/kmw/build_fixtures.bat
vendored
Normal file
17
developer/src/kmc-kmn/test/fixtures/kmw/build_fixtures.bat
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
@echo off
|
||||
echo Compiles the keyboards using the legacy kmcomp.exe
|
||||
echo to use as baseline comparisons for kmc kmw module
|
||||
rem we run for the .kmx first even though we don't use them because the legacy
|
||||
rem cmdline web compiler has a bit of an issue generating the VK properly if we
|
||||
rem build the .kmn directly and haven't already built the .kmx (which generates
|
||||
rem the .kvk that the web compiler is expecting). This doesn't happen in project
|
||||
rem mode because the .kmx is always built first. Probably won't fix this because
|
||||
rem legacy compiler is being replaced anyway.
|
||||
for %%d in (*.kmn) do ..\..\..\..\..\bin\kmcomp -no-compiler-version -d %%d %%~nd.kmx
|
||||
for %%d in (*.kmn) do ..\..\..\..\..\bin\kmcomp -no-compiler-version -d %%d %%~nd.js
|
||||
rem ok, we no longer need .kmx and .kvk once we've built the .js fixtures
|
||||
del *.kmx
|
||||
rem We can't do `del *.kvk` because that also deletes *.kvks, thanks 8.3
|
||||
rem filenames! But the following horror works:
|
||||
for %%d in (*.kvk) do if %%~xd == .kvk del %%d
|
||||
|
||||
699
developer/src/kmc-kmn/test/fixtures/kmw/test_keychars.js
vendored
Normal file
699
developer/src/kmc-kmn/test/fixtures/kmw/test_keychars.js
vendored
Normal file
|
|
@ -0,0 +1,699 @@
|
|||
if(typeof keyman === 'undefined') {
|
||||
console.log('Keyboard requires KeymanWeb 10.0 or later');
|
||||
if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");
|
||||
} else {
|
||||
KeymanWeb.KR(new Keyboard_test_keychars());
|
||||
}
|
||||
function Keyboard_test_keychars()
|
||||
{
|
||||
var modCodes = keyman.osk.modifierCodes;
|
||||
var keyCodes = keyman.osk.keyCodes;
|
||||
|
||||
this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;
|
||||
this.KI="Keyboard_test_keychars";
|
||||
this.KN="test_keychars";
|
||||
this.KMINVER="10.0";
|
||||
this.KV=null;
|
||||
this.KDU=0;
|
||||
this.KH='';
|
||||
this.KM=0;
|
||||
this.KBVER="1.0";
|
||||
this.KMBM=modCodes.SHIFT /* 0x0010 */;
|
||||
this.s_letter_6=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
this.KVS=[];
|
||||
this.gs=function(t,e) {
|
||||
return this.g_Main_0(t,e);
|
||||
};
|
||||
this.gs=function(t,e) {
|
||||
return this.g_Main_0(t,e);
|
||||
};
|
||||
this.g_Main_0=function(t,e) {
|
||||
var k=KeymanWeb,r=0,m=0;
|
||||
if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_SPACE /* 0x20 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"- -");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_1 /* 0x31 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-!-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_QUOTE /* 0xDE */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-\"-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_3 /* 0x33 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-#-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_4 /* 0x34 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-$-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_5 /* 0x35 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-%-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_7 /* 0x37 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-&-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_QUOTE /* 0xDE */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-'-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_9 /* 0x39 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-(-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_0 /* 0x30 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-)-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_8 /* 0x38 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-*-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_EQUAL /* 0xBB */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-+-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_COMMA /* 0xBC */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-,-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_HYPHEN /* 0xBD */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"---");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_PERIOD /* 0xBE */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-.-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_SLASH /* 0xBF */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-/-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_0 /* 0x30 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-0-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_1 /* 0x31 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-1-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_2 /* 0x32 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-2-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_3 /* 0x33 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-3-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_4 /* 0x34 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-4-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_5 /* 0x35 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-5-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_6 /* 0x36 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-6-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_7 /* 0x37 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-7-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_8 /* 0x38 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-8-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_9 /* 0x39 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-9-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_COLON /* 0xBA */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-:-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_COLON /* 0xBA */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-;-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_COMMA /* 0xBC */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-<-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_EQUAL /* 0xBB */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-=-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_PERIOD /* 0xBE */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"->-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_SLASH /* 0xBF */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-?-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_2 /* 0x32 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-@-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_A /* 0x41 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-A-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_B /* 0x42 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-B-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_C /* 0x43 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-C-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_D /* 0x44 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-D-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_E /* 0x45 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-E-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_F /* 0x46 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-F-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_G /* 0x47 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-G-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_H /* 0x48 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-H-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_I /* 0x49 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-I-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_J /* 0x4A */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-J-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_K /* 0x4B */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-K-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_L /* 0x4C */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-L-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_M /* 0x4D */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-M-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_N /* 0x4E */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-N-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_O /* 0x4F */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-O-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_P /* 0x50 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-P-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_Q /* 0x51 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-Q-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_R /* 0x52 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-R-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_S /* 0x53 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-S-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_T /* 0x54 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-T-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_U /* 0x55 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-U-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_V /* 0x56 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-V-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_W /* 0x57 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-W-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_X /* 0x58 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-X-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_Y /* 0x59 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-Y-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_Z /* 0x5A */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-Z-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_LBRKT /* 0xDB */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-[-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_BKSLASH /* 0xDC */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-\\-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_RBRKT /* 0xDD */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-]-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_6 /* 0x36 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-^-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_HYPHEN /* 0xBD */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-_-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_BKQUOTE /* 0xC0 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-`-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_A /* 0x41 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-a-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_B /* 0x42 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-b-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_C /* 0x43 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-c-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_D /* 0x44 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-d-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_E /* 0x45 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-e-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_F /* 0x46 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-f-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_G /* 0x47 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-g-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_H /* 0x48 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-h-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_I /* 0x49 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-i-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_J /* 0x4A */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-j-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_K /* 0x4B */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-k-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_L /* 0x4C */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-l-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_M /* 0x4D */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-m-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_N /* 0x4E */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-n-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_O /* 0x4F */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-o-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_P /* 0x50 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-p-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_Q /* 0x51 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-q-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_R /* 0x52 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-r-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_S /* 0x53 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-s-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_T /* 0x54 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-t-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_U /* 0x55 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-u-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_V /* 0x56 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-v-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_W /* 0x57 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-w-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_X /* 0x58 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-x-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_Y /* 0x59 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-y-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_Z /* 0x5A */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-z-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_LBRKT /* 0xDB */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-{-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_BKSLASH /* 0xDC */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-|-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_RBRKT /* 0xDD */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-}-");
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_BKQUOTE /* 0xC0 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"-~-");
|
||||
}
|
||||
}
|
||||
return r;
|
||||
};
|
||||
}
|
||||
14
developer/src/kmc-kmn/test/fixtures/kmw/test_keychars.kmn
vendored
Normal file
14
developer/src/kmc-kmn/test/fixtures/kmw/test_keychars.kmn
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
c Verifies every letter on the US English keyboard, ensuring
|
||||
c that our mapping tables are correct
|
||||
|
||||
store(&NAME) 'test_keychars'
|
||||
store(&version) '10.0'
|
||||
store(&targets) 'any'
|
||||
|
||||
begin Unicode > use(Main)
|
||||
|
||||
group(Main) using keys
|
||||
|
||||
store(letter) ' !"#$%&' "'" '()*+,-./' '0'..'9' ':;<=>?@' 'A'..'Z' '[\]^_`' 'a'..'z' '{|}~'
|
||||
|
||||
+ any(letter) > '-' index(letter, 1) '-'
|
||||
64
developer/src/kmc-kmn/test/fixtures/kmw/test_options.js
vendored
Normal file
64
developer/src/kmc-kmn/test/fixtures/kmw/test_options.js
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
if(typeof keyman === 'undefined') {
|
||||
console.log('Keyboard requires KeymanWeb 10.0 or later');
|
||||
if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");
|
||||
} else {
|
||||
KeymanWeb.KR(new Keyboard_test_options());
|
||||
}
|
||||
function Keyboard_test_options()
|
||||
{
|
||||
var modCodes = keyman.osk.modifierCodes;
|
||||
var keyCodes = keyman.osk.keyCodes;
|
||||
|
||||
this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9;
|
||||
this.KI="Keyboard_test_options";
|
||||
this.KN="test_options";
|
||||
this.KMINVER="10.0";
|
||||
this.KV=null;
|
||||
this.KDU=0;
|
||||
this.KH='';
|
||||
this.KM=0;
|
||||
this.KBVER="1.0";
|
||||
this.KMBM=0 /* 0x0000 */;
|
||||
this.s_foo_5=KeymanWeb.KLOAD(this.KI,"foo","0");
|
||||
this.s8="1";
|
||||
this.s9="0";
|
||||
this.s10="1";
|
||||
this.s11="0";
|
||||
this.KVS=['s_foo_5'];
|
||||
this.gs=function(t,e) {
|
||||
return this.g_Main_0(t,e);
|
||||
};
|
||||
this.gs=function(t,e) {
|
||||
return this.g_Main_0(t,e);
|
||||
};
|
||||
this.g_Main_0=function(t,e) {
|
||||
var k=KeymanWeb,r=0,m=0;
|
||||
if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_0 /* 0x30 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 16
|
||||
k.KDC(0,t);
|
||||
this.s_foo_5=this.s11;
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_1 /* 0x31 */)) {
|
||||
if(1){
|
||||
r=m=1; // Line 15
|
||||
k.KDC(0,t);
|
||||
this.s_foo_5=this.s10;
|
||||
}
|
||||
}
|
||||
else if(k.KKM(e, modCodes.VIRTUAL_KEY /* 0x4000 */, keyCodes.K_A /* 0x41 */)) {
|
||||
if(this.s_foo_5===this.s8){
|
||||
r=m=1; // Line 13
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"foo.");
|
||||
}
|
||||
else if(this.s_foo_5===this.s9){
|
||||
r=m=1; // Line 14
|
||||
k.KDC(0,t);
|
||||
k.KO(-1,t,"no foo.");
|
||||
}
|
||||
}
|
||||
return r;
|
||||
};
|
||||
}
|
||||
16
developer/src/kmc-kmn/test/fixtures/kmw/test_options.kmn
vendored
Normal file
16
developer/src/kmc-kmn/test/fixtures/kmw/test_options.kmn
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
c Adapted from common baseline test keyboard k_021__options.kmn
|
||||
|
||||
store(&NAME) 'test_options'
|
||||
store(&version) '10.0'
|
||||
store(&targets) 'any'
|
||||
|
||||
store(foo) '0'
|
||||
|
||||
begin Unicode > use(Main)
|
||||
|
||||
group(Main) using keys
|
||||
|
||||
if(foo = '1') + 'a' > 'foo.'
|
||||
if(foo = '0') + 'a' > 'no foo.'
|
||||
+ '1' > set(foo = '1')
|
||||
+ '0' > set(foo = '0')
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import fs from 'fs';
|
||||
import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers';
|
||||
import { KmnCompiler } from '../../src/compiler/compiler.js';
|
||||
import { extractTouchLayout } from './util.js';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url)).replace(/\\/g, '/');
|
||||
const fixturesDir = __dirname + '/../../../test/fixtures/kmw/';
|
||||
const fixtureName = fixturesDir + 'khmer_angkor.js';
|
||||
const infile = fixturesDir + 'khmer_angkor.kmn';
|
||||
const outfile = fixturesDir + 'khmer_angkor.kmx'; // intermediate outfile
|
||||
const testOutfile = fixturesDir + 'khmer_angkor.test.js';
|
||||
|
||||
if(fs.existsSync(testOutfile)) {
|
||||
fs.unlinkSync(testOutfile);
|
||||
}
|
||||
|
||||
const callbacks = new TestCompilerCallbacks();
|
||||
|
||||
const kmnCompiler = new KmnCompiler();
|
||||
if(!await kmnCompiler.init(callbacks)) {
|
||||
console.error('kmx compiler failed to init');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let result = kmnCompiler.runCompiler(infile, outfile, {
|
||||
shouldAddCompilerVersion: false,
|
||||
saveDebug: true, // TODO: we should probably use passed debug flag
|
||||
});
|
||||
|
||||
if(!result) {
|
||||
callbacks.printMessages();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const js = new TextDecoder().decode(result.js.data);
|
||||
|
||||
callbacks.printMessages();
|
||||
|
||||
const fjs = fs.readFileSync(fixtureName, 'utf8');
|
||||
|
||||
const expected = extractTouchLayout(fjs);
|
||||
const actual = extractTouchLayout(js);
|
||||
|
||||
if(expected.js !== actual.js) {
|
||||
fs.writeFileSync(testOutfile, js);
|
||||
console.error('JS not equal');
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
import 'mocha';
|
||||
import { assert } from 'chai';
|
||||
// import sinonChai from 'sinon-chai';
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import fs from 'fs';
|
||||
import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers';
|
||||
import { KmnCompiler } from '../../src/compiler/compiler.js';
|
||||
import { extractTouchLayout } from './util.js';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url)).replace(/\\/g, '/');
|
||||
const fixturesDir = __dirname + '/../../../test/fixtures/kmw/';
|
||||
//const baselineDir = __dirname + '/../../../../../common/test/keyboards/baseline/';
|
||||
// chai.use(sinonChai);
|
||||
|
||||
describe('Compiler class', function() {
|
||||
const callbacks = new TestCompilerCallbacks();
|
||||
|
||||
this.afterEach(function() {
|
||||
callbacks.printMessages();
|
||||
callbacks.clear();
|
||||
});
|
||||
|
||||
it('should compile a basic keyboard', async function() {
|
||||
// const compiler = new KeymanWebCompiler(callbacks, {addCompilerVersion: false, debug: true});
|
||||
|
||||
const fixtureName = fixturesDir + 'khmer_angkor.js';
|
||||
const infile = fixturesDir + 'khmer_angkor.kmn';
|
||||
const outfile = fixturesDir + 'khmer_angkor.kmx'; // intermediate outfile
|
||||
const testOutfile = fixturesDir + 'khmer_angkor.test.js';
|
||||
|
||||
if(fs.existsSync(testOutfile)) {
|
||||
fs.unlinkSync(testOutfile);
|
||||
}
|
||||
|
||||
const kmnCompiler = new KmnCompiler();
|
||||
assert.isTrue(await kmnCompiler.init(callbacks));
|
||||
|
||||
let result = kmnCompiler.runCompiler(infile, outfile, {
|
||||
shouldAddCompilerVersion: false,
|
||||
saveDebug: true, // TODO: we should probably use passed debug flag
|
||||
});
|
||||
|
||||
assert.isNotNull(result);
|
||||
|
||||
const js = new TextDecoder().decode(result.js.data);
|
||||
|
||||
const fjs = fs.readFileSync(fixtureName, 'utf8');
|
||||
|
||||
const expected = extractTouchLayout(fjs);
|
||||
const actual = extractTouchLayout(js);
|
||||
|
||||
fs.writeFileSync(testOutfile + '.strip.js', actual.js);
|
||||
fs.writeFileSync(fixtureName + '.strip.js', expected.js);
|
||||
fs.writeFileSync(testOutfile, js);
|
||||
|
||||
assert.deepEqual(actual.js, expected.js);
|
||||
assert.deepEqual(JSON.parse(actual.touchLayout), JSON.parse(expected.touchLayout));
|
||||
});
|
||||
});
|
||||
92
developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts
Normal file
92
developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import 'mocha';
|
||||
import { assert } from 'chai';
|
||||
// import sinonChai from 'sinon-chai';
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import fs from 'fs';
|
||||
import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers';
|
||||
import { CompilerResult, KmnCompiler } from '../../src/compiler/compiler.js';
|
||||
import { ETLResult, extractTouchLayout as parseWebTestResult } from './util.js';
|
||||
import { KeymanFileTypes } from '@keymanapp/common-types';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url)).replace(/\\/g, '/');
|
||||
const fixturesDir = __dirname + '/../../../test/fixtures/kmw/';
|
||||
//const baselineDir = __dirname + '/../../../../../common/test/keyboards/baseline/';
|
||||
// chai.use(sinonChai);
|
||||
|
||||
const debug=false;
|
||||
|
||||
const generateTestFilenames = (id: string) => ({
|
||||
fixture: fixturesDir + id + KeymanFileTypes.Binary.WebKeyboard,
|
||||
source: fixturesDir + id + KeymanFileTypes.Source.KeymanKeyboard,
|
||||
intermediate: fixturesDir + id + KeymanFileTypes.Binary.Keyboard,
|
||||
binary: fixturesDir + id + '.test' + KeymanFileTypes.Binary.WebKeyboard
|
||||
});
|
||||
|
||||
describe('KeymanWeb Compiler', function() {
|
||||
const callbacks = new TestCompilerCallbacks();
|
||||
const kmnCompiler: KmnCompiler = new KmnCompiler();
|
||||
|
||||
this.beforeAll(async function() {
|
||||
assert.isTrue(await kmnCompiler.init(callbacks));
|
||||
});
|
||||
|
||||
this.afterEach(function() {
|
||||
callbacks.printMessages();
|
||||
callbacks.clear();
|
||||
});
|
||||
|
||||
it('should compile a complex keyboard', async function() {
|
||||
run_test_keyboard(kmnCompiler, 'khmer_angkor');
|
||||
});
|
||||
|
||||
it('should handle option stores', async function() {
|
||||
//
|
||||
// This is enough to verify that the option store is set appropriately with
|
||||
// KLOAD because the fixture has that code present:
|
||||
//
|
||||
// this.s_foo_6=KeymanWeb.KLOAD(this.KI,"foo","0");
|
||||
//
|
||||
run_test_keyboard(kmnCompiler, 'test_options');
|
||||
});
|
||||
|
||||
it('should translate every "character style" key correctly', async function() {
|
||||
//
|
||||
// This is enough to verify that every character style key is encoded in the
|
||||
// same way as the fixture.
|
||||
//
|
||||
run_test_keyboard(kmnCompiler, 'test_keychars');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function run_test_keyboard(kmnCompiler: KmnCompiler, id: string): { result: CompilerResult, actualCode: string, actual: ETLResult, expectedCode: string, expected: ETLResult } {
|
||||
const filenames = generateTestFilenames(id);
|
||||
|
||||
let result = kmnCompiler.runCompiler(filenames.source, filenames.intermediate, {
|
||||
shouldAddCompilerVersion: false,
|
||||
saveDebug: true,
|
||||
});
|
||||
assert.isNotNull(result);
|
||||
|
||||
let value = {
|
||||
result,
|
||||
actualCode: new TextDecoder().decode(result.js.data),
|
||||
expectedCode: fs.readFileSync(filenames.fixture, 'utf8'),
|
||||
expected: <ETLResult>null,
|
||||
actual: <ETLResult>null,
|
||||
};
|
||||
value.actual = parseWebTestResult(value.actualCode);
|
||||
value.expected = parseWebTestResult(value.expectedCode);
|
||||
assert.deepEqual(value.actual.js, value.expected.js);
|
||||
assert.deepEqual(JSON.parse(value.actual.touchLayout), JSON.parse(value.expected.touchLayout));
|
||||
|
||||
if(debug) {
|
||||
// This is mostly to allow us to verify that parseWebTestResult is doing what we want
|
||||
fs.writeFileSync(filenames.binary + '.strip.js', value.actual.js);
|
||||
fs.writeFileSync(filenames.fixture + '.strip.js', value.expected.js);
|
||||
fs.writeFileSync(filenames.binary, value.actualCode);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
interface ETLResult {
|
||||
export interface ETLResult {
|
||||
js: string;
|
||||
touchLayout: string;
|
||||
}
|
||||
|
|
@ -7,7 +7,10 @@ interface ETLResult {
|
|||
export function extractTouchLayout(js: string): ETLResult|null {
|
||||
let m = /KVKL=(?<kvkl>.+?);[\r\n]/ds.exec(js);
|
||||
if(!m) {
|
||||
return null;
|
||||
return {
|
||||
js: js,
|
||||
touchLayout: 'null'
|
||||
};
|
||||
}
|
||||
|
||||
let kvkl = (<any>m).indices.groups.kvkl;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
|
|
@ -30,6 +31,22 @@ struct KMCMP_COMPILER_OPTIONS {
|
|||
int target; // CKF_KEYMAN, CKF_KEYMANWEB
|
||||
};
|
||||
|
||||
//
|
||||
// Additional metadata passed sideband from compiler result
|
||||
//
|
||||
|
||||
#define STORETYPE_STORE 0x01
|
||||
#define STORETYPE_RESERVED 0x02
|
||||
#define STORETYPE_OPTION 0x04
|
||||
#define STORETYPE_DEBUG 0x08
|
||||
#define STORETYPE_CALL 0x10
|
||||
#define STORETYPE__MASK 0x1F
|
||||
|
||||
struct KMCMP_COMPILER_RESULT_EXTRA_STORE {
|
||||
int storeType; // STORETYPE__MASK
|
||||
std::string name; // when debug=false, the .kmx will not have store names
|
||||
};
|
||||
|
||||
#define COMPILETARGETS_KMX 0x01
|
||||
#define COMPILETARGETS_JS 0x02
|
||||
#define COMPILETARGETS__MASK 0x03
|
||||
|
|
@ -39,6 +56,7 @@ struct KMCMP_COMPILER_RESULT_EXTRA {
|
|||
std::string kmnFilename;
|
||||
std::string kvksFilename;
|
||||
std::string displayMapFilename;
|
||||
std::vector<KMCMP_COMPILER_RESULT_EXTRA_STORE> stores;
|
||||
};
|
||||
|
||||
struct KMCMP_COMPILER_RESULT {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@
|
|||
#include "CompileKeyboardBuffer.h"
|
||||
#include "../../../../common/windows/cpp/include/keymanversion.h"
|
||||
|
||||
namespace kmcmp {
|
||||
void CopyExtraData(PFILE_KEYBOARD fk);
|
||||
};
|
||||
|
||||
bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk)
|
||||
{
|
||||
PKMX_WCHAR str, p;
|
||||
|
|
@ -45,6 +49,7 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk)
|
|||
fk->extra->targets = COMPILETARGETS_KMX;
|
||||
fk->extra->kvksFilename = "";
|
||||
fk->extra->displayMapFilename = "";
|
||||
fk->extra->stores.clear();
|
||||
/* fk->szMessage[0] = 0;
|
||||
fk->szLanguageName[0] = 0;*/
|
||||
fk->dwBitmapSize = 0;
|
||||
|
|
@ -158,5 +163,26 @@ bool CompileKeyboardBuffer(KMX_BYTE* infile, int sz, PFILE_KEYBOARD fk)
|
|||
/* Flag presence of deprecated features */
|
||||
kmcmp::CheckForDeprecatedFeatures(fk);
|
||||
|
||||
/* Extract extra metadata for callers */
|
||||
kmcmp::CopyExtraData(fk);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
namespace kmcmp {
|
||||
void CopyExtraData(PFILE_KEYBOARD fk) {
|
||||
/* Copy stores */
|
||||
PFILE_STORE store = fk->dpStoreArray;
|
||||
for(int i = 0; i < fk->cxStoreArray; i++, store++) {
|
||||
KMCMP_COMPILER_RESULT_EXTRA_STORE extraStore;
|
||||
extraStore.storeType =
|
||||
(store->fIsStore ? STORETYPE_STORE : 0) |
|
||||
(store->fIsReserved ? STORETYPE_RESERVED : 0) |
|
||||
(store->fIsOption ? STORETYPE_OPTION : 0) |
|
||||
(store->fIsDebug ? STORETYPE_DEBUG : 0) |
|
||||
(store->fIsCall ? STORETYPE_CALL : 0);
|
||||
extraStore.name = string_from_u16string(store->szName);
|
||||
fk->extra->stores.push_back(extraStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -79,6 +79,38 @@ WASM_COMPILER_RESULT kmcmp_wasm_compile(std::string pszInfile, const KMCMP_COMPI
|
|||
return r;
|
||||
}
|
||||
|
||||
// This little bit of magic gives us implicit bindings for any `std::vector`,
|
||||
// so long as we bind `emscripten::value_object<T>`, and comes from:
|
||||
// https://github.com/emscripten-core/emscripten/issues/11070#issuecomment-717675128
|
||||
namespace emscripten {
|
||||
namespace internal {
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
struct BindingType<std::vector<T, Allocator>> {
|
||||
using ValBinding = BindingType<val>;
|
||||
using WireType = ValBinding::WireType;
|
||||
|
||||
static WireType toWireType(const std::vector<T, Allocator> &vec) {
|
||||
return ValBinding::toWireType(val::array(vec));
|
||||
}
|
||||
|
||||
static std::vector<T, Allocator> fromWireType(WireType value) {
|
||||
return vecFromJSArray<T>(ValBinding::fromWireType(value));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TypeID<T,
|
||||
typename std::enable_if_t<std::is_same<
|
||||
typename Canonicalized<T>::type,
|
||||
std::vector<typename Canonicalized<T>::type::value_type,
|
||||
typename Canonicalized<T>::type::allocator_type>>::value>> {
|
||||
static constexpr TYPEID get() { return TypeID<val>::get(); }
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace emscripten
|
||||
|
||||
EMSCRIPTEN_BINDINGS(compiler_interface) {
|
||||
|
||||
emscripten::class_<KMCMP_COMPILER_OPTIONS>("CompilerOptions")
|
||||
|
|
@ -109,6 +141,12 @@ EMSCRIPTEN_BINDINGS(compiler_interface) {
|
|||
.property("kmnFilename", &KMCMP_COMPILER_RESULT_EXTRA::kmnFilename)
|
||||
.property("kvksFilename", &KMCMP_COMPILER_RESULT_EXTRA::kvksFilename)
|
||||
.property("displayMapFilename", &KMCMP_COMPILER_RESULT_EXTRA::displayMapFilename)
|
||||
.property("stores", &KMCMP_COMPILER_RESULT_EXTRA::stores)
|
||||
;
|
||||
|
||||
emscripten::value_object<KMCMP_COMPILER_RESULT_EXTRA_STORE>("CompilerResultExtraStore")
|
||||
.field("storeType", &KMCMP_COMPILER_RESULT_EXTRA_STORE::storeType)
|
||||
.field("name", &KMCMP_COMPILER_RESULT_EXTRA_STORE::name)
|
||||
;
|
||||
|
||||
emscripten::function("kmcmp_compile", &kmcmp_wasm_compile);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue