<commit_before>namespace com.keyman.keyboards {
  type KeyDistribution = text.KeyDistribution;


  export class ActiveKey implements LayoutKey {

    static readonly DEFAULT_PAD=15;          // Padding to left of key, in virtual units
    static readonly DEFAULT_RIGHT_MARGIN=15; // Padding to right of right-most key, in virtual units
    static readonly DEFAULT_KEY_WIDTH=100;   // Width of a key, if not specified, in virtual units

    // Defines key defaults
    static readonly DEFAULT_KEY = {
      text: '',
      width: ActiveKey.DEFAULT_KEY_WIDTH.toString(),
      sp: '0',
      pad: ActiveKey.DEFAULT_PAD.toString()
    };

    id?: string;
    width?: string;
    pad?: string;
    layer: string;
    displayLayer: string;
    nextlayer: "string";

    Lcode: number;
    vkCode: number = 0; // default value; may be changed for mnemonic keyboards.
    isVirtualKey: boolean = true; // default value; may be changed for KMW-1.0 keyboards.
    isMnemonic: boolean = false;

    proportionalX: number;
    proportionalWidth: number;

    static polyfill(key: LayoutKey, layout: ActiveLayout, displayLayer: string) {
      // Add class functions to the existing layout object, allowing it to act as an ActiveLayout.
      let dummy = new ActiveKey();
      for(let prop in dummy) {
        if(!key.hasOwnProperty(prop)) {
          key[prop] = dummy[prop];
        }
      }

      let aKey = key as ActiveKey;
      aKey.displayLayer = displayLayer;
      aKey.layer = aKey.layer || displayLayer;

      aKey.Lcode = text.Codes.keyCodes[key.id.toUpperCase()];

      if(layout.keyboard) {
        let keyboard = layout.keyboard;

        // Include *limited* support for mnemonic keyboards (Sept 2012)
        // If a touch layout has been defined for a mnemonic keyout, do not perform mnemonic mapping for rules on touch devices.
        if(keyboard.isMnemonic && !(layout.isDefault && layout.formFactor != 'desktop')) {
          if(aKey.Lcode != text.Codes.keyCodes['K_SPACE']) { // exception required, March 2013
            // Jan 2019 - interesting that 'K_SPACE' also affects the caps-state check...
            aKey.vkCode = aKey.Lcode;
            aKey.isMnemonic = true;
          }
        } else {
          aKey.vkCode=aKey.Lcode;
        }

        // Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic
        if(!keyboard.definesPositionalOrMnemonic) {
          // Not the best pattern, but currently safe - we don't look up any properties of either
          // argument in this use case, and the object's scope is extremely limited.
          aKey.Lcode = KeyMapping._USKeyCodeToCharCode(aKey.constructKeyEvent(null, null));
          aKey.isVirtualKey=false;
        }
      }
    }

    constructKeyEvent(target: text.OutputTarget, device: text.EngineDeviceSpec): text.KeyEvent {
      let keyman = com.keyman.singleton;
      let core = keyman.core;

      // Get key name and keyboard shift state (needed only for default layouts and physical keyboard handling)
      // Note - virtual keys should be treated case-insensitive, so we force uppercasing here.
      var layer = this.layer || this.displayLayer || '', keyName=this.id.toUpperCase();

      // Start:  mirrors _GetKeyEventProperties<commit_msg>refactor(web/engine): popup-key adjustments, key.id null check<commit_after>namespace com.keyman.keyboards {
  type KeyDistribution = text.KeyDistribution;


  export class ActiveKey implements LayoutKey {

    static readonly DEFAULT_PAD=15;          // Padding to left of key, in virtual units
    static readonly DEFAULT_RIGHT_MARGIN=15; // Padding to right of right-most key, in virtual units
    static readonly DEFAULT_KEY_WIDTH=100;   // Width of a key, if not specified, in virtual units

    // Defines key defaults
    static readonly DEFAULT_KEY = {
      text: '',
      width: ActiveKey.DEFAULT_KEY_WIDTH.toString(),
      sp: '0',
      pad: ActiveKey.DEFAULT_PAD.toString()
    };

    id?: string;
    width?: string;
    pad?: string;
    layer: string;
    displayLayer: string;
    nextlayer: "string";

    Lcode: number;
    vkCode: number = 0; // default value; may be changed for mnemonic keyboards.
    isVirtualKey: boolean = true; // default value; may be changed for KMW-1.0 keyboards.
    isMnemonic: boolean = false;

    proportionalX: number;
    proportionalWidth: number;

    static polyfill(key: LayoutKey, layout: ActiveLayout, displayLayer: string) {
      // Add class functions to the existing layout object, allowing it to act as an ActiveLayout.
      let dummy = new ActiveKey();
      for(let prop in dummy) {
        if(!key.hasOwnProperty(prop)) {
          key[prop] = dummy[prop];
        }
      }

      // Ensure subkeys are also properly extended.
      if(key.sk) {
        for(let subkey of key.sk) {
          ActiveKey.polyfill(subkey, layout, displayLayer);
        }
      }

      let aKey = key as ActiveKey;
      aKey.displayLayer = displayLayer;
      aKey.layer = aKey.layer || displayLayer;

      if(key.id) {
        aKey.Lcode = text.Codes.keyCodes[key.id.toUpperCase()];

        if(layout.keyboard) {
          let keyboard = layout.keyboard;

          // Include *limited* support for mnemonic keyboards (Sept 2012)
          // If a touch layout has been defined for a mnemonic keyout, do not perform mnemonic mapping for rules on touch devices.
          if(keyboard.isMnemonic && !(layout.isDefault && layout.formFactor != 'desktop')) {
            if(aKey.Lcode != text.Codes.keyCodes['K_SPACE']) { // exception required, March 2013
              // Jan 2019 - interesting that 'K_SPACE' also affects the caps-state check...
              aKey.vkCode = aKey.Lcode;
              aKey.isMnemonic = true;
            }
          } else {
            aKey.vkCode=aKey.Lcode;
          }

          // Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic
          if(!keyboard.definesPositionalOrMnemonic) {
            // Not the best pattern, but currently safe - we don't look up any properties of either
            // argument in this use case, and the object's scope is extremely limited.
            aKey.Lcode = KeyMapping._USKeyCodeToCharCode(aKey.constructKeyEvent(null, null));
            aKey.isVirtualKey=false;
          }
        }
      }
    }

    constructKeyEvent(target: text.OutputTarget, device: text.EngineDeviceSpec): text.KeyEvent {
      let keyman = com.keyman.singleton;
      let core = keyman.core;

      // Get key name and keyboard shift state (needed only for default layouts and physical keyboard handling)
      // Note - virtual keys should be treated case-insensitive, so we force uppercasing here.
      var layer = this.layer || this.displayLayer || '', keyName=this.id.toUpperCase();

      // Start:  mirrors _GetKeyEventProperties
{'fraction_non_alphanumeric': 0.09304703476482618, 'fraction_numerical': 0.007303534910896874, 'mean_word_length': 2.531201650335224, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5984771', 'n_tokens_mistral': 2015, 'n_tokens_neox': 1902, 'n_words': 613}