source: trunk/phpgwapi/js/expressoAjax/vkboards.js @ 2982

Revision 2982, 62.1 KB checked in by amuller, 14 years ago (diff)

Ticket #1121 - Implementando teclado virtual no login para quem quer usar

Line 
1/* JavaScript Virtual Keyboard (slim variant), version 2.7
2 *
3 * (C) 2006-2008 Dmitriy Khudorozhkov (mailto:dmitrykhudorozhkov@yahoo.com)
4 *
5 * This software is provided "as-is", without any express or implied warranty.
6 * In no event will the author be held liable for any damages arising from the
7 * use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 *    claim that you wrote the original software. If you use this software
15 *    in a product, an acknowledgment in the product documentation would be
16 *    appreciated but is not required.
17 *
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 *    misrepresented as being the original software.
20 *
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24function VKeyboard(container_id, callback_ref, create_arrows, create_updown,
25                   create_nav_keys, create_numpad, font_name, font_size,
26                   font_color, dead_color, bg_color, key_color,
27                   sel_item_color, border_color, inactive_border_color,
28                   inactive_key_color, lang_sel_brd_color, show_click,
29                   click_font_color, click_bg_color, click_border_color,
30                   do_embed, do_gap, start_layout_index)
31{
32  return this._construct(container_id, callback_ref, create_arrows, create_updown,
33                         create_nav_keys, create_numpad, font_name, font_size,
34                         font_color, dead_color, bg_color, key_color,
35                         sel_item_color, border_color, inactive_border_color,
36                         inactive_key_color, lang_sel_brd_color, show_click,
37                         click_font_color, click_bg_color, click_border_color,
38                         do_embed, do_gap, start_layout_index);
39}
40
41VKeyboard.kbArray = [];
42
43VKeyboard.prototype = {
44
45  _get_event_source: function(event)
46  {
47    var e = event || window.event;
48    return e.srcElement || e.target;
49  },
50
51  _setup_event: function(elem, eventType, handler)
52  {
53    return (elem.attachEvent ? elem.attachEvent("on" + eventType, handler) : ((elem.addEventListener) ? elem.addEventListener(eventType, handler, false) : null));
54  },
55
56  _detach_event: function(elem, eventType, handler)
57  {
58    return (elem.detachEvent ? elem.detachEvent("on" + eventType, handler) : ((elem.removeEventListener) ? elem.removeEventListener(eventType, handler, false) : null));
59  },
60
61  _start_flash: function(in_el)
62  {
63    function getColor(str, posOne, posTwo)
64    {
65      if(/rgb\((\d+),\s(\d+),\s(\d+)\)/.exec(str)) // try to detect Mozilla-style rgb value.
66      {
67        switch(posOne)
68        {
69          case 1: return parseInt(RegExp.$1, 10);
70          case 2: return parseInt(RegExp.$2, 10);
71          case 3: return parseInt(RegExp.$3, 10);
72          default: return 0;
73        }
74      }
75      else // standard (#xxxxxx or #xxx) way
76        return str.length == 4 ? parseInt(str.substr(posOne, 1) + str.substr(posOne, 1), 16) : parseInt(str.substr(posTwo, 2), 16);
77    }
78
79    function getR(color_string)
80    { return getColor(color_string, 1, 1); }
81
82    function getG(color_string)
83    { return getColor(color_string, 2, 3); }
84
85    function getB(color_string)
86    { return getColor(color_string, 3, 5); }
87
88    var el = in_el.time ? in_el : (in_el.company && in_el.company.time ? in_el.company : null);
89
90    if(el)
91    {
92      el.time = 0;
93      clearInterval(el.timer);
94    }
95
96    var vkb = this;
97    var ftc = vkb.fontcolor, bgc = vkb.keycolor, brc = vkb.bordercolor;
98
99    // Special fixes for simple/dead/modifier keys:
100
101    if(in_el.dead)
102      ftc = vkb.deadcolor;
103
104    if(((in_el.innerHTML == "Shift") && vkb.Shift) || ((in_el.innerHTML == "Caps") && vkb.Caps) || ((in_el.innerHTML == "AltGr") && vkb.AltGr))
105      bgc = vkb.lic;
106
107    // Extract base color values:
108    var fr = getR(ftc), fg = getG(ftc), fb = getB(ftc);
109    var kr = getR(bgc), kg = getG(bgc), kb = getB(bgc);
110    var br = getR(brc), bg = getG(brc), bb = getB(brc);
111
112    // Extract flash color values:
113    var f_r = getR(vkb.cfc), f_g = getG(vkb.cfc), f_b = getB(vkb.cfc);
114    var k_r = getR(vkb.cbg), k_g = getG(vkb.cbg), k_b = getB(vkb.cbg);
115    var b_r = getR(vkb.cbr), b_g = getG(vkb.cbr), b_b = getB(vkb.cbr);
116
117    var _shift_colors = function()
118    {
119      function dec2hex(dec)
120      {
121        var hexChars = "0123456789ABCDEF";
122        var a = dec % 16;
123        var b = (dec - a) / 16;
124
125        return hexChars.charAt(b) + hexChars.charAt(a) + "";
126      }
127
128      in_el.time = !in_el.time ? 10 : (in_el.time - 1);
129
130      function calc_color(start, end)
131      { return (end - (in_el.time / 10) * (end - start)); }
132
133      var t_f_r = calc_color(f_r, fr), t_f_g = calc_color(f_g, fg), t_f_b = calc_color(f_b, fb);
134      var t_k_r = calc_color(k_r, kr), t_k_g = calc_color(k_g, kg), t_k_b = calc_color(k_b, kb);
135      var t_b_r = calc_color(b_r, br), t_b_g = calc_color(b_g, bg), t_b_b = calc_color(b_b, bb);
136
137      function setStyles(style)
138      {
139        style.color = "#" + dec2hex(t_f_r) + dec2hex(t_f_g) + dec2hex(t_f_b);
140        style.borderColor = "#" + dec2hex(t_b_r) + dec2hex(t_b_g) + dec2hex(t_b_b);
141        style.backgroundColor = "#" + dec2hex(t_k_r) + dec2hex(t_k_g) + dec2hex(t_k_b);
142      }
143
144      var first = (in_el == vkb.mod[4]) ? false : true, is = in_el.style, cs = in_el.company ? in_el.company.style : null;
145
146      if(cs && first)
147        setStyles(cs);
148
149      setStyles(is);
150
151      if(cs)
152      {
153        if(!first)
154        {
155          setStyles(cs);
156          is.borderBottomColor = "#" + dec2hex(t_k_r) + dec2hex(t_k_g) + dec2hex(t_k_b);
157        }
158        else
159          cs.borderBottomColor = "#" + dec2hex(t_k_r) + dec2hex(t_k_g) + dec2hex(t_k_b);
160      }
161
162      if(!in_el.time)
163      {
164        clearInterval(in_el.timer);
165        return;
166      }
167    };
168
169    _shift_colors();
170
171    in_el.timer = window.setInterval(_shift_colors, 50);
172  },
173
174  _setup_style: function(obj, top, left, width, height, position, text_align, line_height, font_size, font_weight, padding_left, padding_right)
175  {
176    var os = obj.style;
177
178    if(top)    os.top = top;
179    if(left)   os.left = left;
180    if(width)  os.width = width;
181    if(height) os.height = height;
182
183    if(position) os.position = position;
184
185    if(text_align)  os.textAlign  = text_align;
186    if(line_height) os.lineHeight = line_height;
187    if(font_size)   os.fontSize   = font_size;
188
189    os.fontWeight = font_weight || "bold";
190
191    if(padding_left)  os.paddingLeft  = padding_left;
192    if(padding_right) os.paddingRight = padding_right;
193  },
194
195  _setup_key: function(parent, id, top, left, width, height, text_align, line_height, font_size, font_weight, padding_left, padding_right)
196  {
197    var _id = this.Cntr.id + id;
198    var exists = document.getElementById(_id);
199
200    var key = exists ? exists.parentNode : document.createElement("DIV");
201    this._setup_style(key, top, left, width, height, "absolute");
202
203    var key_sub = exists || document.createElement("DIV");
204    key.appendChild(key_sub); parent.appendChild(key);
205
206    this._setup_style(key_sub, "", "", "", line_height, "relative", text_align, line_height, font_size, font_weight, padding_left, padding_right);
207    key_sub.id = _id;
208
209    return key_sub;
210  },
211
212  _findX: function(obj)
213  { return (obj && obj.parentNode) ? parseFloat(obj.parentNode.offsetLeft) : 0; },
214
215  _findY: function(obj)
216  { return (obj && obj.parentNode) ? parseFloat(obj.parentNode.offsetTop) : 0; },
217
218  _findW: function(obj)
219  { return (obj && obj.parentNode) ? parseFloat(obj.parentNode.offsetWidth) : 0; },
220
221  _findH: function(obj)
222  { return (obj && obj.parentNode) ? parseFloat(obj.parentNode.offsetHeight) : 0; },
223
224  _construct: function(container_id, callback_ref, create_arrows, create_updown, create_nav_keys, create_numpad,
225                       font_name, font_size, font_color, dead_color, bg_color, key_color, sel_item_color,
226                       border_color, inactive_border_color, inactive_key_color, lang_sel_brd_color,
227                       show_click, click_font_color, click_bg_color, click_border_color, do_embed,
228                       do_gap, start_layout_index)
229  {
230    var exists  = (this.Cntr != undefined), ct = exists ? this.Cntr : document.getElementById(container_id);
231    var changed = (font_size && (font_size != this.fontsize));
232
233    this._Callback = ((typeof(callback_ref) == "function") && ((callback_ref.length == 1) || (callback_ref.length == 2))) ? callback_ref : (this._Callback || null);
234
235    var ff = font_name || this.fontname || "";
236    var fs = font_size || this.fontsize || "14px";
237
238    var fc = font_color   || this.fontcolor   || "#000";
239    var dc = dead_color   || this.deadcolor   || "#F00";
240    var bg = bg_color     || this.bgcolor     || "#FFF";
241    var kc = key_color    || this.keycolor    || "#FFF";
242    var bc = border_color || this.bordercolor || "#777";
243
244    this.fontname = ff, this.fontsize = fs, this.fontcolor = fc;
245    this.bgcolor = bg,  this.keycolor = kc, this.deadcolor = dc, this.bordercolor = bc;
246
247    this.lic = sel_item_color        || this.lic || "#DDD";
248    this.ibc = inactive_border_color || this.ibc || "#CCC";
249    this.ikc = inactive_key_color    || this.ikc || "#FFF";
250    this.lsc = lang_sel_brd_color    || this.lsc || "#F77";
251
252    this.cfc = click_font_color   || this.cfc || "#CC3300";
253    this.cbg = click_bg_color     || this.cbg || "#FF9966";
254    this.cbr = click_border_color || this.cbr || "#CC3300";
255
256    this.sc = (show_click == undefined) ? ((this.sc == undefined) ? false : this.sc) : show_click;
257    this.gap = (do_gap != undefined) ? (do_gap ? 1 : -1) : (this.gap || 1);
258
259    if(!exists)
260    {
261      this.Cntr = ct;
262      this.Caps = this.Shift = this.AltGr = false;
263
264      this.DeadAction = []; this.DeadAction[0] = this.DeadAction[1] = null;
265      this.keys = [], this.mod = [], this.pad = [];
266
267      VKeyboard.kbArray[container_id] = this;
268    }
269
270    var kb = exists ? ct.childNodes[0] : document.createElement("DIV");
271
272    if(!exists)
273    {
274      ct.appendChild(kb);
275      ct.style.display = "block";
276      ct.style.zIndex  = 999;
277
278      if(do_embed)
279        ct.style.position = "relative";
280      else
281      {
282        ct.style.position = "absolute";
283
284        var initX = 0, initY = 0, ct_ = ct;
285        if(ct_.offsetParent)
286        {
287          while (ct_.offsetParent)
288          {
289            initX += ct_.offsetLeft;
290            initY += ct_.offsetTop;
291
292            ct_ = ct_.offsetParent;
293          }
294        }
295        else if (ct_.x)
296        {
297          initX += ct_.x;
298          initY += ct_.y;
299        }
300
301        ct.style.top = initY + "px", ct.style.left = initX +"px";
302      }
303
304      kb.style.position = "relative";
305      kb.style.top      = "0px", kb.style.left = "0px";
306    }
307
308    kb.style.border = "1px solid " + bc;
309
310    var kb_main = exists ? kb.childNodes[0] : document.createElement("DIV"), ks = kb_main.style;
311    if(!exists)
312    {
313      kb.appendChild(kb_main);
314
315      ks.position = "relative";
316      ks.width    = "1px";
317      ks.cursor   = "default";
318    }
319
320    // Disable content selection:
321    this._setup_event(kb_main, "selectstart", function(event) { return false; });
322    this._setup_event(kb_main, "mousedown",   function(event) { if(event.preventDefault) event.preventDefault(); return false; });
323
324    ks.fontFamily = ff, ks.backgroundColor = bg;
325
326    if(!exists || changed)
327    {
328      var mag = parseFloat(fs) / 14.0, cell = Math.floor(25.0 * mag), dcell = 2 * cell, gap = this.gap;
329      var cp = String(cell) + "px", cx = String(cell - (do_gap ? 0 : 2.0)) + "px", lh = String(cell - 2.0) + "px";
330
331      var prevX = 0, prevY = gap, prevW = 0, prevH = 0;
332
333      // Convenience strings:
334      var c = "center", n = "normal", r = "right", l = "left", e = " ", pad = String(4 * mag) + "px";
335
336      // Number row:
337
338      var key;
339      for(var i = 0; i < 13; i++)
340      {
341        this.keys[i] = key = this._setup_key(kb_main, "___key" + String(i), prevY + "px", (prevX + prevW + gap) + "px", cp, cp, c, lh, fs);
342
343        prevX = this._findX(key), prevW = this._findW(key);
344      }
345
346      prevY = this._findY(key);
347      prevH = this._findH(key); // universal key height
348
349      var kb_kbp = this._setup_key(kb_main, "___kbp", prevY + "px", (prevX + prevW + gap) + "px", (2.96 * cell) + "px", cp, r, lh, fs, n, "", pad);
350      kb_kbp.innerHTML = "BackSpace";
351      this.mod[0] = kb_kbp;
352
353      // Top row:
354
355      var kb_tab = this._setup_key(kb_main, "___tab", (prevY + prevH + gap) + "px", gap + "px", (1.48 * cell + gap) + "px", cp, l, lh, fs, n, pad);
356      kb_tab.innerHTML = "Tab";
357      this.mod[1] = kb_tab;
358
359      prevX = this._findX(kb_tab), prevW = this._findW(kb_tab), prevY = this._findY(kb_tab);
360
361      for(; i < 26; i++)
362      {
363        this.keys[i] = key = this._setup_key(kb_main, "___key" + String(i), prevY + "px", (prevX + prevW + gap) + "px", cp, cp, c, lh, fs);
364
365        prevX = this._findX(key), prevW = this._findW(key);
366      }
367
368      this.kbpH = this._findX(kb_kbp) + this._findW(kb_kbp);
369
370      // Home row:
371
372      var kb_caps = this._setup_key(kb_main, "___caps", (prevY + prevH + gap) + "px", gap + "px", dcell + "px", cp, l, lh, fs, n, pad);
373      kb_caps.innerHTML = "Caps";
374      this.mod[2] = kb_caps;
375
376      prevX = this._findX(kb_caps), prevW = this._findW(kb_caps), prevY = this._findY(kb_caps);
377
378      for(; i < 38; i++)
379      {
380        this.keys[i] = key = this._setup_key(kb_main, "___key" + String(i), prevY + "px", (prevX + prevW + gap) + "px", cp, cp, c, lh, fs);
381
382        prevX = this._findX(key), prevW = this._findW(key);
383      }
384
385      prevY = this._findY(key);
386      var s = prevX + prevW + gap;
387
388      var kb_enter = this._setup_key(kb_main, "___enter_l", prevY + "px", s + "px", (this.kbpH - s) + "px", cp, r, lh, fs, n, "", pad);
389      kb_enter.innerHTML = "Enter";
390      this.mod[3] = kb_enter;
391
392      s = this._findX(this.keys[25]) + this._findW(this.keys[25]) + gap;
393
394      var kb_enter_top = this._setup_key(kb_main, "___enter_top", this._findY(kb_tab) + "px", s + "px", (this.kbpH - s) + "px", cx, c, cx);
395      kb_enter_top.innerHTML = e;
396      kb_enter_top.subst = "Enter";
397      this.mod[4] = kb_enter_top;
398
399      kb_enter_top.company = kb_enter;
400      kb_enter.company = kb_enter_top;
401
402      // Bottom row:
403
404      var kb_shift = this._setup_key(kb_main, "___shift", (prevY + prevH + gap) + "px", gap + "px", (2.52 * cell) + "px", cp, l, lh, fs, n, pad);
405      kb_shift.innerHTML = "Shift";
406      this.mod[5] = kb_shift;
407
408      prevX = this._findX(kb_shift), prevW = this._findW(kb_shift), prevY = this._findY(kb_shift);
409
410      for(; i < 48; i++)
411      {
412        this.keys[i] = key = this._setup_key(kb_main, "___key" + String(i), prevY + "px", (prevX + prevW + gap) + "px", cp, cp, c, lh, fs);
413
414        prevX = this._findX(key), prevW = this._findW(key);
415      }
416
417      prevY = this._findY(key);
418
419      var kb_shift_r = this._setup_key(kb_main, "___shift_r", prevY + "px", (prevX + prevW + gap) + "px", (this._findX(kb_kbp) + this._findW(kb_kbp) - prevX - prevW - gap) + "px", cp, r, lh, fs, n, "", pad);
420      kb_shift_r.innerHTML = "Shift";
421      this.mod[6] = kb_shift_r;
422
423      // Language selector:
424
425      var vcell = String(1.32 * cell) + "px";
426
427      var kb_lang = this._setup_key(kb_main, "___lang", (prevY + prevH + gap) + "px", gap + "px", vcell, cp, l, lh, fs, n, pad);
428      this.mod[7] = kb_lang;
429
430      prevY = this._findY(kb_lang);
431
432      ks.height = (prevY + prevH + gap) + "px";
433
434      prevY += "px";
435
436      var kb_res_1 = this._setup_key(kb_main, "___res_1", prevY, (this._findX(kb_lang) + this._findW(kb_lang) + gap) + "px", vcell, cp, c, lh, fs);
437      kb_res_1.innerHTML = e;
438      this.mod[8] = kb_res_1;
439
440      var kb_res_2 = this._setup_key(kb_main, "___res_2", prevY, (this._findX(kb_res_1) + this._findW(kb_res_1) + gap) + "px", vcell, cp, c, lh, fs);
441      kb_res_2.innerHTML = e;
442      this.mod[9] = kb_res_2;
443
444      var kb_space = this._setup_key(kb_main, "___space", prevY, (this._findX(kb_res_2) + this._findW(kb_res_2) + gap) + "px", (6.28 * cell) + "px", cp, c, lh, fs);
445      this.mod[10] = kb_space;
446
447      var kb_alt_gr = this._setup_key(kb_main, "___alt_gr", prevY, (this._findX(kb_space) + this._findW(kb_space) + gap) + "px", vcell, cp, c, lh, parseFloat(fs) * 0.786, n);
448      kb_alt_gr.innerHTML = "AltGr";
449      this.mod[11] = kb_alt_gr;
450
451      var kb_res_3 = this._setup_key(kb_main, "___res_3", prevY, (this._findX(kb_alt_gr) + this._findW(kb_alt_gr) + gap) + "px", vcell, cp, c, lh, fs);
452      kb_res_3.innerHTML = e;
453      this.mod[12] = kb_res_3;
454
455      var kb_res_4 = this._setup_key(kb_main, "___res_4", prevY, (this._findX(kb_res_3) + this._findW(kb_res_3) + gap) + "px", vcell, cp, c, lh, fs);
456      kb_res_4.innerHTML = e;
457      this.mod[13] = kb_res_4;
458
459      var w = this.kbpH + gap;
460
461      // Arrow keys:
462      if(!exists && ((create_arrows == undefined) ? true : create_arrows))
463      {
464        var kb_left = this._setup_key(kb_main, "___left", prevY, (this.kbpH + gap + cell / 2) + "px", cp, cp, c, lh, fs);
465        kb_left.innerHTML = "&lt;"
466        this.mod[14] = kb_left;
467
468        if((create_updown == undefined) ? true : create_updown)
469        {
470          var kb_down = this._setup_key(kb_main, "___down", prevY, (this._findX(kb_left) + this._findW(kb_left) + gap) + "px", cp, cp, c, lh, fs);
471          kb_down.innerHTML = "\\/"
472          this.mod[15] = key = kb_down;
473
474          var kb_up = this._setup_key(kb_main, "___up", this._findY(kb_shift_r) + "px", (this._findX(kb_left) + this._findW(kb_left) + gap) + "px", cp, cp, c, lh, fs);
475          kb_up.innerHTML = "/\\"
476          this.mod[16] = kb_up;
477        }
478                else key = kb_left;
479
480        var kb_right = this._setup_key(kb_main, "___right", prevY, (this._findX(key) + this._findW(key) + gap) + "px", cp, cp, c, lh, fs);
481        kb_right.innerHTML = "&gt;"
482        this.mod[this.mod.length] = kb_right;
483
484        this.kbpH = this._findX(kb_right) + this._findW(kb_right);
485        w = this.kbpH + gap;
486      }
487
488      // Numpad:
489
490      if((create_numpad == undefined) ? true : create_numpad)
491      {
492        var w2 = this._create_numpad(container_id, kb_main);
493        if(w2 > w) w = w2;
494      }
495
496      kb.style.width = ks.width = w + "px";
497    }
498
499    this._refresh_layout(this.avail_langs[start_layout_index || 0][0]);
500
501    return this;
502  },
503
504  _create_numpad: function(container_id, parent)
505  {
506    var c = "center", n = "normal", l = "left";
507    var fs = this.fontsize, bc = this.bordercolor, gap = this.gap;
508
509    var mag = parseFloat(fs) / 14.0, cell = Math.floor(25.0 * mag);
510    var dcell = 2 * cell, dp = (dcell + 1) + "px", dp2 = (dcell - 1 - ((gap < 0) ? 2 : 0)) + "px";
511    var cp = String(cell) + "px", lh = String(Math.floor(cell - 2.0)) + "px";
512
513    var edge = (this.kbpH + cell / 2 + gap) + "px";
514
515    var kb_pad_eur = this._setup_key(parent, "___pad_eur", gap + "px", edge, cp, cp, c, lh, fs);
516    kb_pad_eur.innerHTML = "&#x20AC;";
517    this.pad[0] = kb_pad_eur;
518
519    var edge_1 = (this._findX(kb_pad_eur) + this._findW(kb_pad_eur) + gap) + "px";
520
521    var kb_pad_slash = this._setup_key(parent, "___pad_slash", gap + "px", edge_1, cp, cp, c, lh, fs);
522    kb_pad_slash.innerHTML = "/";
523    this.pad[1] = kb_pad_slash;
524
525    var edge_2 = (this._findX(kb_pad_slash) + this._findW(kb_pad_slash) + gap) + "px";
526
527    var kb_pad_star = this._setup_key(parent, "___pad_star", gap + "px", edge_2, cp, cp, c, lh, fs);
528    kb_pad_star.innerHTML = "*";
529    this.pad[2] = kb_pad_star;
530
531    var edge_3 = (this._findX(kb_pad_star) + this._findW(kb_pad_star) + gap) + "px";
532
533    var kb_pad_minus = this._setup_key(parent, "___pad_minus", gap + "px", edge_3, cp, cp, c, lh, fs);
534    kb_pad_minus.innerHTML = "-";
535    this.pad[3] = kb_pad_minus;
536
537    this.kbpM = this._findX(kb_pad_minus) + this._findW(kb_pad_minus) + gap;
538
539    var prevH = this._findH(kb_pad_eur), edge_Y = (this._findY(kb_pad_eur) + prevH + gap) + "px";
540
541    var kb_pad_7 = this._setup_key(parent, "___pad_7", edge_Y, edge, cp, cp, c, lh, fs);
542    kb_pad_7.innerHTML = "7";
543    this.pad[4] = kb_pad_7;
544
545    var kb_pad_8 = this._setup_key(parent, "___pad_8", edge_Y, edge_1, cp, cp, c, lh, fs);
546    kb_pad_8.innerHTML = "8";
547    this.pad[5] = kb_pad_8;
548
549    var kb_pad_9 = this._setup_key(parent, "___pad_9", edge_Y, edge_2, cp, cp, c, lh, fs);
550    kb_pad_9.innerHTML = "9";
551    this.pad[6] = kb_pad_9;
552
553    var kb_pad_plus = this._setup_key(parent, "___pad_plus", edge_Y, edge_3, cp, dp, c, dp2, fs);
554    kb_pad_plus.innerHTML = "+";
555    this.pad[7] = kb_pad_plus;
556
557    edge_Y = (this._findY(kb_pad_7) + prevH + gap) + "px";
558
559    var kb_pad_4 = this._setup_key(parent, "___pad_4", edge_Y, edge, cp, cp, c, lh, fs);
560    kb_pad_4.innerHTML = "4";
561    this.pad[8] = kb_pad_4;
562
563    var kb_pad_5 = this._setup_key(parent, "___pad_5", edge_Y, edge_1, cp, cp, c, lh, fs);
564    kb_pad_5.innerHTML = "5";
565    this.pad[9] = kb_pad_5;
566
567    var kb_pad_6 = this._setup_key(parent, "___pad_6", edge_Y, edge_2, cp, cp, c, lh, fs);
568    kb_pad_6.innerHTML = "6";
569    this.pad[10] = kb_pad_6;
570
571    edge_Y = (this._findY(kb_pad_4) + prevH + gap) + "px";
572
573    var kb_pad_1 = this._setup_key(parent, "___pad_1", edge_Y, edge, cp, cp, c, lh, fs);
574    kb_pad_1.innerHTML = "1";
575    this.pad[11] = kb_pad_1;
576
577    var kb_pad_2 = this._setup_key(parent, "___pad_2", edge_Y, edge_1, cp, cp, c, lh, fs);
578    kb_pad_2.innerHTML = "2";
579    this.pad[12] = kb_pad_2;
580
581    var kb_pad_3 = this._setup_key(parent, "___pad_3", edge_Y, edge_2, cp, cp, c, lh, fs);
582    kb_pad_3.innerHTML = "3";
583    this.pad[13] = kb_pad_3;
584
585    var kb_pad_enter = this._setup_key(parent, "___pad_enter", edge_Y, edge_3, cp, dp, c, dp2, parseFloat(fs) * 0.643, n);
586    kb_pad_enter.innerHTML = "Enter";
587    this.pad[14] = kb_pad_enter;
588
589    edge_Y = (this._findY(kb_pad_1) + prevH + gap) + "px";
590
591    var kb_pad_0 = this._setup_key(parent, "___pad_0", edge_Y, edge, dp, cp, l, lh, fs, "", 7 * mag + "px");
592    kb_pad_0.innerHTML = "0";
593    this.pad[15] = kb_pad_0;
594
595    var kb_pad_period = this._setup_key(parent, "___pad_period", edge_Y, edge_2, cp, cp, c, lh, fs);
596    kb_pad_period.innerHTML = ".";
597    this.pad[16] = kb_pad_period;
598
599    return this.kbpM;
600  },
601
602  _set_key_state: function(key, on, textcolor, bordercolor, bgcolor)
603  {
604    if(key)
605    {
606      var ks = key.style;
607      if(ks)
608      {
609        if(textcolor) ks.color = textcolor;
610        if(bordercolor) ks.border = "1px solid " + bordercolor;
611        if(bgcolor) ks.backgroundColor = bgcolor;
612      }
613
614      this._detach_event(key, 'mouseup', this._generic_callback_proc);
615
616      if(on)
617        this._setup_event(key, 'mouseup', this._generic_callback_proc);
618    }
619  },
620
621  _refresh_layout: function(layout)
622  {
623    if(!layout) layout = this.mod[7].innerHTML;
624
625    var fc = this.fontcolor, kc = this.keycolor, ikc = this.ikc;
626    var ibc = this.ibc, bc = this.bordercolor, lic = this.lic;
627
628    var arr_type = this.AltGr ? (this.Shift ? "alt_gr_shift" : "alt_gr") : (this.Shift ? "shift" : (this.Caps ? "caps" : "normal"));
629
630    var nkeys = this.keys.length;
631
632    var norm_arr  = this[layout + "_normal"];
633    var caps_arr  = this[layout + "_caps"];
634    var shift_arr = this[layout + "_shift"];
635    var alt_arr   = this[layout + "_alt_gr"];
636
637    var alt_shift_arr = this[layout + "_alt_gr_shift"];
638
639    var dead_arr = this[this.DeadAction[1]] || null;
640
641    var bcaps  = (caps_arr  && (caps_arr.length  == nkeys));
642    var bshift = (shift_arr && (shift_arr.length == nkeys));
643    var balt   = (alt_arr   && (alt_arr.length   == nkeys));
644    var baltsh = (balt      && alt_shift_arr && (alt_shift_arr.length == nkeys));
645
646    var caps = this.mod[2], shift = this.mod[5], shift_r = this.mod[6], alt_gr = this.mod[11];
647
648    if(bshift)
649    {
650      this._set_key_state(shift, true, fc, bc, this.Shift ? lic : kc);
651      this._set_key_state(shift_r, true, fc, bc, this.Shift ? lic : kc);
652    }
653    else
654    {
655      this._set_key_state(shift, false, ibc, ibc, ikc);
656      this._set_key_state(shift_r, false, ibc, ibc, ikc);
657
658      if(arr_type == "shift")
659      {
660        arr_type = "normal";
661        this.Shift = false;
662      }
663    }
664
665    if(balt)
666    {
667      this._set_key_state(alt_gr, true, fc, bc, this.AltGr ? lic : kc);
668
669      if(this.AltGr)
670      {
671        if(baltsh)
672        {
673          this._set_key_state(shift, true, fc, bc);
674          this._set_key_state(shift_r, true, fc, bc);
675        }
676        else
677        {
678          this._set_key_state(shift, false, ibc, ibc, ikc);
679          this._set_key_state(shift_r, false, ibc, ibc, ikc);
680
681          arr_type = "alt_gr";
682          this.Shift = false;
683        }
684      }
685    }
686    else
687    {
688      this._set_key_state(alt_gr, false, ibc, ibc, ikc);
689
690      if(arr_type == "alt_gr")
691      {
692        arr_type = "normal";
693        this.AltGr = false;
694      }
695      else if(arr_type == "alt_gr_shift")
696      {
697        arr_type = "normal";
698        this.AltGr = false, this.Shift = false;
699
700        shift.style.backgroundColor = kc, shift_r.style.backgroundColor = kc;
701      }
702    }
703
704    if(this.Shift && !baltsh)
705      this._set_key_state(alt_gr, false, ibc, ibc, ikc);
706
707    if(bcaps && !this.AltGr)
708      this._set_key_state(caps, true, fc, bc, this.Caps ? lic : kc);
709    else
710    {
711      this._set_key_state(caps, false, ibc, ibc, ikc);
712
713      this.Caps = false;
714      if(arr_type == "caps") arr_type = "normal";
715    }
716
717    var arr_cur = this[layout + "_" + arr_type];
718
719    var i = nkeys;
720    while(--i >= 0)
721    {
722      var key = this.keys[i], key_val = arr_cur[i]; if(!key_val) key_val = "";
723
724      if(this.Shift && this.Caps)
725      {
726        var key_nrm = norm_arr[i], key_cps = caps_arr[i], key_shf = shift_arr[i];
727
728        if((key_cps == key_shf) && (key_nrm != key_cps)) key_val = key_nrm;
729      }
730
731      if(typeof(key_val) == "object")
732      {
733        key.innerHTML = key_val[0], key.dead = key_val[1];
734
735        this._set_key_state(key, true, this.deadcolor, bc, (this.DeadAction[0] == key_val[0] ? lic : kc));
736      }
737      else
738      {
739        key.dead = null;
740
741        var block = false;
742
743        if(key_val != "")
744        {
745          if(dead_arr)
746          {
747            for(var j = 0, l = dead_arr.length; j < l; j++) { var dk = dead_arr[j]; if(dk[0] == key_val) { key_val = dk[1]; break;}};
748
749            if(j == l) block = true;
750          }
751
752          key.innerHTML = key_val;
753
754          if(block)
755            this._set_key_state(key, false, ibc, ibc, ikc);
756          else
757            this._set_key_state(key, true, fc, bc, kc);
758        }
759        else
760        {
761          key.innerHTML = "&nbsp;";
762          this._set_key_state(key, false, ibc, ibc, ikc);
763        }
764      }
765    }
766
767    i = this.mod.length;
768    while(--i >= 0)
769    {
770      var key = this.mod[i];
771
772      switch(i)
773      {
774        case 2: case 5: case 6: case 11:
775          break;
776
777        case 7:
778          key.innerHTML = layout;
779
780          this._detach_event(key, 'mousedown', this._handle_lang_menu);
781
782          if(this.DeadAction[1])
783            this._set_key_state(key, false, ibc, ibc, ikc);
784          else
785          {
786            var many = (this.avail_langs.length > 1);
787
788            this._set_key_state(key, false, fc, many ? this.lsc : ibc, many ? kc : ikc);
789            if(many)
790              this._setup_event(key, 'mousedown', this._handle_lang_menu);
791          }
792          break;
793
794        case 10:
795          key.innerHTML = this.DeadAction[1] ? this.DeadAction[0] : "&nbsp;";
796
797        default:
798          if((this.DeadAction[1] && (i != 10)) || ((i == 8) || (i == 9) || (i == 12) || (i ==13)))
799            this._set_key_state(key, false, ibc, ibc, ikc);
800          else
801            this._set_key_state(key, true, fc, bc, kc);
802
803          var ks = key.style;
804          switch(i)
805          {
806            case 4: ks.borderBottomColor = kc; break;
807
808            case 8: case 9: case 12: case 13: ks.borderColor = ibc; break;
809          }
810      }
811    }
812
813    i = this.pad.length;
814    while(--i >= 0)
815    {
816      key = this.pad[i];
817
818      if(this.DeadAction[1])
819        this._set_key_state(key, false, ibc, ibc, ikc);
820      else
821        this._set_key_state(key, true, fc, bc, kc);
822    }
823  },
824
825  _handle_lang_menu: function(event)
826  {
827    var in_el = VKeyboard.prototype._get_event_source(event);
828    var container_id = in_el.id.substring(0, in_el.id.indexOf("___"));
829    var vkb = VKeyboard.kbArray[container_id];
830
831    var ct = vkb.Cntr, menu = vkb.menu;
832
833    if(menu)
834    { ct.removeChild(menu); vkb.menu = null; }
835    else
836    {
837      var fs = vkb.fontsize, kc = vkb.keycolor, bc = "1px solid " + vkb.bordercolor;
838
839      var pad = vkb.pad.length, per_row = pad ? 5 : 4, item_wd = pad ? 108 : 103;
840      var num_rows = Math.ceil(vkb.avail_langs.length / per_row);
841
842      var mag = parseFloat(fs) / 14.0, cell = Math.floor(25.0 * mag), cp = cell + "px", lh = (cell - 2) + "px", w = item_wd * mag;
843      var h1 = Math.floor(cell + mag), h2 = String(w - mag) + "px", pad = String(4 * mag) + "px", wd = String(w * per_row + 1) + "px";
844
845      var langs = vkb.avail_langs.length;
846
847      menu = document.createElement("DIV"); var ms = menu.style;
848      ms.display  = "block";
849      ms.position = "relative";
850
851      ms.top = "1px", ms.left = "0px";
852      ms.width = wd;
853      ms.border = bc;
854      ms.backgroundColor = vkb.bgcolor;
855
856      vkb.menu = ct.appendChild(menu);
857
858      var menu_main = document.createElement("DIV"); ms = menu_main.style;
859      ms.fontFamily = vkb.fontname;
860      ms.position   = "relative";
861
862      ms.color  = vkb.fontcolor;
863      ms.width  = wd;
864      ms.height = String(num_rows * h1 + 1) + "px";
865      ms.cursor = "default";
866
867      menu.appendChild(menu_main);
868
869      function setcolor(obj, c) { return function() { obj.style.backgroundColor = c; } };
870
871      for(var j = 0; j < langs; j++)
872      {
873        var item = vkb._setup_key(menu_main, "___lang_" + String(j), String(h1 * Math.floor(j / per_row) + 1) + "px", String((j % per_row) * w + 1) + "px", h2, cp, "center", lh, fs, "normal", pad);
874        item.style.backgroundColor = kc;
875        item.style.border = bc;
876        item.innerHTML = vkb.avail_langs[j][1];
877
878        vkb._setup_event(item, 'mousedown', vkb._handle_lang_item);
879        vkb._setup_event(item, 'mouseover', setcolor(item, vkb.lic));
880        vkb._setup_event(item, 'mouseout',  setcolor(item, kc));
881      }
882    }
883  },
884
885  _handle_lang_item: function(event)
886  {
887    var in_el = VKeyboard.prototype._get_event_source(event);
888    var container_id = in_el.id.substring(0, in_el.id.indexOf("___"));
889    var vkb = VKeyboard.kbArray[container_id];
890
891    var ndx = in_el.id.indexOf("___lang_");
892    var lng = in_el.id.substring(ndx + 8, in_el.id.length);
893    var newl = vkb.avail_langs[lng][0];
894
895    if(vkb.mod[7].innerHTML != newl)
896      vkb._refresh_layout(newl);
897
898    vkb.Cntr.removeChild(vkb.menu);
899    vkb.menu = null;
900  },
901
902  _generic_callback_proc: function(event)
903  {
904    var in_el = VKeyboard.prototype._get_event_source(event);
905    var container_id = in_el.id.substring(0, in_el.id.indexOf("___"));
906    var vkb = VKeyboard.kbArray[container_id];
907
908    var val = in_el.subst || in_el.innerHTML;
909    if(!val) return;
910
911    switch(val)
912    {
913      case "Caps": case "Shift": case "AltGr":
914
915        vkb[val] = !vkb[val];
916        vkb._refresh_layout();
917
918        if(vkb.sc) vkb._start_flash(in_el);
919        return;
920
921      case "Tab":    val = "\t"; break;
922      case "&nbsp;": val = " ";  break;
923      case "&quot;": val = "\""; break;
924      case "&lt;":   val = "<";  break;
925      case "&gt;":   val = ">";  break;
926      case "&amp;":  val = "&";  break;
927    }
928
929    if(vkb.sc) vkb._start_flash(in_el);
930
931    if(in_el.dead)
932    {
933      if(in_el.dead == vkb.DeadAction[1])
934      { val = ""; vkb.DeadAction[0] = vkb.DeadAction[1] = null; }
935      else
936      { vkb.DeadAction[0] = val; vkb.DeadAction[1] = in_el.dead; }
937
938      vkb._refresh_layout();
939      return;
940    }
941    else
942    {
943          var r;
944      if(vkb.DeadAction[1]) { vkb.DeadAction[0] = vkb.DeadAction[1] = null; r = true; }
945
946      if(vkb.AltGr || vkb.Shift || r)
947      {
948        vkb.AltGr = false; vkb.Shift = false;
949        vkb._refresh_layout();
950      }
951    }
952
953    if(vkb._Callback) vkb._Callback(val, vkb.Cntr.id);
954  },
955
956  SetParameters: function()
957  {
958    var l = arguments.length;
959    if(!l || (l % 2 != 0)) return false;
960
961    var p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16;
962
963    while(--l > 0)
964    {
965      var value = arguments[l];
966
967      switch(arguments[--l])
968      {
969        case "callback":
970          p0 = ((typeof(value) == "function") && ((value.length == 1) || (value.length == 2))) ? value : this._Callback;
971          break;
972
973        case "font-name":  p1 = value; break;
974        case "font-size":  p2 = value; break;
975        case "font-color": p3 = value; break;
976        case "dead-color": p4 = value; break;
977        case "base-color": p5 = value; break;
978        case "key-color":  p6 = value; break;
979
980        case "selection-color": p7 = value; break;
981        case "border-color":    p8 = value; break;
982
983        case "inactive-border-color": p9  = value; break;
984        case "inactive-key-color":    p10 = value; break;
985        case "lang-cell-color":       p11 = value; break;
986
987        case "show-click": p12 = value; break;
988
989        case "click-font-color":   p13 = value; break;
990        case "click-key-color":    p14 = value; break;
991        case "click-border-color": p15 = value; break;
992
993        case "layout": p16 = value; break;
994
995        default: break;
996      }
997    }
998
999    this._construct(this.Cntr.id, p0, 0, 0, 0, (this.pad.length != 0), p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, this.gap, p16);
1000
1001    return true;
1002  },
1003
1004  Show: function(value)
1005  {
1006    var ct = this.Cntr.style;
1007
1008    ct.display = ((value == undefined) || (value == true)) ? "block" : ((value == false) ? "none" : ct.display);
1009  },
1010
1011  ShowNumpad: function(value)
1012  {
1013    var sh = ((value == undefined) || (value == true)) ? "block" : ((value == false) ? "none" : null);
1014    if(!sh) return;
1015
1016    var kb = this.Cntr.childNodes[0];
1017
1018    var i = this.pad.length;
1019    if(i)
1020    {
1021      while(--i >= 0)
1022        this.pad[i].parentNode.style.display = sh;
1023
1024      kb.style.width = kb.childNodes[0].style.width = (sh == "none") ? (this.kbpH + 1) + "px" : this.kbpM + "px";
1025    }
1026    else
1027    {
1028      if(sh == "block")
1029      {
1030        kb.style.width = kb.childNodes[0].style.width = this._create_numpad(this.Cntr.id, kb.childNodes[0]);
1031        this._refresh_layout();
1032      }
1033    }
1034  },
1035
1036  // Layout info:
1037
1038  avail_langs: [["Us", "English (US)"], ["Ca", "Canadian"],
1039                ["Ru", "&#x0420;&#x0443;&#x0441;&#x0441;&#x043A;&#x0438;&#x0439;"], ["De", "Deutsch"],
1040                ["Fr", "Fran&#x00E7;ais"], ["Es", "Espa&#x00F1;ol"], ["It", "Italiano"], ["Cz", "&#x010C;esky"],
1041                ["El", "&#x0388;&#x03BB;&#x03BB;&#x03B7;&#x03BD;&#x03B1;&#x03C2;"], ["He", "&#x05E2;&#x05D1;&#x05E8;&#x05D9;&#x05EA;"]],
1042
1043  // Us International:
1044
1045  Us_normal: [["&#x0060;", "Grave"], "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1046              "&#x0071;", "&#x0077;", "&#x0065;", "&#x0072;", "&#x0074;", "&#x0079;", "&#x0075;", "&#x0069;", "&#x006F;", "&#x0070;", "&#x005B;", "&#x005D;", "&#x005C;",
1047              "&#x0061;", "&#x0073;", "&#x0064;", "&#x0066;", "&#x0067;", "&#x0068;", "&#x006A;", "&#x006B;", "&#x006C;", "&#x003B;", "&#x0027;",,
1048              "&#x007A;", "&#x0078;", "&#x0063;", "&#x0076;", "&#x0062;", "&#x006E;", "&#x006D;", "&#x002C;", "&#x002E;", "&#x002F;"],
1049
1050  Us_caps: [["&#x0060;", "Grave"], "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1051            "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x005B;", "&#x005D;", "&#x005C;",
1052            "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x003B;", "&#x0027;",,
1053            "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x002C;", "&#x002E;", "&#x002F;"],
1054
1055  Us_shift: [["&#x007E;", "Tilde"], "&#x0021;", "&#x0040;", "&#x0023;", "&#x0024;", "&#x0025;", ["&#x005E;", "Circumflex"], "&#x0026;", "&#x002A;", "&#x0028;", "&#x0029;", "&#x005F;", "&#x002B;",
1056             "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x007B;", "&#x007D;", "&#x007C;",
1057             "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x003A;", "&#x0022;",,
1058             "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x003C;", "&#x003E;", "&#x003F;"],
1059
1060  Us_alt_gr: [, "&#x00A1;", "&#x00B2;", "&#x00B3;", "&#x00A4;", "&#x20AC;", "&#x00BC;", "&#x00BD;", "&#x00BE;", "&#x0091;", "&#x0092;", "&#x00A5;", "&#x00D7;",
1061              "&#x00E4;", "&#x00E5;", "&#x00E9;", "&#x00AE;", "&#x00FE;", "&#x00FC;", "&#x00FA;", "&#x00ED;", "&#x00F3;", "&#x00F6;", "&#x00AB;", "&#x00BB;",
1062              "&#x00AC;", "&#x00E1;", "&#x00DF;", "&#x0111;",,,,,, "&#x00F8;", "&#x00B6;", ["&#x00B4;", "Acute"],, "&#x00E6;",, "&#x00A9;",,,
1063              "&#x00F1;", "&#x00B5;", "&#x00E7;",, "&#x00BF;"],
1064
1065  Us_alt_gr_shift: [, "&#x00B9;",,, "&#x00A3;",,,,,,,, "&#x00F7;", "&#x00C4;", "&#x00C5;", "&#x00C9;",, "&#x00DE;", "&#x00DC;",
1066                    "&#x00DA;", "&#x00CD;", "&#x00D3;", "&#x00D6;",,, "&#x00A6;", "&#x00C1;", "&#x00A7;", "&#x0110;",,,,,, "&#x00D8;",
1067                    "&#x00B0;", ["&#x00A8;", "Umlaut"],, "&#x00C6;",, "&#x00A2;",,, "&#x00D1;",, "&#x00C7;",,""],
1068
1069  // Canadian (multilingual standard):
1070
1071  Ca_normal: ["&#x002F;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1072              "&#x0071;", "&#x0077;", "&#x0065;", "&#x0072;", "&#x0074;", "&#x0079;", "&#x0075;", "&#x0069;", "&#x006F;", "&#x0070;", ["&#x005E;", "Circumflex"], "&#x00E7;", "&#x00F9;",
1073              "&#x0061;", "&#x0073;", "&#x0064;", "&#x0066;", "&#x0067;", "&#x0068;", "&#x006A;", "&#x006B;", "&#x006C;", "&#x003B;", "&#x00E8;", "&#x00E0;",
1074              "&#x007A;", "&#x0078;", "&#x0063;", "&#x0076;", "&#x0062;", "&#x006E;", "&#x006D;", "&#x002C;", "&#x002E;", "&#x00E9;"],
1075
1076  Ca_caps: ["&#x002F;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1077            "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", ["&#x005E;", "Circumflex"], "&#x00C7;", "&#x00D9;",
1078            "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x003B;", "&#x00C8;", "&#x00C0;",
1079            "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x002C;", "&#x002E;", "&#x00C9;"],
1080
1081  Ca_shift: ["&#x005C;", "&#x0021;", "&#x0040;", "&#x0023;", "&#x0024;", "&#x0025;", "&#x003F;", "&#x0026;", "&#x002A;", "&#x0028;", "&#x0029;", "&#x005F;", "&#x002B;",
1082             "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", ["&#x00A8;", "Umlaut"], "&#x00C7;", "&#x00D9;",
1083             "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x003A;", "&#x00C8;", "&#x00C0;",
1084             "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x0027;", "&#x0022;", "&#x00C9;"],
1085
1086  Ca_alt_gr: ["&#x007C;",,,,,,, "&#x007B;", "&#x007D;", "&#x005B;", "&#x005D;",, "&#x00AC;",,,,,,,,,,, ["&#x0060;", "Grave"],
1087             ["&#x007E;", "Tilde"],,,,,,,,,,, "&#x00B0;",,, "&#x00AB;", "&#x00BB;",,,,,, "&#x003C;", "&#x003E;",""],
1088
1089  // Russian:
1090
1091  Ru_normal: ["&#x0451;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1092              "&#x0439;", "&#x0446;", "&#x0443;", "&#x043A;", "&#x0435;", "&#x043D;", "&#x0433;", "&#x0448;", "&#x0449;", "&#x0437;", "&#x0445;", "&#x044A;", "&#x005C;",
1093              "&#x0444;", "&#x044B;", "&#x0432;", "&#x0430;", "&#x043F;", "&#x0440;", "&#x043E;", "&#x043B;", "&#x0434;", "&#x0436;", "&#x044D;",,
1094              "&#x044F;", "&#x0447;", "&#x0441;", "&#x043C;", "&#x0438;", "&#x0442;", "&#x044C;", "&#x0431;", "&#x044E;", "&#x002E;"],
1095
1096  Ru_caps: ["&#x0401;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1097            "&#x0419;", "&#x0426;", "&#x0423;", "&#x041A;", "&#x0415;", "&#x041D;", "&#x0413;", "&#x0428;", "&#x0429;", "&#x0417;", "&#x0425;", "&#x042A;", "&#x005C;",
1098            "&#x0424;", "&#x042B;", "&#x0412;", "&#x0410;", "&#x041F;", "&#x0420;", "&#x041E;", "&#x041B;", "&#x0414;", "&#x0416;", "&#x042D;",,
1099            "&#x042F;", "&#x0427;", "&#x0421;", "&#x041C;", "&#x0418;", "&#x0422;", "&#x042C;", "&#x0411;", "&#x042E;", "&#x002E;"],
1100
1101  Ru_shift: ["&#x0401;", "&#x0021;", "&#x0022;", "&#x2116;", "&#x003B;", "&#x0025;", "&#x003A;", "&#x003F;", "&#x002A;", "&#x0028;", "&#x0029;", "&#x005F;", "&#x002B;",
1102             "&#x0419;", "&#x0426;", "&#x0423;", "&#x041A;", "&#x0415;", "&#x041D;", "&#x0413;", "&#x0428;", "&#x0429;", "&#x0417;", "&#x0425;", "&#x042A;", "&#x002F;",
1103             "&#x0424;", "&#x042B;", "&#x0412;", "&#x0410;", "&#x041F;", "&#x0420;", "&#x041E;", "&#x041B;", "&#x0414;", "&#x0416;", "&#x042D;",,
1104             "&#x042F;", "&#x0427;", "&#x0421;", "&#x041C;", "&#x0418;", "&#x0422;", "&#x042C;", "&#x0411;", "&#x042E;", "&#x002C;"],
1105
1106  // German:
1107
1108  De_normal: [["&#x005E;", "Circumflex"], "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x00DF;", ["&#x00B4;", "Acute"],
1109              "&#x0071;", "&#x0077;", "&#x0065;", "&#x0072;", "&#x0074;", "&#x007A;", "&#x0075;", "&#x0069;", "&#x006F;", "&#x0070;", "&#x00FC;", "&#x002B;", "&#x003C;",
1110              "&#x0061;", "&#x0073;", "&#x0064;", "&#x0066;", "&#x0067;", "&#x0068;", "&#x006A;", "&#x006B;", "&#x006C;", "&#x00F6;", "&#x00E4;", "&#x0023;",
1111              "&#x0079;", "&#x0078;", "&#x0063;", "&#x0076;", "&#x0062;", "&#x006E;", "&#x006D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1112
1113  De_caps: [["&#x005E;", "Circumflex"], "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x00DF;", ["&#x00B4;", "Acute"],
1114            "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x005A;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x00DC;", "&#x002B;", "&#x003C;",
1115            "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x00D6;", "&#x00C4;", "&#x0023;",
1116            "&#x0059;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1117
1118  De_shift: ["&#x00BA;", "&#x0021;", "&#x0022;", "&#x00A7;", "&#x0024;", "&#x0025;", "&#x0026;", "&#x002F;", "&#x0028;", "&#x0029;", "&#x003D;", "&#x003F;", ["&#x0060;", "Grave"],
1119             "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x005A;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x00DC;", "&#x002A;", "&#x003E;",
1120             "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x00D6;", "&#x00C4;", "&#x0027;",
1121             "&#x0059;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x003B;", "&#x003A;", "&#x005F;"],
1122
1123  De_alt_gr: [,, "&#x00B2;", "&#x00B3;",,,, "&#x007B;", "&#x005B;", "&#x005D;", "&#x007D;", "&#x005C;",, "&#x0040;",, "&#x20AC;",,,,,,
1124              ,,, ["&#x007E;", "Tilde"], "&#x007C;",,,,,,,,,,,,,,,,,,, "&#x00B5;",,,""],
1125
1126  // French:
1127
1128  Fr_normal: ["&#x00B2;", "&#x0026;", "&#x00E9;", "&#x0022;", "&#x0027;", "&#x0028;", "&#x007C;", "&#x00E8;", "&#x005F;", "&#x00E7;", "&#x00E0;", "&#x0029;", "&#x003D;",
1129              "&#x0061;", "&#x007A;", "&#x0065;", "&#x0072;", "&#x0074;", "&#x0079;", "&#x0075;", "&#x0069;", "&#x006F;", "&#x0070;", ["&#x005E;", "Circumflex"], "&#x0024;", "&#x003C;",
1130              "&#x0071;", "&#x0073;", "&#x0064;", "&#x0066;", "&#x0067;", "&#x0068;", "&#x006A;", "&#x006B;", "&#x006C;", "&#x006D;", "&#x00F9;", "&#x002A;",
1131              "&#x0077;", "&#x0078;", "&#x0063;", "&#x0076;", "&#x0062;", "&#x006E;", "&#x002C;", "&#x003B;", "&#x003A;", "&#x0021;"],
1132
1133  Fr_caps: ["&#x00B2;", "&#x0026;", "&#x00C9;", "&#x0022;", "&#x0027;", "&#x0028;", "&#x007C;", "&#x00C8;", "&#x005F;", "&#x00C7;", "&#x00C0;", "&#x0029;", "&#x003D;",
1134            "&#x0041;", "&#x005A;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", ["&#x005E;", "Circumflex"], "&#x0024;", "&#x003C;",
1135            "&#x0051;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x004D;", "&#x00D9;", "&#x002A;",
1136            "&#x0057;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x002C;", "&#x003B;", "&#x003A;", "&#x0021;"],
1137
1138  Fr_shift: [, "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x00BA;", "&#x002B;",
1139             "&#x0041;", "&#x005A;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", ["&#x00A8;", "Umlaut"], "&#x00A3;", "&#x003E;",
1140             "&#x0051;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x004D;", "&#x0025;", "&#x00B5;",
1141             "&#x0057;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x003F;", "&#x005F;", "&#x002F;", "&#x00A7;"],
1142
1143  Fr_alt_gr: [,,, "&#x0023;", "&#x007B;", "&#x005B;", "&#x007C;",, "&#x005C;", "&#x005E;", "&#x0040;", "&#x005D;", "&#x007D;",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,""],
1144
1145  // Spanish:
1146
1147  Es_normal: ["&#x00BA;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x0092;", "&#x00A1;",
1148              "&#x0071;", "&#x0077;", "&#x0065;", "&#x0072;", "&#x0074;", "&#x0079;", "&#x0075;", "&#x0069;", "&#x006F;", "&#x0070;", ["&#x0060;", "Grave"], "&#x002B;", "&#x003C;",
1149              "&#x0061;", "&#x0073;", "&#x0064;", "&#x0066;", "&#x0067;", "&#x0068;", "&#x006A;", "&#x006B;", "&#x006C;", "&#x00F1;", ["&#x00B4;", "Acute"], "&#x00E7;",
1150              "&#x007A;", "&#x0078;", "&#x0063;", "&#x0076;", "&#x0062;", "&#x006E;", "&#x006D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1151
1152  Es_caps: ["&#x00BA;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x0092;", "&#x00A1;",
1153            "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", ["&#x0060;", "Grave"], "&#x002B;", "&#x003C;",
1154            "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x00D1;", ["&#x00B4;", "Acute"], "&#x00C7;",
1155            "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1156
1157  Es_shift: ["&#x00AA;", "&#x0021;", "&#x0022;", "&#x0027;", "&#x0024;", "&#x0025;", "&#x0026;", "&#x002F;", "&#x0028;", "&#x0029;", "&#x003D;", "&#x003F;", "&#x00BF;",
1158             "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", ["&#x005E;", "Circumflex"], "&#x002A;", "&#x003E;",
1159             "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x00D1;", ["&#x00A8;", "Umlaut"], "&#x00C7;",
1160             "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x003B;", "&#x003A;", "&#x005F;"],
1161
1162  Es_alt_gr: ["&#x005C;", "&#x007C;", "&#x0040;", "&#x0023;",,, "&#x00AC;",,,,,,,,,,,,,,,,, "&#x005B;","&#x005D;",,,,,,,,,,,, "&#x007B;", "&#x007D;",,,,,,,,,,""],
1163
1164  // Italian:
1165
1166  It_normal: ["&#x005C;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x0092;", "&#x00EC;",
1167              "&#x0071;", "&#x0077;", "&#x0065;", "&#x0072;", "&#x0074;", "&#x0079;", "&#x0075;", "&#x0069;", "&#x006F;", "&#x0070;", "&#x00E8;", "&#x002B;", "&#x003C;",
1168              "&#x0061;", "&#x0073;", "&#x0064;", "&#x0066;", "&#x0067;", "&#x0068;", "&#x006A;", "&#x006B;", "&#x006C;", "&#x00F2;", "&#x00E0;", "&#x00F9;",
1169              "&#x007A;", "&#x0078;", "&#x0063;", "&#x0076;", "&#x0062;", "&#x006E;", "&#x006D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1170
1171  It_caps: ["&#x005C;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x0092;", "&#x00EC;",
1172            "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x00C8;", "&#x002B;", "&#x003C;",
1173            "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x00D2;", "&#x00C0;", "&#x00D9;",
1174            "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1175
1176  It_shift: ["&#x007C;", "&#x0021;", "&#x0022;", "&#x00A3;", "&#x0024;", "&#x0025;", "&#x0026;", "&#x002F;", "&#x0028;", "&#x0029;", "&#x003D;", "&#x003F;", "&#x005E;",
1177             "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x0059;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x00E9;", "&#x002A;", "&#x003C;",
1178             "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x00E7;", "&#x00B0;", "&#x00A7;",
1179             "&#x005A;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x003B;", "&#x003A;", "&#x005F;"],
1180
1181  It_alt_gr: [,,,,,,,,,,,,,,,,,,,,,,"&#x005B;","&#x005D;",,,,,,,,,,,"&#x0040;","&#x0023;",,,,,,,,,,,,""],
1182
1183  It_alt_gr_shift: [,,,,,,,,,,,,,,,,,,,,,,"&#x007B;","&#x007D;",,,,,,,,,,,,,,,,,,,,,,,,""],
1184
1185  // Czech:
1186
1187  Cz_normal: ["&#x003B;", "&#x002B;", "&#x011B;", "&#x0161;", "&#x010D;", "&#x0159;", "&#x017E;", "&#x00FD;", "&#x00E1;", "&#x00ED;", "&#x00E9;", "&#x003D;", ["&#x00B4;", "Acute"],
1188              "&#x0071;", "&#x0077;", "&#x0065;", "&#x0072;", "&#x0074;", "&#x007A;", "&#x0075;", "&#x0069;", "&#x006F;", "&#x0070;", "&#x00FA;", "&#x0029;", "&#x0026;",
1189              "&#x0061;", "&#x0073;", "&#x0064;", "&#x0066;", "&#x0067;", "&#x0068;", "&#x006A;", "&#x006B;", "&#x006C;", "&#x016F;", "&#x00A7;", ["&#x00A8;", "Umlaut"],
1190              "&#x0079;", "&#x0078;", "&#x0063;", "&#x0076;", "&#x0062;", "&#x006E;", "&#x006D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1191
1192  Cz_caps: ["&#x003B;", "&#x002B;", "&#x011A;", "&#x0160;", "&#x010C;", "&#x0158;", "&#x017D;", "&#x00DD;", "&#x00C1;", "&#x00CD;", "&#x00C9;", "&#x003D;", "&#x02CA;",
1193            "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x005A;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x00DA;", "&#x0029;", "&#x0026;",
1194            "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x016E;", "&#x00A7;", ["&#x00A8;", "Umlaut"],
1195            "&#x0059;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x002C;", "&#x002E;", "&#x002D;"],
1196
1197  Cz_shift: [["&#x00BA;", "RingAbove"], "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x0025;", ["&#x02C7;", "Caron"],
1198             "&#x0051;", "&#x0057;", "&#x0045;", "&#x0052;", "&#x0054;", "&#x005A;", "&#x0055;", "&#x0049;", "&#x004F;", "&#x0050;", "&#x002F;", "&#x0028;", "&#x002A;",
1199             "&#x0041;", "&#x0053;", "&#x0044;", "&#x0046;", "&#x0047;", "&#x0048;", "&#x004A;", "&#x004B;", "&#x004C;", "&#x0022;", "&#x0021;", "&#x0027;",
1200             "&#x0059;", "&#x0058;", "&#x0043;", "&#x0056;", "&#x0042;", "&#x004E;", "&#x004D;", "&#x003F;", "&#x003A;", "&#x005F;"],
1201
1202  Cz_alt_gr: [,["&#x007E;", "Tilde"],["&#x02C7;", "Caron"],["&#x005E;", "Circumflex"],["&#x02D8;", "Breve"],["&#x00B0;", "RingAbove"],["&#x02DB;", "Ogonek"],
1203              ["&#x0060;", "Grave"],["&#x02D9;", "DotAbove"],["&#x00B4;", "Acute"],["&#x02DD;", "DoubleAcute"],["&#x00A8;", "Umlaut"],["&#x00B8;", "Cedilla"],
1204              "&#x005C;","&#x007C;","&#x20AC;",,,,,,,,"&#x00F7;", "&#x00D7;", "&#x003C;",,"&#x0111;","&#x00D0;","&#x005B;","&#x005D;",,,"&#x0142;","&#x0141;","&#x0024;", "&#x00DF;", "&#x00A4;", "&#x003E;",
1205              "&#x0023;",,"&#x0040;","&#x007B;","&#x007D;",,,,""],
1206
1207  // Greek:
1208
1209  El_normal: ["&#x00BD;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1210              "&#x003B;", "&#x03C2;", "&#x03B5;", "&#x03C1;", "&#x03C4;", "&#x03C5;", "&#x03B8;", "&#x03B9;", "&#x03BF;", "&#x03C0;", "&#x005B;", "&#x005D;", "&#x00A7;",
1211              "&#x03B1;", "&#x03C3;", "&#x03B4;", "&#x03C6;", "&#x03B3;", "&#x03B7;", "&#x03BE;", "&#x03BA;", "&#x03BB;", ["&#x00B4;", "Acute"], "&#x0092;", "&#x005C;",
1212              "&#x03B6;", "&#x03C7;", "&#x03C8;", "&#x03C9;", "&#x03B2;", "&#x03BD;", "&#x03BC;", "&#x002C;", "&#x002E;", "&#x002F;"],
1213
1214  El_caps: ["&#x00BD;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1215            "&#x003B;", "&#x03C2;", "&#x0395;", "&#x03A1;", "&#x03A4;", "&#x03A5;", "&#x0398;", "&#x0399;", "&#x039F;", "&#x03A0;", "&#x005B;", "&#x005D;", "&#x00A7;",
1216            "&#x0391;", "&#x03A3;", "&#x0394;", "&#x03A6;", "&#x0393;", "&#x0397;", "&#x039E;", "&#x039A;", "&#x039B;", ["&#x00B4;", "Acute"], "&#x0092;", "&#x005C;",
1217            "&#x0396;", "&#x03A7;", "&#x03A8;", "&#x03A9;", "&#x0392;", "&#x039D;", "&#x039C;", "&#x002C;", "&#x002E;", "&#x002F;"],
1218
1219  El_shift: ["&#x00B1;", "&#x0021;", "&#x0040;", "&#x0023;", "&#x0024;", "&#x0025;", "&#x005E;", "&#x0026;", "&#x002A;", "&#x0028;", "&#x0029;", "&#x005F;", "&#x002B;",
1220             "&#x003A;", "&#x00A6;", "&#x0395;", "&#x03A1;", "&#x03A4;", "&#x03A5;", "&#x0398;", "&#x0399;", "&#x039F;", "&#x03A0;", "&#x007B;", "&#x007D;", "&#x00A9;",
1221             "&#x0391;", "&#x03A3;", "&#x0394;", "&#x03A6;", "&#x0393;", "&#x0397;", "&#x039E;", "&#x039A;", "&#x039B;", ["&#x00A8;", "Umlaut"], "&#x0091;", "&#x007C;",
1222             "&#x0396;", "&#x03A7;", "&#x03A8;", "&#x03A9;", "&#x0392;", "&#x039D;", "&#x039C;", "&#x003C;", "&#x003E;", "&#x003F;"],
1223
1224  El_alt_gr: [,,"&#x00B2;", "&#x00B3;", "&#x00A3;", "&#x00A7;", "&#x00B6;",, "&#x00A4;", "&#x00A6;", "&#x00B0;", "&#x00B1;", "&#x00BD;",,,,,,
1225              ,,,,,"&#x00AB;", "&#x00BB;",,,,,,,,,,,["&#x0385;", "DialytikaTonos"],, "&#x00AC;",,,,,,,,,,""],
1226
1227  // Hebrew:
1228
1229  He_normal: ["&#x003B;", "&#x0031;", "&#x0032;", "&#x0033;", "&#x0034;", "&#x0035;", "&#x0036;", "&#x0037;", "&#x0038;", "&#x0039;", "&#x0030;", "&#x002D;", "&#x003D;",
1230              "&#x002F;", "&#x0027;", "&#x05E7;", "&#x05E8;", "&#x05D0;", "&#x05D8;", "&#x05D5;", "&#x05DF;", "&#x05DD;", "&#x05E4;", "&#x005B;", "&#x005D;", "&#x005C;",
1231              "&#x05E9;", "&#x05D3;", "&#x05D2;", "&#x05DB;", "&#x05E2;", "&#x05D9;", "&#x05D7;", "&#x05DC;", "&#x05DA;", "&#x05E3;", "&#x002C;",,
1232              "&#x05D6;", "&#x05E1;", "&#x05D1;", "&#x05D4;", "&#x05E0;", "&#x05DE;", "&#x05E6;", "&#x05EA;", "&#x05E5;", "&#x002E;"],
1233
1234  He_shift: ["&#x007E;", "&#x0021;", "&#x0040;", "&#x0023;", "&#x0024;", "&#x0025;", "&#x005E;", "&#x0026;", "&#x002A;", "&#x0028;", "&#x0029;", "&#x005F;", "&#x002B;",
1235             "&#x002F;", "&#x0027;", "&#x05E7;", "&#x05E8;", "&#x05D0;", "&#x05D8;", "&#x05D5;", "&#x05DF;", "&#x05DD;", "&#x05E4;", "&#x007B;", "&#x007D;", "&#x007C;",
1236             "&#x05E9;", "&#x05D3;", "&#x05D2;", "&#x05DB;", "&#x05E2;", "&#x05D9;", "&#x05D7;", "&#x05DC;", "&#x05DA;", "&#x003A;", "&#x0022;",,
1237             "&#x05D6;", "&#x05E1;", "&#x05D1;", "&#x05D4;", "&#x05E0;", "&#x05DE;", "&#x05E6;", "&#x003C;", "&#x003E;", "&#x003F;"],
1238
1239  He_alt_gr: [,,,,"&#x20AA;",,,,,,,"&#x05BE;",,,,,,,,"&#x05F0;",,,,,,,,,,,,"&#x05F2;","&#x05F1;",,,,,,,,,,,,,,,""],
1240
1241  // Diacritic arrays:
1242
1243  Acute: [["&#x0061;", "&#x00E1;"], ["&#x0065;", "&#x00E9;"], ["&#x0069;", "&#x00ED;"], ["&#x006F;", "&#x00F3;"],
1244          ["&#x0075;", "&#x00FA;"], ["&#x0079;", "&#x00FD;"], ["&#x0041;", "&#x00C1;"], ["&#x0045;", "&#x00C9;"],
1245          ["&#x0049;", "&#x00CD;"], ["&#x004F;", "&#x00D3;"], ["&#x0055;", "&#x00DA;"], ["&#x0059;", "&#x00DD;"],
1246          ["&#x0063;", "&#x0107;"], ["&#x0043;", "&#x0106;"], ["&#x006C;", "&#x013A;"], ["&#x004C;", "&#x0139;"],
1247          ["&#x006D;", "&#x1E3F;"], ["&#x004D;", "&#x1E3E;"], ["&#x006E;", "&#x0144;"], ["&#x004E;", "&#x0143;"],
1248          ["&#x0072;", "&#x0155;"], ["&#x0052;", "&#x0154;"], ["&#x0073;", "&#x015B;"], ["&#x0053;", "&#x015A;"],
1249          ["&#x007A;", "&#x017A;"], ["&#x005A;", "&#x0179;"], ["&#x0391;", "&#x0386;"], ["&#x0395;", "&#x0388;"],
1250          ["&#x0397;", "&#x0389;"], ["&#x0399;", "&#x038A;"], ["&#x039F;", "&#x038C;"], ["&#x03A5;", "&#x038E;"],
1251          ["&#x03A9;", "&#x038F;"], ["&#x03B1;", "&#x03AC;"], ["&#x03B5;", "&#x03AD;"], ["&#x03B7;", "&#x03AE;"],
1252          ["&#x03B9;", "&#x03AF;"], ["&#x03BF;", "&#x03CC;"], ["&#x03C5;", "&#x03CD;"], ["&#x03C9;", "&#x03CE;"],
1253          ["&#x0057;", "&#x1E82;"], ["&#x0077;", "&#x1E83;"]],
1254
1255  Breve: [["&#x0061;", "&#x0103;"], ["&#x0065;", "&#x0115;"], ["&#x0069;", "&#x012D;"], ["&#x006F;", "&#x014F;"],
1256          ["&#x0075;", "&#x016D;"], ["&#x0041;", "&#x0102;"], ["&#x0045;", "&#x0114;"], ["&#x0049;", "&#x012C;"],
1257          ["&#x004F;", "&#x014E;"], ["&#x0055;", "&#x016C;"], ["&#x0079;", "y&#x306;"], ["&#x0059;", "Y&#x306;"],
1258          ["&#x0067;", "&#x011F;"], ["&#x0047;", "&#x011E;"]],
1259
1260  Caron: [["&#x0063;", "&#x010D;"], ["&#x0043;", "&#x010C;"], ["&#x0064;", "&#x010F;"], ["&#x0044;", "&#x010E;"],
1261          ["&#x0065;", "&#x011B;"], ["&#x0045;", "&#x011A;"], ["&#x006E;", "&#x0148;"], ["&#x004E;", "&#x0147;"],
1262          ["&#x0072;", "&#x0159;"], ["&#x0052;", "&#x0158;"], ["&#x0073;", "&#x0161;"], ["&#x0053;", "&#x0160;"],
1263          ["&#x0074;", "&#x0165;"], ["&#x0054;", "&#x0164;"], ["&#x007A;", "&#x017E;"], ["&#x005A;", "&#x017D;"],
1264          ["&#x006C;", "&#x013E;"], ["&#x004C;", "&#x013D;"]],
1265
1266  Cedilla: [["&#x0063;", "&#x00E7;"], ["&#x0043;", "&#x00C7;"], ["&#x0067;", "&#x0123;"], ["&#x0047;", "&#x0122;"],
1267            ["&#x006B;", "&#x0137;"], ["&#x004B;", "&#x0136;"], ["&#x006C;", "&#x013C;"], ["&#x004C;", "&#x013B;"],
1268            ["&#x006E;", "&#x0146;"], ["&#x004E;", "&#x0145;"], ["&#x0072;", "&#x0157;"], ["&#x0052;", "&#x0156;"],
1269            ["&#x0073;", "&#x015F;"], ["&#x0053;", "&#x015E;"], ["&#x0074;", "&#x0163;"], ["&#x0054;", "&#x0162;"]],
1270
1271  Circumflex: [["&#x0061;", "&#x00E2;"], ["&#x0041;", "&#x00C2;"], ["&#x0065;", "&#x00EA;"], ["&#x0045;", "&#x00CA;"],
1272               ["&#x0069;", "&#x00EE;"], ["&#x0049;", "&#x00CE;"], ["&#x006F;", "&#x00F4;"], ["&#x004F;", "&#x00D4;"],
1273               ["&#x0063;", "&#x0109;"], ["&#x0043;", "&#x0108;"], ["&#x0067;", "&#x011D;"], ["&#x0047;", "&#x011C;"],
1274               ["&#x0068;", "&#x0125;"], ["&#x0048;", "&#x0124;"], ["&#x006A;", "&#x0135;"], ["&#x004A;", "&#x0134;"],
1275               ["&#x0073;", "&#x015D;"], ["&#x0053;", "&#x015C;"], ["&#x0075;", "&#x00FB;"], ["&#x0055;", "&#x00DB;"],
1276               ["&#x0077;", "&#x0175;"], ["&#x0057;", "&#x0174;"], ["&#x0079;", "&#x0177;"], ["&#x0059;", "&#x0176;"]],
1277
1278  DialytikaTonos: [["&#x03B9;", "&#x0390;"], ["&#x03C6;", "&#x03B0;"]], // combined acute + ulmaut
1279
1280  DotAbove: [["&#x0063;", "&#x010B;"], ["&#x0043;", "&#x010A;"], ["&#x0067;", "&#x0121;"], ["&#x0047;", "&#x0120;"],
1281             ["&#x007A;", "&#x017C;"], ["&#x005A;", "&#x017B;"], ["&#x0065;", "&#x0117;"], ["&#x0045;", "&#x0116;"],
1282             ["&#x006E;", "&#x1E45;"], ["&#x004E;", "&#x1E44;"], ["&#x006D;", "m&#x307;"], ["&#x004D;", "M&#x307;"],
1283             ["&#x0062;", "b&#x307;"], ["&#x0042;", "B&#x307;"]],
1284
1285  DoubleAcute: [["&#x006F;", "&#x0151;"], ["&#x004F;", "&#x0150;"], ["&#x0075;", "&#x0171;"], ["&#x0055;", "&#x0170;"]],
1286
1287  Grave: [["&#x0061;", "&#x00E0;"], ["&#x0065;", "&#x00E8;"], ["&#x0069;", "&#x00EC;"], ["&#x006F;", "&#x00F2;"], ["&#x0075;", "&#x00F9;"],
1288          ["&#x0041;", "&#x00C0;"], ["&#x0045;", "&#x00C8;"], ["&#x0049;", "&#x00CC;"], ["&#x004F;", "&#x00D2;"], ["&#x0055;", "&#x00D9;"],
1289          ["&#x0057;", "&#x1E80;"], ["&#x0077;", "&#x1E81;"], ["&#x0059;", "&#x1EF2;"], ["&#x0079;", "&#x1EF3;"],
1290          ["&#x006D;", "m&#x300;"], ["&#x004D;", "M&#x300;"], ["&#x006E;", "n&#x300;"], ["&#x004E;", "N&#x300;"]],
1291
1292  Ogonek: [["&#x0069;", "&#x012F;"], ["&#x006F;", "&#x01EB;"], ["&#x0075;", "&#x0173;"],
1293           ["&#x0049;", "&#x012E;"], ["&#x004F;", "&#x01EA;"], ["&#x0055;", "&#x0172;"]],
1294
1295  RingAbove: [["&#x0061;", "&#x00E5;"], ["&#x0041;", "&#x00C5;"], ["&#x0075;", "&#x016F;"], ["&#x0055;", "&#x016E;"]],
1296
1297  Tilde: [["&#x0061;", "&#x00E3;"], ["&#x006F;", "&#x00F5;"], ["&#x006E;", "&#x00F1;"], ["&#x0041;", "&#x00C3;"], ["&#x004F;", "&#x00D5;"],
1298          ["&#x0069;", "&#x0129;"], ["&#x0049;", "&#x0128;"], ["&#x0075;", "&#x0169;"], ["&#x0055;", "&#x0168;"], ["&#x004E;", "&#x00D1;"],
1299          ["&#x0065;", "&#x1EBD;"], ["&#x0045;", "&#x1EBC;"], ["&#x0079;", "&#x1EF9;"], ["&#x0059;", "&#x1EF8;"], ["&#x0067;", "g&#x303;"],
1300          ["&#x0047;", "G&#x303;"]],
1301
1302  Umlaut: [["&#x0061;", "&#x00E4;"], ["&#x0065;", "&#x00EB;"], ["&#x0069;", "&#x00EF;"], ["&#x006F;", "&#x00F6;"], ["&#x0075;", "&#x00FC;"],
1303           ["&#x0079;", "&#x00FF;"], ["&#x0041;", "&#x00C4;"], ["&#x0045;", "&#x00CB;"], ["&#x0049;", "&#x00CF;"], ["&#x004F;", "&#x00D6;"],
1304           ["&#x0055;", "&#x00DC;"], ["&#x0059;", "&#x0178;"], ["&#x0399;", "&#x03AA;"], ["&#x03A5;", "&#x03AB;"], ["&#x03B9;", "&#x03CA;"],
1305           ["&#x03C5;", "&#x03CB;"]]
1306};
Note: See TracBrowser for help on using the repository browser.