Add new language specified script 17/138117/1 accepted/tizen_5.0_unified accepted/tizen_5.5_unified accepted/tizen_5.5_unified_mobile_hotfix accepted/tizen_5.5_unified_wearable_hotfix accepted/tizen_6.0_unified accepted/tizen_6.0_unified_hotfix tizen_5.0 tizen_5.5 tizen_5.5_mobile_hotfix tizen_5.5_tv tizen_5.5_wearable_hotfix tizen_6.0 tizen_6.0_hotfix accepted/tizen/5.0/unified/20181102.023610 accepted/tizen/5.5/unified/20191031.015740 accepted/tizen/5.5/unified/mobile/hotfix/20201027.075215 accepted/tizen/5.5/unified/wearable/hotfix/20201027.111336 accepted/tizen/6.0/unified/20201030.104407 accepted/tizen/6.0/unified/hotfix/20201103.000513 accepted/tizen/unified/20180703.163729 submit/tizen/20180703.095812 submit/tizen_5.0/20181101.000005 submit/tizen_5.5/20191031.000005 submit/tizen_5.5_mobile_hotfix/20201026.185105 submit/tizen_5.5_wearable_hotfix/20201026.184305 submit/tizen_6.0/20201029.205501 submit/tizen_6.0_hotfix/20201102.192901 submit/tizen_6.0_hotfix/20201103.115101 tizen_5.5.m2_release tizen_6.0.m2_release
authorSuyeon Hwang <stom.hwang@samsung.com>
Tue, 11 Jul 2017 06:36:08 +0000 (15:36 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Tue, 11 Jul 2017 06:36:08 +0000 (15:36 +0900)
Change-Id: Ia6890e4bf43e6006799de24454991378228c545d
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
15 files changed:
js/vc-webview-de_DE.js [new file with mode: 0755]
js/vc-webview-en_GB.js [new file with mode: 0755]
js/vc-webview-en_US.js
js/vc-webview-es_ES.js [new file with mode: 0755]
js/vc-webview-es_US.js [new file with mode: 0755]
js/vc-webview-fr_FR.js [new file with mode: 0755]
js/vc-webview-it_IT.js [new file with mode: 0755]
js/vc-webview-ja_JP.js [new file with mode: 0755]
js/vc-webview-ko_KR.js
js/vc-webview-pt_BR.js [new file with mode: 0755]
js/vc-webview-ru_RU.js [new file with mode: 0755]
js/vc-webview-zh_CN.js [new file with mode: 0755]
js/vc-webview-zh_HK.js [new file with mode: 0755]
js/vc-webview-zh_SG.js [new file with mode: 0755]
js/vc-webview-zh_TW.js [new file with mode: 0755]

diff --git a/js/vc-webview-de_DE.js b/js/vc-webview-de_DE.js
new file mode 100755 (executable)
index 0000000..1a45ad5
--- /dev/null
@@ -0,0 +1,332 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-de_DE.js
+ *
+ *  This source code is a language specified script for German(de_DE).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['ein', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun', 'zehn',
+               'elf', 'zwölf', 'dreizehn', 'vierzehn', 'fünfzehn', 'sechzehn', 'siebzehn', 'achtzehn', 'neunzehn', 'zwanzig',
+               'einundzwanzig', 'zweiundzwanzig', 'dreiundzwanzig', 'vierundzwanzig', 'fünfundzwanzig', 'sechsundzwanzig', 'siebenundzwanzig', 'achtundzwanzig', 'neunundzwanzig', 'dreissig',
+               'einunddreissig', 'zweiunddreissig', 'dreiunddreissig', 'vierunddreissig', 'fünfunddreissig', 'sechsunddreissig', 'siebenunddreissig', 'achtunddreissig', 'neununddreissig', 'vierzig',
+               'einundvierzig', 'zweiundvierzig', 'dreiundvierzig', 'vierundvierzig', 'fünfundvierzig', 'sechsundvierzig', 'siebenundvierzig', 'achtundvierzig', 'neunundvierzig', 'fünfzig',
+               'einundfünfzig', 'zweiundfünfzig', 'dreiundfünfzig', 'vierundfünfzig', 'fünfundfünfzig', 'sechsundfünfzig', 'siebenundfünfzig', 'achtundfünfzig', 'neunundfünfzig', 'sechzig',
+               'einundsechzig', 'zweiundsechzig', 'dreiundsechzig', 'vierundsechzig', 'fünfundsechzig', 'sechsundsechzig', 'siebenundsechzig', 'achtundsechzig', 'neunundsechzig', 'siebzig',
+               'einundsiebzig', 'zweiundsiebzig', 'dreiundsiebzig', 'vierundsiebzig', 'fünfundsiebzig', 'sechsundsiebzig', 'siebenundsiebzig', 'achtundsiebzig', 'neunundsiebzig', 'achtzig',
+               'einundachtzig', 'zweiundachtzig', 'dreiundachtzig', 'vierundachtzig', 'fünfundachtzig', 'sechsundachtzig', 'siebenundachtzig', 'achtundachtzig', 'neunundachtzig', 'neunzig',
+               'einundneunzig', 'zweiundneunzig', 'dreiundneunzig', 'vierundneunzig', 'fünfundneunzig', 'sechsundneunzig', 'siebenundneunzig', 'achtundneunzig', 'neunundneunzig', 'hundert'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'suchen google';
+       var googleSearch2 = ['suchen', 'auf google'];
+       var youtubeSearch = 'suchen youtube';
+       var youtubeSearch2 = ['suchen', 'auf youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'erfrischen' || convert == 'neuladen') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'runterscrollen') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == 'hochscrollen') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'quellcode') {
+               vc_print_html();
+       } else if (convert == 'nächster' || convert == 'vorwärts') {
+               history.forward();
+       } else if (convert == 'zuvor' || convert == 'zurück' || convert == 'früher') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-en_GB.js b/js/vc-webview-en_GB.js
new file mode 100755 (executable)
index 0000000..89a6d17
--- /dev/null
@@ -0,0 +1,381 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-en_GB.js
+ *
+ *  This source code is a language specified script for English(en_GB).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
+               'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty',
+               'twenty one', 'twenty two', 'twenty three', 'twenty four', 'twenty five', 'twenty six', 'twenty seven', 'twenty eight', 'twenty nine', 'thirty',
+               'thirty one', 'thirty two', 'thirty three', 'thirty four', 'thirty five', 'thirty six', 'thirty seven', 'thirty eight', 'thirty nine', 'forty',
+               'forty one', 'forty two', 'forty three', 'forty four', 'forty five', 'forty six', 'forty seven', 'forty eight', 'forty nine', 'fifty',
+               'fifty one', 'fifty two', 'fifty three', 'fifty four', 'fifty five', 'fifty six', 'fifty seven', 'fifty eight', 'fifty nine', 'sixty',
+               'sixty one', 'sixty two', 'sixty three', 'sixty four', 'sixty five', 'sixty six', 'sixty seven', 'sixty eight', 'sixty nine', 'seventy',
+               'seventy one', 'seventy two', 'seventy three', 'seventy four', 'seventy five', 'seventy six', 'seventy seven', 'seventy eight', 'seventy nine', 'eighty',
+               'eighty one', 'eighty two', 'eighty three', 'eighty four', 'eighty five', 'eighty six', 'eighty seven', 'eighty eight', 'eighty nine', 'ninety',
+               'ninety one', 'ninety two', 'ninety three', 'ninety four', 'ninety five', 'ninety six', 'ninety seven', 'ninety eight', 'ninety nine', 'hundred'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       if (true == convert.startsWith('to') && (' ' == text[2] || text.length == 2)) {
+               if (vc_visible_hints[1].type == 'input' || text.length == 2) {
+                       result = {
+                               cmd : 2,
+                               param : text.substr(3).trim()
+                       };
+                       return result;
+               }
+       } else if (true == convert.startsWith('for') && (' ' == text[3] || text.length == 3)) {
+               if (vc_visible_hints[3].type == 'input' || text.length == 3) {
+                       result = {
+                               cmd : 4,
+                               param : text.substr(4).trim()
+                       };
+                       return result;
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       var idx_sep;
+       if (isNaN(result.cmd) == true) {
+               if (0 < (idx_sep = result.param.includes('st ')) && !isNaN(result.param.substr(0, idx_sep))) {
+                       if (idx_sep == result.param.length - 1) {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = '';
+                       } else {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = result.param.substr(idx_sep + 3, result.param.length);
+                       }
+               } else if (0 < (idx_sep = result.param.includes('nd ')) && !isNaN(result.param.substr(0, idx_sep))) {
+                       if (idx_sep == result.param.length - 1) {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = '';
+                       } else {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = result.param.substr(idx_sep + 3, result.param.length);
+                       }
+               } else if (0 < (idx_sep = result.param.includes('th ')) && !isNaN(result.param.substr(0, idx_sep))) {
+                       if (idx_sep == result.param.length - 1) {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = '';
+                       } else {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = result.param.substr(idx_sep + 3, result.param.length);
+                       }
+               }
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'search google';
+       var googleSearch2 = ['search', 'on google'];
+       var youtubeSearch = 'search youtube';
+       var youtubeSearch2 = ['search', 'on youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'refresh' || convert == 'reload') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'scrolldown') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == 'scrollup') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'tothetop') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'showsourcecode') {
+               vc_print_html();
+       } else if (convert == 'next' || convert == 'forward') {
+               history.forward();
+       } else if (convert == 'before' || convert == 'back' || convert == 'previous') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
index fe01a8b..40906a9 100755 (executable)
@@ -28,7 +28,7 @@
  */
 function vc_search_word(param, replace) {
        /* phase 2. search partial word in the webpage */
-       /* second, compare with links in html documents */
+       /* First, compare with links in html documents */
        if (vc_flag_log == true) {
                vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
        }
@@ -63,7 +63,7 @@ function vc_search_word(param, replace) {
                return el;
        }
 
-       /* first, compare with whole text of elements in html documents */
+       /* Second, compare with whole text of elements in html documents */
        var result = [];
        for (var i = 0; i < resultTokenArr.length; i++) {
                var obj = vc_selector([resultTokenArr[i]]);
@@ -225,7 +225,16 @@ function vc_search_pronunciation(param) {
  * @param text  text string from voice-control-webview.cpp.
  */
 function vc_is_included_number(text) {
-       var numbers = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
+       var numbers = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
+               'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty',
+               'twenty one', 'twenty two', 'twenty three', 'twenty four', 'twenty five', 'twenty six', 'twenty seven', 'twenty eight', 'twenty nine', 'thirty',
+               'thirty one', 'thirty two', 'thirty three', 'thirty four', 'thirty five', 'thirty six', 'thirty seven', 'thirty eight', 'thirty nine', 'forty',
+               'forty one', 'forty two', 'forty three', 'forty four', 'forty five', 'forty six', 'forty seven', 'forty eight', 'forty nine', 'fifty',
+               'fifty one', 'fifty two', 'fifty three', 'fifty four', 'fifty five', 'fifty six', 'fifty seven', 'fifty eight', 'fifty nine', 'sixty',
+               'sixty one', 'sixty two', 'sixty three', 'sixty four', 'sixty five', 'sixty six', 'sixty seven', 'sixty eight', 'sixty nine', 'seventy',
+               'seventy one', 'seventy two', 'seventy three', 'seventy four', 'seventy five', 'seventy six', 'seventy seven', 'seventy eight', 'seventy nine', 'eighty',
+               'eighty one', 'eighty two', 'eighty three', 'eighty four', 'eighty five', 'eighty six', 'eighty seven', 'eighty eight', 'eighty nine', 'ninety',
+               'ninety one', 'ninety two', 'ninety three', 'ninety four', 'ninety five', 'ninety six', 'ninety seven', 'ninety eight', 'ninety nine', 'hundred'];
        var convert = text.toLowerCase();
        var result;
 
@@ -283,6 +292,35 @@ function vc_correct_parameter(text) {
                result.param = result.param.substr(words[0].length + 1).trim();
        }
 
+       var idx_sep;
+       if (isNaN(result.cmd) == true) {
+               if (0 < (idx_sep = result.param.includes('st ')) && !isNaN(result.param.substr(0, idx_sep))) {
+                       if (idx_sep == result.param.length - 1) {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = '';
+                       } else {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = result.param.substr(idx_sep + 3, result.param.length);
+                       }
+               } else if (0 < (idx_sep = result.param.includes('nd ')) && !isNaN(result.param.substr(0, idx_sep))) {
+                       if (idx_sep == result.param.length - 1) {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = '';
+                       } else {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = result.param.substr(idx_sep + 3, result.param.length);
+                       }
+               } else if (0 < (idx_sep = result.param.includes('th ')) && !isNaN(result.param.substr(0, idx_sep))) {
+                       if (idx_sep == result.param.length - 1) {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = '';
+                       } else {
+                               result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                               result.param = result.param.substr(idx_sep + 3, result.param.length);
+                       }
+               }
+       }
+
        return result
 }
 
@@ -294,17 +332,25 @@ function vc_correct_parameter(text) {
 function vc_check_web_control(text) {
        text = text.toLowerCase();
        var convert = text.replace(/ /g, '');
-       var googleSearch = 'google search';
-       var youtubeSearch = 'youtube search';
+       var googleSearch = 'search google';
+       var googleSearch2 = ['search', 'on google'];
+       var youtubeSearch = 'search youtube';
+       var youtubeSearch2 = ['search', 'on youtube'];
 
        if (text.startsWith(googleSearch) == true) {
-               location.href = 'https://www.google.co.kr/search?q=' + (text.substr(googleSearch.length)).trim();
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
        } else if (text.startsWith(youtubeSearch) == true) {
                location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
-       } else if (convert == 'refresh') {
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'refresh' || convert == 'reload') {
                location.reload();
        } else if (convert == 'google') {
-               location.href = 'https://www.google.co.kr/';
+               location.href = 'https://www.google.com/';
        } else if (convert == 'facebook') {
                location.href = 'https://www.facebook.com/';
        } else if (convert == 'amazon') {
diff --git a/js/vc-webview-es_ES.js b/js/vc-webview-es_ES.js
new file mode 100755 (executable)
index 0000000..30ec0c9
--- /dev/null
@@ -0,0 +1,353 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-es_ES.js
+ *
+ *  This source code is a language specified script for Spanish(es_ES).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['uno', 'dos', 'tres', 'cuatro', 'sinco', 'seis', 'siete', 'ocho', 'nueve', 'diez',
+               'on ce', 'doce', 'trece', 'catorce', 'quince', 'dieciseis', 'diecisiete', 'dieciocho', 'diecinueve', 'veinte',
+               'veinti uno', 'veinti dos', 'veinti tres', 'veinti cuatro', 'veinti sinco', 'veinti seis', 'veinti siete', 'veinti ocho', 'veinti nueve', 'treinta',
+               'treinta y uno', 'treinta y dos', 'treinta y tres', 'treinta y cuatro', 'treinta y sinco', 'treinta y seis', 'treinta y siete', 'treinta y ocho', 'treinta y nueve', 'cuarenta',
+               'cuarenta y uno', 'cuarenta y dos', 'cuarenta y tres', 'cuarenta y cuatro', 'cuarenta y sinco', 'cuarenta y seis', 'cuarenta y siete', 'cuarenta y ocho', 'cuarenta y nueve', 'cincuenta',
+               'cincuenta y uno', 'cincuenta y dos', 'cincuenta y tres', 'cincuenta y cuatro', 'cincuenta y sinco', 'cincuenta y seis', 'cincuenta y siete', 'cincuenta y ocho', 'cincuenta y nueve', 'sesenta',
+               'sesenta y uno', 'sesenta y dos', 'sesenta y tres', 'sesenta y cuatro', 'sesenta y sinco', 'sesenta y seis', 'sesenta y siete', 'sesenta y ocho', 'sesenta y nueve', 'setenta',
+               'setenta y uno', 'setenta y dos', 'setenta y tres', 'setenta y cuatro', 'setenta y sinco', 'setenta y seis', 'setenta y siete', 'setenta y ocho', 'setenta y nueve', 'ochenta',
+               'ochenta y uno', 'ochenta y dos', 'ochenta y tres', 'ochenta y cuatro', 'ochenta y sinco', 'ochenta y seis', 'ochenta y siete', 'ochenta y ocho', 'ochenta y nueve', 'noventa',
+               'noventa y uno', 'noventa y dos', 'noventa y tres', 'noventa y cuatro', 'noventa y sinco', 'noventa y seis', 'noventa y siete', 'noventa y ocho', 'noventa y nueve', 'cien'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       var idx_sep;
+       if (0 < (idx_sep = result.param.includes('º ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       } else if (0 < (idx_sep = result.param.includes('ª ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'busca no google';
+       var googleSearch2 = ['buscar', 'en google'];
+       var youtubeSearch = 'busca no youtube';
+       var youtubeSearch2 = ['buscar', 'en youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'refrescar') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'scrolldown') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == 'scrollup') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'iralacima') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'código fuente') {
+               vc_print_html();
+       } else if (convert == 'siguiente' || convert == 'adelante') {
+               history.forward();
+       } else if (convert == 'antes' || convert == 'espalda' || convert == 'previo' || convert == 'previa') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-es_US.js b/js/vc-webview-es_US.js
new file mode 100755 (executable)
index 0000000..e8a49a5
--- /dev/null
@@ -0,0 +1,353 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-es_US.js
+ *
+ *  This source code is a language specified script for Spanish(es_US).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['uno', 'dos', 'tres', 'cuatro', 'sinco', 'seis', 'siete', 'ocho', 'nueve', 'diez',
+               'on ce', 'doce', 'trece', 'catorce', 'quince', 'dieciseis', 'diecisiete', 'dieciocho', 'diecinueve', 'veinte',
+               'veinti uno', 'veinti dos', 'veinti tres', 'veinti cuatro', 'veinti sinco', 'veinti seis', 'veinti siete', 'veinti ocho', 'veinti nueve', 'treinta',
+               'treinta y uno', 'treinta y dos', 'treinta y tres', 'treinta y cuatro', 'treinta y sinco', 'treinta y seis', 'treinta y siete', 'treinta y ocho', 'treinta y nueve', 'cuarenta',
+               'cuarenta y uno', 'cuarenta y dos', 'cuarenta y tres', 'cuarenta y cuatro', 'cuarenta y sinco', 'cuarenta y seis', 'cuarenta y siete', 'cuarenta y ocho', 'cuarenta y nueve', 'cincuenta',
+               'cincuenta y uno', 'cincuenta y dos', 'cincuenta y tres', 'cincuenta y cuatro', 'cincuenta y sinco', 'cincuenta y seis', 'cincuenta y siete', 'cincuenta y ocho', 'cincuenta y nueve', 'sesenta',
+               'sesenta y uno', 'sesenta y dos', 'sesenta y tres', 'sesenta y cuatro', 'sesenta y sinco', 'sesenta y seis', 'sesenta y siete', 'sesenta y ocho', 'sesenta y nueve', 'setenta',
+               'setenta y uno', 'setenta y dos', 'setenta y tres', 'setenta y cuatro', 'setenta y sinco', 'setenta y seis', 'setenta y siete', 'setenta y ocho', 'setenta y nueve', 'ochenta',
+               'ochenta y uno', 'ochenta y dos', 'ochenta y tres', 'ochenta y cuatro', 'ochenta y sinco', 'ochenta y seis', 'ochenta y siete', 'ochenta y ocho', 'ochenta y nueve', 'noventa',
+               'noventa y uno', 'noventa y dos', 'noventa y tres', 'noventa y cuatro', 'noventa y sinco', 'noventa y seis', 'noventa y siete', 'noventa y ocho', 'noventa y nueve', 'cien'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       var idx_sep;
+       if (0 < (idx_sep = result.param.includes('º ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       } else if (0 < (idx_sep = result.param.includes('ª ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'busca no google';
+       var googleSearch2 = ['buscar', 'en google'];
+       var youtubeSearch = 'busca no youtube';
+       var youtubeSearch2 = ['buscar', 'en youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'refrescar') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'scrolldown') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == 'scrollup') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'iralacima') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'código fuente') {
+               vc_print_html();
+       } else if (convert == 'siguiente' || convert == 'adelante') {
+               history.forward();
+       } else if (convert == 'antes' || convert == 'espalda' || convert == 'previo' || convert == 'previa') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-fr_FR.js b/js/vc-webview-fr_FR.js
new file mode 100755 (executable)
index 0000000..8f6f210
--- /dev/null
@@ -0,0 +1,334 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-fr_FR.js
+ *
+ *  This source code is a language specified script for French(fr_FR).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix',
+               'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf', 'vingt',
+               'vingt et un', 'vingt-deux', 'vingt-trois', 'vingt-quatre', 'vingt-cinq', 'vingt-six', 'vingt-sept', 'vingt-huit', 'vingt-neuf', 'trente',
+               'trente et un', 'trente-deux', 'trente-trois', 'trente-quatre', 'trente-cinq', 'trente-six', 'trente-sept', 'trente-huit', 'trente-neuf', 'quarante',
+               'quarante et un', 'quarante-deux', 'quarante-trois', 'quarante-quatre', 'quarante-cinq', 'quarante-six', 'quarante-sept', 'quarante-huit', 'quarante-neuf', 'cinquante',
+               'cinquante et un', 'cinquante-deux', 'cinquante-trois', 'cinquante-quatre', 'cinquante-cinq', 'cinquante-six', 'cinquante-sept', 'cinquante-huit', 'cinquante-neuf',
+               'soixante', 'soixante et un', 'soixante-deux', 'soixante-trois', 'soixante-quatre', 'soixante-cinq', 'soixante-six', 'soixante-sept', 'soixante-huit', 'soixante-neuf', 'soixante-dix',
+               'soixante et onze', 'soixante-douze', 'soixante-treize', 'soixante-quatorze', 'soixante-quinze', 'soixante-seize', 'soixante-dix-sept', 'soixante-dix-huit', 'soixante-dix-neuf','quatre-vingts',
+               'quatre-vingt-un', 'quatre-vingt-deux', 'quatre-vingt-trois', 'quatre-vingt-quatre', 'quatre-vingt-cinq', 'quatre-vingt-six', 'quatre-vingt-sept', 'quatre-vingt-huit', 'quatre-vingt-neuf', 'quatre-vingt-dix',
+               'quatre-vingt-onze', 'quatre-vingt-douze', 'quatre-vingt-treize', 'quatre-vingt-quatorze', 'quatre-vingt-quinze', 'quatre-vingt-seize', 'quatre-vingt-dix-sept', 'quatre-vingt-dix-huit', 'quatre-vingt-dix-neuf', 'cent'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'rechercher google';
+       var googleSearch2 = ['rechercher', 'sur google'];
+       var youtubeSearch = 'rechercher youtube';
+       var youtubeSearch2 = ['rechercher', 'sur youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'recharger' || convert == 'rafraîchir') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'scrolldown') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == 'scrollup') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'allerausommet') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'codesource') {
+               vc_print_html();
+       } else if (convert == 'prochain' || convert == "vers l'avant") {
+               history.forward();
+       } else if (convert == 'avant' || convert == 'arrière' || convert == 'précédent') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-it_IT.js b/js/vc-webview-it_IT.js
new file mode 100755 (executable)
index 0000000..ae7bb0f
--- /dev/null
@@ -0,0 +1,353 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-it_IT.js
+ *
+ *  This source code is a language specified script for Italian(it_IT).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['uno', 'due', 'tre', 'quattro', 'cinque', 'sei', 'sette', 'otto', 'nove', 'dieci',
+               'undici', 'dodici', 'tredici', 'quattordici', 'quindici', 'sedici', 'diciasette', 'diciotto', 'diciannove', 'venti',
+               'ventiuno', 'ventidue', 'ventitre', 'ventiquattro', 'venticinque', 'ventisei', 'ventisette', 'ventiotto', 'ventinove', 'trenta',
+               'trentauno', 'trentadue', 'trentatre', 'trentaquattro', 'trentacinque', 'trentasei', 'trentasette', 'trentaotto', 'trentanove', 'quaranta',
+               'quarantauno', 'quarantadue', 'quarantatre', 'quarantaquattro', 'quarantacinque', 'quarantasei', 'quarantasette', 'quarantaotto', 'quarantanove', 'cinquanta',
+               'cinquantauno', 'cinquantadue', 'cinquantatre', 'cinquantaquattro', 'cinquantacinque', 'cinquantasei', 'cinquantasette', 'cinquantaotto', 'cinquantanove', 'sessanta',
+               'sessantauno', 'sessantadue', 'sessantatre', 'sessantaquattro', 'sessantacinque', 'sessantasei', 'sessantasette', 'sessantaotto', 'sessantanove', 'settanta',
+               'settantauno', 'settantadue', 'settantatre', 'settantaquattro', 'settantacinque', 'settantasei', 'settantasette', 'settantaotto', 'settantanove', 'ottanta',
+               'ottantauno', 'ottantadue', 'ottantatre', 'ottantaquattro', 'ottantacinque', 'ottantasei', 'ottantasette', 'ottantaotto', 'ottantanove', 'novanta',
+               'novantauno', 'novantadue', 'novantatre', 'novantaquattro', 'novantacinque', 'novantasei', 'novantasette', 'novantaotto', 'novantanove', 'cento',];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       var idx_sep;
+       if (0 < (idx_sep = result.param.includes('º ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       } else if (0 < (idx_sep = result.param.includes('ª ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'ricerca google';
+       var googleSearch2 = ['ricerca', 'su google'];
+       var youtubeSearch = 'ricerca youtube';
+       var youtubeSearch2 = ['ricerca', 'su youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'ricaricare') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'scorriversoilbasso') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == "scorriversol'alto") {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'vaiincima') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'codicesorgente') {
+               vc_print_html();
+       } else if (convert == 'prossimo' || convert == 'inoltrare') {
+               history.forward();
+       } else if (convert == 'prima' || convert == 'indietro' || convert == 'precedente') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-ja_JP.js b/js/vc-webview-ja_JP.js
new file mode 100755 (executable)
index 0000000..68ffedf
--- /dev/null
@@ -0,0 +1,223 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-jp_JP.js
+ *
+ *  This source code is a language specified script for Japanese(jp_JP).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.replace(/ /gi, '');
+       var threshold = resultTokenArr.length * 0.6;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the character keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十',
+               '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
+               '二十一', '二十二', '二十三', '二十四', '二十五', '二十六', '二十七', '二十八', '二十九', '三十',
+               '三十一', '三十二', '三十三', '三十四', '三十五', '三十六', '三十七', '三十八', '三十九', '四十',
+               '四十一', '四十二', '四十三', '四十四', '四十五', '四十六', '四十七', '四十八', '四十九', '五十',
+               '五十一', '五十二', '五十三', '五十四', '五十五', '五十六', '五十七', '五十八', '五十九', '六十',
+               '六十一', '六十二', '六十三', '六十四', '六十五', '六十六', '六十七', '六十八', '六十九', '七十',
+               '七十一', '七十二', '七十三', '七十四', '七十五', '七十六', '七十七', '七十八', '七十九', '八十',
+               '八十一', '八十二', '八十三', '八十四', '八十五', '八十六', '八十七', '八十八', '八十九', '九十',
+               '九十一', '九十二', '九十三', '九十四', '九十五', '九十六', '九十七', '九十八', '九十九', '百'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'google 検索';
+       var youtubeSearch = 'youtube 検索';
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (convert == 'リフレッシュ') {
+               location.reload();
+       } else if (convert == '下にスクロール') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == '上にスクロール') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'トップに行き') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'ソースコード') {
+               vc_print_html();
+       } else if (convert == '次の' || convert == '前方に') {
+               history.forward();
+       } else if (convert == '前に' || convert == 'バック' || convert == '前') {
+               history.back();
+       } else if (convert == '記録' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
index 25c4cdd..eca5a93 100755 (executable)
@@ -29,7 +29,7 @@
  */
 function vc_search_word(param, replace) {
        /* phase 2. search partial word in the webpage */
-       /* second, compare with links in html documents */
+       /* First, compare with links in html documents */
        if (vc_flag_log == true) {
                vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
        }
@@ -65,7 +65,7 @@ function vc_search_word(param, replace) {
                return el;
        }
 
-       /* first, compare with whole text of elements in html documents */
+       /* Second, compare with whole text of elements in html documents */
        var result = [];
        for (var i = 0; i < resultTokenArr.length; i++) {
                var obj = vc_selector([resultTokenArr[i]]);
@@ -444,7 +444,7 @@ function vc_check_web_control(text) {
        var youtubeSearch2 = '유튜브 ';
 
        if (text.startsWith(googleSearch) == true) {
-               location.href = 'https://www.google.co.kr/search?q=' + (text.substr(googleSearch.length)).trim();
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
        } else if (text.startsWith(naverSearch) == true) {
                location.href = 'https://search.naver.com/search.naver?where=nexearch&query=' + (text.substr(naverSearch.length)).trim();
        } else if (text.startsWith(youtubeSearch) == true) {
@@ -452,13 +452,13 @@ function vc_check_web_control(text) {
        } else if (convert == '유튜브TV') {
                location.href = 'https://www.youtube.com/tv';
        } else if (text.startsWith(googleSearch2) == true) {
-               location.href = 'https://www.google.co.kr/search?q=' + (text.substr(googleSearch2.length)).trim();
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch2.length)).trim();
        } else if (text.startsWith(naverSearch2) == true) {
                location.href = 'https://search.naver.com/search.naver?where=nexearch&query=' + (text.substr(naverSearch2.length)).trim();
        } else if (text.startsWith(youtubeSearch2) == true) {
                location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch2.length)).trim();
        } else if (convert.startsWith('구글') == true) {
-               location.href = 'https://www.google.co.kr/';
+               location.href = 'https://www.google.com/';
        } else if (convert.startsWith('네이버') == true) {
                location.href = 'http://www.naver.com/';
        } else if (convert.startsWith('유튜브') == true) {
diff --git a/js/vc-webview-pt_BR.js b/js/vc-webview-pt_BR.js
new file mode 100755 (executable)
index 0000000..0ff0ae8
--- /dev/null
@@ -0,0 +1,365 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-pt_BR.js
+ *
+ *  This source code is a language specified script for Portuguese(pt_BR).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = [['um', 'uma'], ['dois', 'duas'], 'três', 'quartro', 'cinco', 'seis', 'sete', 'oito', 'nove', 'dez',
+               'onze', 'doze', 'treze', 'catorze', 'quinze', 'dezesseis', 'dezessete', 'dezeoito', 'dezenove', 'vinte',
+               ['vinte e um', 'vinte e uma'], ['vinte e dois', 'vinte e duas'], 'vinte e três', 'vinte e quartro', 'vinte e cinco', 'vinte e seis', 'vinte e sete', 'vinte e oito', 'vinte e nove', 'trinda',
+               ['trinda e um', 'trinda e uma'], ['trinda e dois', 'trinda e duas'], 'trinda e três', 'trinda e quartro', 'trinda e cinco', 'trinda e seis', 'trinda e sete', 'trinda e oito', 'trinda e nove', 'quarenta',
+               ['quarenta e um', 'quarenta e uma'], ['quarenta e dois', 'quarenta e duas'], 'quarenta e três', 'quarenta e quartro', 'quarenta e cinco', 'quarenta e seis', 'quarenta e sete', 'quarenta e oito', 'quarenta e nove', 'cinquenta',
+               ['cinquenta e um', 'cinquenta e uma'], ['cinquenta e dois', 'cinquenta e duas'], 'cinquenta e três', 'cinquenta e quartro', 'cinquenta e cinco', 'cinquenta e seis', 'cinquenta e sete', 'cinquenta e oito', 'cinquenta e nove', 'sessenta',
+               ['sessenta e um', 'sessenta e uma'], ['sessenta e dois', 'sessenta e duas'], 'sessenta e três', 'sessenta e quartro', 'sessenta e cinco', 'sessenta e seis', 'sessenta e sete', 'sessenta e oito', 'sessenta e nove', 'setenta',
+               ['setenta e um', 'setenta e uma'], ['setenta e dois', 'setenta e duas'], 'setenta e três', 'setenta e quartro', 'setenta e cinco', 'setenta e seis', 'setenta e sete', 'setenta e oito', 'setenta e nove', 'oitenta',
+               ['oitenta e um', 'oitenta e uma'], ['oitenta e dois', 'oitenta e duas'], 'oitenta e três', 'oitenta e quartro', 'oitenta e cinco', 'oitenta e seis', 'oitenta e sete', 'oitenta e oito', 'oitenta e nove', 'noventa',
+               ['noventa e um', 'noventa e uma'], ['noventa e dois', 'noventa e duas'], 'noventa e três', 'noventa e quartro', 'noventa e cinco', 'noventa e seis', 'noventa e sete', 'noventa e oito', 'noventa e nove', 'cem'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == Array.isArray(numbers[i])) {
+                       for (var j = 0; numbers[i].length > j; j++) {
+                               if (true == convert.startsWith(numbers[i][j]) && (' ' == text[numbers[i][j].length] || text.length == numbers[i][j].length)) {
+                                       var partial = text.substr(numbers[i][j].length);
+
+                                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i][j].length) {
+                                               result = {
+                                                       cmd : (i + 1),
+                                                       param : partial.trim()
+                                               };
+                                               return result;
+                                       }
+                               }       
+                       }
+               } else {
+                       if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                               var partial = text.substr(numbers[i].length);
+
+                               if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                                       result = {
+                                               cmd : (i + 1),
+                                               param : partial.trim()
+                                       };
+                                       return result;
+                               }
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       var idx_sep;
+       if (0 < (idx_sep = result.param.includes('º ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       } else if (0 < (idx_sep = result.param.includes('ª ')) && !isNaN(result.param.substr(0, idx_sep))) {
+               if (idx_sep == result.param.length - 1) {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = '';
+               } else {
+                       result.cmd = parseFloat(result.param.substr(0, idx_sep));
+                       result.param = result.param.substr(idx_sep + 2, result.param.length);
+               }
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'busca no google';
+       var googleSearch2 = ['pesquisa', 'no google'];
+       var youtubeSearch = 'busca no youtube';
+       var youtubeSearch2 = ['pesquisa', 'no youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'recarregar' || convert == 'refrescar') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'iratéotopo') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'códigofonte') {
+               vc_print_html();
+       } else if (convert == 'próximo') {
+               history.forward();
+       } else if (convert == 'antesde' || convert == 'devolta' || convert == 'anterior') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-ru_RU.js b/js/vc-webview-ru_RU.js
new file mode 100755 (executable)
index 0000000..d95883b
--- /dev/null
@@ -0,0 +1,334 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-ru_RU.js
+ *
+ *  This source code is a language specified script for Russian(ru_RU).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.split(' ');
+       var threshold = resultTokenArr.length * 0.3;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       return vc_search_character(param);
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       vc_print_log('=== start searching(character level)');
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(200, 100, 0, 1)';
+       }
+       var similarity = [];
+       var threshold = 0;
+
+       param = param.toLowerCase().split(' ');
+       for (var i = 0; i < vc_all_elem.length; i++) {
+               if (vc_all_elem[i].childElementCount == 0 && vc_is_visible(vc_all_elem[i]) == true) {
+                       var text = vc_all_elem[i].textContent.replace(/[`~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ' ').toLowerCase().split(' ');
+                       var score = 0;
+
+                       for(var k = 0; k < param.length; k++) {
+                               var min = 2147483647;
+
+                               if (3 > param[k].length) {
+                                       continue;
+                               }
+
+                               for(var j = 0; j < text.length; j++) {
+                                       if (3 > text[j].length) {
+                                               continue;
+                                       }
+                                       var cost = [];
+                                       var ncost = [];
+                                       var longStr;
+                                       var shortStr;
+
+                                       if (text[j].length > param[k].length) {
+                                               longStr = text[j];
+                                               shortStr = param[k];
+                                       } else {
+                                               longStr = param[k];
+                                               shortStr = text[j];
+                                       }
+
+                                       for (var l = 0; l <= longStr.length; l++) {
+                                               cost[l] = l;
+                                       }
+
+                                       for (var s = 1; s <= shortStr.length; s++) {
+                                               ncost[0] = s;
+
+                                               for (var l = 1; l <= longStr.length; l++) {
+                                                       var match = shortStr[s - 1] == longStr[l - 1] ? 0 : 1;
+
+                                                       var rep = cost[l - 1] + match;
+                                                       var ins = cost[l] + 1;
+                                                       var del = ncost[l - 1] + 1;
+
+                                                       ncost[l] = Math.min(rep, ins, del);
+                                               }
+
+                                               var arr = cost;
+                                               cost = ncost;
+                                               ncost = arr;
+                                       }
+
+                                       if (param[k].length * 0.25 >= cost[longStr.length] && min > cost[longStr.length]) {
+                                               min = cost[longStr.length];
+                                       }
+                               }
+
+                               if (min < 2147483647) {
+                                       score = score + min;
+                               } else {
+                                       score = score + param[k].length;
+                               }
+                       }
+
+                       similarity.push(score);
+               } else {
+                       similarity.push(2147483647);
+               }
+       }
+
+       vc_print_log('=== finish searching(character level)');
+
+       var min = 2147483647;
+       for (var i = 0; i < similarity.length; i++) {
+               if (min > similarity[i]) {
+                       min = similarity[i];
+               }
+       }
+
+       for (var i = 0; i < param.length; i++) {
+               if (3 <= param[i].length) {
+                       threshold = threshold + param[i].length;
+               }
+       }
+
+       if (threshold > min) {
+               return vc_all_elem[similarity.indexOf(min)];
+       }
+
+       return undefined;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['один', 'два', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять', 'десять',
+               'одиннадцать', 'двенадцать', 'тринадцать', 'четырнадцать', 'пятнадцать', 'шестнадцать', 'семнадцать', 'восемнадцать', 'девятнадцать', 'двадцать',
+               'двадцать один', 'двадцать два', 'двадцать три', 'двадцать четыре', 'двадцать пять', 'двадцать шесть', 'двадцать семь', 'двадцать восемь', 'двадцать девять', 'тридцать',
+               'тридцать один', 'тридцать два', 'тридцать три', 'тридцать четыре', 'тридцать пять', 'тридцать шесть', 'тридцать семь', 'тридцать восемь', 'тридцать девять', 'сорок',
+               'сорок один', 'сорок два', 'сорок три', 'сорок четыре', 'сорок пять', 'сорок шесть', 'сорок семь', 'сорок восемь', 'сорок девять', 'пятьдесят',
+               'пятьдесят один', 'пятьдесят два', 'пятьдесят три', 'пятьдесят четыре', 'пятьдесят пять', 'пятьдесят шесть', 'пятьдесят семь', 'пятьдесят восемь', 'пятьдесят девять', 'шестьдесят',
+               'шестьдесят один', 'шестьдесят два', 'шестьдесят три', 'шестьдесят четыре', 'шестьдесят пять', 'шестьдесят шесть', 'шестьдесят семь', 'шестьдесят восемь', 'шестьдесят девять', 'семьдесят',
+               'семьдесят один', 'семьдесят два', 'семьдесят три', 'семьдесят четыре', 'семьдесят пять', 'семьдесят шесть', 'семьдесят семь', 'семьдесят восемь', 'семьдесят девять', 'восемьдесят',
+               'восемьдесят один', 'восемьдесят два', 'восемьдесят три', 'восемьдесят четыре', 'восемьдесят пять', 'восемьдесят шесть', 'восемьдесят семь', 'восемьдесят восемь', 'восемьдесят девять', 'девяносто',
+               'девяносто один', 'девяносто два', 'девяносто три', 'девяносто четыре', 'девяносто пять', 'девяносто шесть', 'девяносто семь', 'девяносто восемь', 'девяносто девять', 'сто'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+       var googleSearch = 'поиск в google';
+       var googleSearch2 = ['поиска', 'в google'];
+       var youtubeSearch = 'поиск в youtube';
+       var youtubeSearch2 = ['поиска', 'в youtube'];
+
+       if (text.startsWith(googleSearch) == true) {
+               location.href = 'https://www.google.com/search?q=' + (text.substr(googleSearch.length)).trim();
+       } else if (text.startsWith(googleSearch2[0]) && text.endsWith(googleSearch2[1])) {
+               var query = text.substr(googleSearch2[0].length, text.length - googleSearch2[0].length - googleSearch2[1].length);
+               location.href = 'https://www.google.com/search?q=' + query.trim();
+       } else if (text.startsWith(youtubeSearch) == true) {
+               location.href = 'https://www.youtube.com/results?search_query=' + (text.substr(youtubeSearch.length)).trim();
+       } else if (text.startsWith(youtubeSearch2[0]) && text.endsWith(youtubeSearch2[1])) {
+               var query = text.substr(youtubeSearch2[0].length, text.length - youtubeSearch2[0].length - youtubeSearch2[1].length);
+               location.href = 'https://www.youtube.com/results?search_query=' + query.trim();
+       } else if (convert == 'обновите') {
+               location.reload();
+       } else if (convert == 'google') {
+               location.href = 'https://www.google.com/';
+       } else if (convert == 'facebook') {
+               location.href = 'https://www.facebook.com/';
+       } else if (convert == 'amazon') {
+               location.href = 'https://www.amazon.com/';
+       } else if (convert == 'yahoo') {
+               location.href = 'https://www.yahoo.com/';
+       } else if (convert == 'youtube') {
+               location.href = 'https://www.youtube.com/';
+       } else if (convert == 'scrolldown') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == 'scrollup') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == 'перейтикначалу') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == 'исходныйкод') {
+               vc_print_html();
+       } else if (convert == 'следующий' || convert == 'вперед') {
+               history.forward();
+       } else if (convert == 'предыдущие') {
+               history.back();
+       } else if (convert == 'playlog' && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-zh_CN.js b/js/vc-webview-zh_CN.js
new file mode 100755 (executable)
index 0000000..881703b
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-zh_CN.js
+ *
+ *  This source code is a language specified script for Chinese(zh_CN).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.replace(/ /gi, '');
+       var threshold = resultTokenArr.length * 0.6;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the character keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十',
+               '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
+               '二十一', '二十二', '二十三', '二十四', '二十五', '二十六', '二十七', '二十八', '二十九', '三十',
+               '三十一', '三十二', '三十三', '三十四', '三十五', '三十六', '三十七', '三十八', '三十九', '四十',
+               '四十一', '四十二', '四十三', '四十四', '四十五', '四十六', '四十七', '四十八', '四十九', '五十',
+               '五十一', '五十二', '五十三', '五十四', '五十五', '五十六', '五十七', '五十八', '五十九', '六十',
+               '六十一', '六十二', '六十三', '六十四', '六十五', '六十六', '六十七', '六十八', '六十九', '七十',
+               '七十一', '七十二', '七十三', '七十四', '七十五', '七十六', '七十七', '七十八', '七十九', '八十',
+               '八十一', '八十二', '八十三', '八十四', '八十五', '八十六', '八十七', '八十八', '八十九', '九十',
+               '九十一', '九十二', '九十三', '九十四', '九十五', '九十六', '九十七', '九十八', '九十九', '百'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+
+       if (convert == '刷新' || convert == '重新加载') {
+               location.reload();
+       } else if (convert == '向下滚动' || convert == '向下滾動') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == '向上滚动' || convert == '向上滾動') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == '去顶部' || convert == '去頂部') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == '源代碼' || convert == '源代码') {
+               vc_print_html();
+       } else if (convert == '下一个' || convert == '下一個' || convert == '向前' || convert == '前进' || convert == '前進') {
+               history.forward();
+       } else if (convert == '背部' || convert == '背部' || convert == '前' || convert == '以前') {
+               history.back();
+       } else if ((convert == '记录' || convert == '記錄') && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-zh_HK.js b/js/vc-webview-zh_HK.js
new file mode 100755 (executable)
index 0000000..6afbd3b
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-zh_HK.js
+ *
+ *  This source code is a language specified script for Chinese(zh_HK).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.replace(/ /gi, '');
+       var threshold = resultTokenArr.length * 0.6;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the character keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十',
+               '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
+               '二十一', '二十二', '二十三', '二十四', '二十五', '二十六', '二十七', '二十八', '二十九', '三十',
+               '三十一', '三十二', '三十三', '三十四', '三十五', '三十六', '三十七', '三十八', '三十九', '四十',
+               '四十一', '四十二', '四十三', '四十四', '四十五', '四十六', '四十七', '四十八', '四十九', '五十',
+               '五十一', '五十二', '五十三', '五十四', '五十五', '五十六', '五十七', '五十八', '五十九', '六十',
+               '六十一', '六十二', '六十三', '六十四', '六十五', '六十六', '六十七', '六十八', '六十九', '七十',
+               '七十一', '七十二', '七十三', '七十四', '七十五', '七十六', '七十七', '七十八', '七十九', '八十',
+               '八十一', '八十二', '八十三', '八十四', '八十五', '八十六', '八十七', '八十八', '八十九', '九十',
+               '九十一', '九十二', '九十三', '九十四', '九十五', '九十六', '九十七', '九十八', '九十九', '百'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+
+       if (convert == '刷新' || convert == '重新加载') {
+               location.reload();
+       } else if (convert == '向下滚动' || convert == '向下滾動') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == '向上滚动' || convert == '向上滾動') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == '去顶部' || convert == '去頂部') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == '源代碼' || convert == '源代码') {
+               vc_print_html();
+       } else if (convert == '下一个' || convert == '下一個' || convert == '向前' || convert == '前进' || convert == '前進') {
+               history.forward();
+       } else if (convert == '背部' || convert == '背部' || convert == '前' || convert == '以前') {
+               history.back();
+       } else if ((convert == '记录' || convert == '記錄') && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-zh_SG.js b/js/vc-webview-zh_SG.js
new file mode 100755 (executable)
index 0000000..ee4468d
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-zh_SG.js
+ *
+ *  This source code is a language specified script for Chinese(zh_SG).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.replace(/ /gi, '');
+       var threshold = resultTokenArr.length * 0.6;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the character keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十',
+               '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
+               '二十一', '二十二', '二十三', '二十四', '二十五', '二十六', '二十七', '二十八', '二十九', '三十',
+               '三十一', '三十二', '三十三', '三十四', '三十五', '三十六', '三十七', '三十八', '三十九', '四十',
+               '四十一', '四十二', '四十三', '四十四', '四十五', '四十六', '四十七', '四十八', '四十九', '五十',
+               '五十一', '五十二', '五十三', '五十四', '五十五', '五十六', '五十七', '五十八', '五十九', '六十',
+               '六十一', '六十二', '六十三', '六十四', '六十五', '六十六', '六十七', '六十八', '六十九', '七十',
+               '七十一', '七十二', '七十三', '七十四', '七十五', '七十六', '七十七', '七十八', '七十九', '八十',
+               '八十一', '八十二', '八十三', '八十四', '八十五', '八十六', '八十七', '八十八', '八十九', '九十',
+               '九十一', '九十二', '九十三', '九十四', '九十五', '九十六', '九十七', '九十八', '九十九', '百'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+
+       if (convert == '刷新' || convert == '重新加载') {
+               location.reload();
+       } else if (convert == '向下滚动' || convert == '向下滾動') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == '向上滚动' || convert == '向上滾動') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == '去顶部' || convert == '去頂部') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == '源代碼' || convert == '源代码') {
+               vc_print_html();
+       } else if (convert == '下一个' || convert == '下一個' || convert == '向前' || convert == '前进' || convert == '前進') {
+               history.forward();
+       } else if (convert == '背部' || convert == '背部' || convert == '前' || convert == '以前') {
+               history.back();
+       } else if ((convert == '记录' || convert == '記錄') && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file
diff --git a/js/vc-webview-zh_TW.js b/js/vc-webview-zh_TW.js
new file mode 100755 (executable)
index 0000000..5dd23a0
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ *   Copyright 2017 Samsung Electronics Co., Ltd.
+ *
+ *   Licensed under the Flora License, Version 1.1 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://floralicense.org/license/
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+/**
+ * vc-webview-zh_TW.js
+ *
+ *  This source code is a language specified script for Chinese(zh_TW).
+ */
+
+/**
+ * vc_search_word function found the text with similarity calculated using words in the @param.
+ *
+ * @param param  param from voice-control.
+ * @param replace  If replace true, function correct some confused charaters and try again.
+ */
+function vc_search_word(param, replace) {
+       /* phase 2. search partial word in the webpage */
+       /* First, compare with links in html documents */
+       if (vc_flag_log == true) {
+               vc_rec_result.style.background = 'rgba(0, 100, 200, 1)';
+       }
+       var resultTokenArr = param.replace(/ /gi, '');
+       var threshold = resultTokenArr.length * 0.6;
+       var temp = [];
+       var el = undefined;
+
+       vc_print_log('=== start vc_search_word');
+
+       for (var i = 0; i < vc_text_indicators.length; ++i) {
+               var text = vc_text_indicators[i].textContent.replace(/[ `~!‘’@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '').toLowerCase();
+               temp[i] = 0;
+
+               for (var j = 0; j < resultTokenArr.length; j++) {
+                       if (vc_is_visible(vc_text_indicators[i], vc_scr, true) && text.indexOf(resultTokenArr[j].toLowerCase()) != -1) {
+                               temp[i]++;
+                       }
+               }
+       }
+
+       var max = -1;
+
+       for (var i = 0; i < vc_text_indicators.length; i++) {
+               if (temp[i] >= threshold && (max == -1 || temp[i] > temp[max])) {
+                       el = vc_text_indicators[i];
+                       max = i;
+               }
+       }
+
+       if (el != undefined) {
+               return el;
+       }
+
+       /* Second, compare with whole text of elements in html documents */
+       var result = [];
+       for (var i = 0; i < resultTokenArr.length; i++) {
+               var obj = vc_selector([resultTokenArr[i]]);
+               for (var j = 0; j < obj.length; j++) {
+                       temp = obj[j];
+                       if (temp.childElementCount === 0) {
+                               if (temp.hasAttribute('vc_count') == false) {
+                                       temp.setAttribute('vc_count', 1);
+                                       result.push(temp);
+                               } else {
+                                       temp.setAttribute('vc_count', parseInt(temp.getAttribute('vc_count')) + 1);
+                               }
+                       }
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               var vccnt = parseInt(result[i].getAttribute('vc_count'));
+               if (vccnt >= threshold && (el == undefined || vccnt > parseInt(el.getAttribute('vc_count')))) {
+                       el = result[i];
+               }
+       }
+
+       for (var i = 0; i < result.length; i++) {
+               result[i].removeAttribute('vc_count');
+       }
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using characters in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_character(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the character keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_search_word function found the text with similarity calculated using pronunciation keys in the @param.
+ *
+ * @param param  param from voice-control.
+ */
+function vc_search_pronunciation(param) {
+       var el = undefined;
+
+       /* TODO: Fill the logic here to find the link or text include the pronunciation keys in param.
+        * If you find the link or text, then allocate that into el.
+        * If the language does not need to pronunciation comapring, you can erase this function.
+        */
+
+       return el;
+}
+
+/**
+ * vc_is_included_number function separate a number value from the @text.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_is_included_number(text) {
+       var numbers = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十',
+               '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
+               '二十一', '二十二', '二十三', '二十四', '二十五', '二十六', '二十七', '二十八', '二十九', '三十',
+               '三十一', '三十二', '三十三', '三十四', '三十五', '三十六', '三十七', '三十八', '三十九', '四十',
+               '四十一', '四十二', '四十三', '四十四', '四十五', '四十六', '四十七', '四十八', '四十九', '五十',
+               '五十一', '五十二', '五十三', '五十四', '五十五', '五十六', '五十七', '五十八', '五十九', '六十',
+               '六十一', '六十二', '六十三', '六十四', '六十五', '六十六', '六十七', '六十八', '六十九', '七十',
+               '七十一', '七十二', '七十三', '七十四', '七十五', '七十六', '七十七', '七十八', '七十九', '八十',
+               '八十一', '八十二', '八十三', '八十四', '八十五', '八十六', '八十七', '八十八', '八十九', '九十',
+               '九十一', '九十二', '九十三', '九十四', '九十五', '九十六', '九十七', '九十八', '九十九', '百'];
+       var convert = text.toLowerCase();
+       var result;
+
+       for (var i = 0; numbers.length > i; i++) {
+               if (true == convert.startsWith(numbers[i]) && (' ' == text[numbers[i].length] || text.length == numbers[i].length)) {
+                       var partial = text.substr(numbers[i].length);
+
+                       if (vc_visible_hints[i].type == 'input' || text.length == numbers[i].length) {
+                               result = {
+                                       cmd : (i + 1),
+                                       param : partial.trim()
+                               };
+                               return result;
+                       }
+               }
+       }
+
+       result = {
+               cmd : NaN,
+               param : text.trim()
+       };
+
+       return result;
+}
+
+/**
+ * vc_correct_parameter function correct the voice recognition result.
+ *
+ * @param text  text string from voice-control-webview.cpp.
+ */
+function vc_correct_parameter(text) {
+       var result = vc_is_included_number(text),
+       words = result.param.split(' ');
+
+       if (isNaN(result.cmd) == true && isNaN(words[0]) == false) {
+               result.cmd = parseFloat(words[0]);
+               result.param = result.param.substr(words[0].length + 1).trim();
+       }
+
+       return result
+}
+
+/**
+ * vc_check_web_control function check some special keyword and run it.
+ *
+ * @param spokenWord  voice recognized result string.
+ */
+function vc_check_web_control(text) {
+       text = text.toLowerCase();
+       var convert = text.replace(/ /g, '');
+
+       if (convert == '刷新' || convert == '重新加载') {
+               location.reload();
+       } else if (convert == '向下滚动' || convert == '向下滾動') {
+               vc_scroll_event_firing('DOWN');
+       } else if (convert == '向上滚动' || convert == '向上滾動') {
+               vc_scroll_event_firing('UP');
+       } else if (convert == '去顶部' || convert == '去頂部') {
+               vc_scroll_event_firing('TOP');
+       } else if (convert == '源代碼' || convert == '源代码') {
+               vc_print_html();
+       } else if (convert == '下一个' || convert == '下一個' || convert == '向前' || convert == '前进' || convert == '前進') {
+               history.forward();
+       } else if (convert == '背部' || convert == '背部' || convert == '前' || convert == '以前') {
+               history.back();
+       } else if ((convert == '记录' || convert == '記錄') && vc_flag_log) {
+               if (vc_log_area.style.visibility == 'visible') vc_log_area.style.visibility = 'hidden';
+               else vc_log_area.style.visibility = 'visible';
+       } else {
+               return false;
+       }
+       return true;
+}
\ No newline at end of file