Automatic Translate Addon For Loco Translate - Version 2.0

Version Description

Download this release

Release Info

Developer Narinder singh
Plugin Icon 128x128 Automatic Translate Addon For Loco Translate
Version 2.0
Comparing to
See all releases

Code changes from version 1.9.1 to 2.0

assets/css/custom.css ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #cool-auto-translate-btn:before {
2
+ padding-right: 5px !IMPORTANT;
3
+ }
4
+ #cool-auto-translate-btn:after{
5
+ content: "No API Required!";
6
+ clear: both;
7
+ display: block;
8
+ font-size: 10px;
9
+ font-weight: bold;
10
+ font-family: monospace;
11
+ position: absolute;
12
+ bottom: -6px;
13
+ left: -1px;
14
+ background: #129412;
15
+ width: calc(100% + 2px);
16
+ height: 12px;
17
+ line-height: 12px;
18
+ color: #fff;
19
+ text-align: center;
20
+ border-radius: 0 0 4px 4px;
21
+ }
22
+ /*form fieldset button.button.has-icon.icon-robot:after {
23
+ content: "API Required!";
24
+ clear: both;
25
+ display: block;
26
+ font-size: 9px;
27
+ font-weight: bold;
28
+ font-family: monospace;
29
+ position: absolute;
30
+ bottom: -6px;
31
+ left: -1px;
32
+ background: #403c3c;
33
+ width: calc(100% + 2px);
34
+ height: 12px;
35
+ line-height: 12px;
36
+ color: #fff;
37
+ text-align: center;
38
+ border-radius: 0 0 4px 4px;
39
+ }*/
40
+
41
+
42
+ span.proonly-button {
43
+ background: #555;
44
+ color: #fff;
45
+ font-size: 12px;
46
+ font-weight: bold;
47
+ font-family: monospace;
48
+ padding: 3px;
49
+ border-radius: 3px;
50
+ display: inline-block;
51
+ margin: 2px 10px;
52
+ }
53
+ span.proonly-button a {
54
+ color: #fff;
55
+ text-decoration: none;
56
+ }
57
+ span.proonly-button.alsofree {
58
+ background: green;
59
+ }
60
+
61
+
62
+ #atlt_strings_model {
63
+ display: none;
64
+ position: fixed;
65
+ z-index: 99999;
66
+ top: 0;
67
+ width: 100%;
68
+ height: 100vh;
69
+ overflow: hidden;
70
+ background-color: rgba(0, 0, 0, 0.75);
71
+ }
72
+ #atlt_strings_model .modal-content {
73
+ position: relative;
74
+ background-color: #fefefe;
75
+ width: 80%;
76
+ height: calc(100% - 40px);
77
+ margin: 32px auto 0;
78
+ overflow: hidden;
79
+ border-radius: 5px;
80
+ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
81
+ -webkit-animation-name: animatetop;
82
+ -webkit-animation-duration: 0.4s;
83
+ animation-name: animatetop;
84
+ animation-duration: 0.4s;
85
+ }
86
+ @-webkit-keyframes animatetop {
87
+ from {top:-300px; opacity:0}
88
+ to {top:0; opacity:1}
89
+ }
90
+ @keyframes animatetop {
91
+ from {top:-300px; opacity:0}
92
+ to {top:0; opacity:1}
93
+ }
94
+
95
+
96
+ #atlt_strings_model .modal-header {
97
+ padding: 2px 16px;
98
+ background-color: #5cb85c;
99
+ color: white;
100
+ height: 86px;
101
+ max-height: 86px;
102
+ overflow: hidden;
103
+ position: relative;
104
+ }
105
+ #atlt_strings_model .modal-header h2 {
106
+ display: inline-block;
107
+ font-size: 18px;
108
+ color: #000;
109
+ padding: 0;
110
+ margin: 18px 159px 5px 0px;
111
+ width: calc(100% - 160px);
112
+ }
113
+ /* The Close Button */
114
+ #atlt_strings_model .modal-header .close {
115
+ color: white;
116
+ font-size: 28px;
117
+ font-weight: bold;
118
+ position: absolute;
119
+ right: 10px;
120
+ top: 20px;
121
+ }
122
+ #atlt_strings_model .modal-header .close:hover,
123
+ #atlt_strings_model .modal-header .close:focus {
124
+ color: #000;
125
+ text-decoration: none;
126
+ cursor: pointer;
127
+ }
128
+ #atlt_strings_model .save_btn_cont {
129
+ margin: 8px;
130
+ position: absolute;
131
+ top: 10px;
132
+ right: 40px;
133
+ }
134
+ #atlt_strings_model .ytstats {
135
+ padding: 0;
136
+ margin: 5px 160px 5px 0;
137
+ width: calc(100% - 160px);
138
+ }
139
+ #atlt_strings_model .ytstats a {
140
+ color: #fff936;
141
+ }
142
+
143
+
144
+ #atlt_strings_model .modal-body {
145
+ padding: 2px 16px;
146
+ position: relative;
147
+ }
148
+ #atlt_strings_model .notice-dismiss {
149
+ padding:0;
150
+ }
151
+ #atlt_strings_model h3 {
152
+ width: 100%;
153
+ display: inline-block;
154
+ font-size: 20px;
155
+ padding: 0;
156
+ margin: 20px 0 0;
157
+ }
158
+ #translate_element {
159
+ margin-bottom: 25px;
160
+ }
161
+ #atlt_strings_model .string_container {
162
+ overflow-y: scroll;
163
+ overflow-x: hidden;
164
+ height: calc(100vh - 460px);
165
+ width: 100%;
166
+ position: relative;
167
+ }
168
+ #atlt_strings_model table {
169
+ border-spacing: 0;
170
+ border-collapse: collapse;
171
+ width: 100%;
172
+ max-width: 100%;
173
+ table-layout: fixed;
174
+ padding:0;
175
+ margin:0;
176
+ }
177
+ #atlt_strings_model table td:first-child, #atlt_strings_model table th:first-child {
178
+ width: 60px;
179
+ text-align: center;
180
+ }
181
+ #atlt_strings_model table td, #atlt_strings_model table th {
182
+ border: 1px solid #ddd;
183
+ padding: 4px;
184
+ height: 26px;
185
+ text-align: left;
186
+ white-space: nowrap;
187
+ font-size: 12px;
188
+ line-height: 14px;
189
+ overflow: hidden;
190
+ vertical-align: middle;
191
+ }
192
+ #atlt_strings_model .my_translate_progress {
193
+ position: absolute;
194
+ display: none;
195
+ top: 0;
196
+ left: 10px;
197
+ color: #fff;
198
+ background: rgba(0, 0, 0, 0.5);
199
+ width: calc(100% - 22px);
200
+ border-radius: 3px;
201
+ height: 100%;
202
+ z-index: 9;
203
+ box-sizing: border-box;
204
+ font-size: 16px;
205
+ line-height: 20px;
206
+ font-weight: bold;
207
+ text-align: center;
208
+ padding-top: 30px;
209
+ }
210
+
211
+
212
+ #atlt_strings_model .modal-footer {
213
+ padding: 2px 16px;
214
+ background-color: #5cb85c;
215
+ color: white;
216
+ position: absolute;
217
+ width: calc(100% - 32px);
218
+ bottom: 0;
219
+ height: 66px;
220
+ max-height: 66px;
221
+ }
222
+
223
+
224
+ .goog-te-banner-frame.skiptranslate {
225
+ display: none !important;
226
+ }
227
+ .goog-te-combo option:first-child {
228
+ display: none;
229
+ }
230
+
231
+ #yt-widget .yt-listbox__text {
232
+ line-height: 14px !important;
233
+ }
234
+ #yt-widget .yt-listbox__input:not(:checked) ~ .yt-listbox__text{
235
+ display: none !important;
236
+ }
assets/css/custom.min.css ADDED
@@ -0,0 +1 @@
 
1
+ #cool-auto-translate-btn:before{padding-right:5px!important}#cool-auto-translate-btn:after{content:"No API Required!";clear:both;display:block;font-size:10px;font-weight:700;font-family:monospace;position:absolute;bottom:-6px;left:-1px;background:#129412;width:calc(100% + 2px);height:12px;line-height:12px;color:#fff;text-align:center;border-radius:0 0 4px 4px}span.proonly-button{background:#555;color:#fff;font-size:12px;font-weight:700;font-family:monospace;padding:3px;border-radius:3px;display:inline-block;margin:2px 10px}span.proonly-button a{color:#fff;text-decoration:none}span.proonly-button.alsofree{background:green}#atlt_strings_model{display:none;position:fixed;z-index:99999;top:0;width:100%;height:100vh;overflow:hidden;background-color:rgba(0,0,0,.75)}#atlt_strings_model .modal-content{position:relative;background-color:#fefefe;width:80%;height:calc(100% - 40px);margin:32px auto 0;overflow:hidden;border-radius:5px;box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);-webkit-animation-name:animatetop;-webkit-animation-duration:.4s;animation-name:animatetop;animation-duration:.4s}@-webkit-keyframes animatetop{from{top:-300px;opacity:0}to{top:0;opacity:1}}@keyframes animatetop{from{top:-300px;opacity:0}to{top:0;opacity:1}}#atlt_strings_model .modal-header{padding:2px 16px;background-color:#5cb85c;color:#fff;height:86px;max-height:86px;overflow:hidden;position:relative}#atlt_strings_model .modal-header h2{display:inline-block;font-size:18px;color:#000;padding:0;margin:18px 159px 5px 0;width:calc(100% - 160px)}#atlt_strings_model .modal-header .close{color:#fff;font-size:28px;font-weight:700;position:absolute;right:10px;top:20px}#atlt_strings_model .modal-header .close:focus,#atlt_strings_model .modal-header .close:hover{color:#000;text-decoration:none;cursor:pointer}#atlt_strings_model .save_btn_cont{margin:8px;position:absolute;top:10px;right:40px}#atlt_strings_model .ytstats{padding:0;margin:5px 160px 5px 0;width:calc(100% - 160px)}#atlt_strings_model .ytstats a{color:#fff936}#atlt_strings_model .modal-body{padding:2px 16px;position:relative}#atlt_strings_model .notice-dismiss{padding:0}#atlt_strings_model h3{width:100%;display:inline-block;font-size:20px;padding:0;margin:20px 0 0}#translate_element{margin-bottom:25px}#atlt_strings_model .string_container{overflow-y:scroll;overflow-x:hidden;height:calc(100vh - 460px);width:100%;position:relative}#atlt_strings_model table{border-spacing:0;border-collapse:collapse;width:100%;max-width:100%;table-layout:fixed;padding:0;margin:0}#atlt_strings_model table td:first-child,#atlt_strings_model table th:first-child{width:60px;text-align:center}#atlt_strings_model table td,#atlt_strings_model table th{border:1px solid #ddd;padding:4px;height:26px;text-align:left;white-space:nowrap;font-size:12px;line-height:14px;overflow:hidden;vertical-align:middle}#atlt_strings_model .my_translate_progress{position:absolute;display:none;top:0;left:10px;color:#fff;background:rgba(0,0,0,.5);width:calc(100% - 22px);border-radius:3px;height:100%;z-index:9;box-sizing:border-box;font-size:16px;line-height:20px;font-weight:700;text-align:center;padding-top:30px}#atlt_strings_model .modal-footer{padding:2px 16px;background-color:#5cb85c;color:#fff;position:absolute;width:calc(100% - 32px);bottom:0;height:66px;max-height:66px}.goog-te-banner-frame.skiptranslate{display:none!important}.goog-te-combo option:first-child{display:none}#yt-widget .yt-listbox__text{line-height:14px!important}#yt-widget .yt-listbox__input:not(:checked)~.yt-listbox__text{display:none!important}
assets/images/powered-by-deepl.png ADDED
Binary file
assets/images/powered-by-google.png CHANGED
Binary file
assets/images/powered-by-yandex.png ADDED
Binary file
assets/js/api-testing.js DELETED
@@ -1,73 +0,0 @@
1
- jQuery(document).ready(function ($) {
2
- $('.atlt_test_api').on('click', function (event) {
3
- event.preventDefault();
4
- var $this = $(this);
5
- $this.parent().find(".atlt-preloader").show();
6
- var ajaxURL=$this.data('ajaxurl');
7
- var source=$this.data('source');
8
- var target=$this.data('target');
9
- var text=$this.data('text');
10
- var apikey=$this.data('apikey');
11
- var apiprovider=$this.data('api-provider');
12
- if(apiprovider=="google" || apiprovider=="microsoft"){
13
- var endpoint='pro_test_api_provider';
14
- }else{
15
- var endpoint='free_test_api_provider';
16
-
17
- }
18
- var nonce=$this.data('nonce');
19
- var defaultString='"Hello" Translation in French:-';
20
- var data = {
21
- 'action':endpoint,
22
- 'nonce':nonce,
23
- 'source':source,
24
- 'target':target,
25
- 'text':text,
26
- 'apikey':apikey,
27
- 'apiprovider':apiprovider,
28
- };
29
- var request = $.ajax({
30
- url:ajaxURL,
31
- method: "POST",
32
- data:data,
33
- });
34
- request.done(function (response, textStatus, jqXHR ){
35
- // console.log(response);
36
-
37
- $this.parent().find(".atlt-preloader").hide();
38
- let output='';
39
- if(response && jqXHR.status==200){
40
- let json_resp = JSON.parse(response);
41
- if(json_resp.translatedString!=null && json_resp.translatedString.length
42
- && json_resp['code']==200){
43
- traString=json_resp.translatedString;
44
- output=defaultString+'"'+traString+'"';
45
- swal({
46
- icon: "success",
47
- text:output
48
- });
49
- }else{
50
- let errorCode=json_resp['code'];
51
- let message=json_resp['error'];
52
- swal({
53
- icon: "error",
54
- text:errorCode+ " " +message
55
- });
56
- }
57
- }else{
58
- swal({
59
- icon: "error",
60
- text:response
61
- });
62
- }
63
-
64
- });
65
- request.fail(function( jqXHR, textStatus ) {
66
- swal({
67
- icon: "warning",
68
- text:"Request failed: " + textStatus
69
- });
70
- $this.parent().find(".atlt-preloader").hide();
71
- });
72
- });
73
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/atlt-admin-feedback-notice.js DELETED
@@ -1,13 +0,0 @@
1
- jQuery(document).ready(function ($) {
2
- $('.atlt_dismiss_notice').on('click', function (event) {
3
- var $this = $(this);
4
- var wrapper=$this.parents('.cool-feedback-notice-wrapper');
5
- var ajaxURL=wrapper.data('ajax-url');
6
- var ajaxCallback=wrapper.data('ajax-callback');
7
-
8
- $.post(ajaxURL, { 'action':ajaxCallback }, function( data ) {
9
- wrapper.slideUp('fast');
10
- }, "json");
11
-
12
- });
13
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/custom.js ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ It is master branch code
3
+ */
4
+
5
+ /*
6
+ it is testing branch
7
+ */
8
+ !function( window, $ ){
9
+ createSettingsPopup();
10
+ createStringsPopup();
11
+ //create_deepl_popup();
12
+ //createSettingsPopup();
13
+
14
+ /*
15
+ String Translate Model
16
+ */
17
+ // Get the modal
18
+ var gModal = document.getElementById("atlt_strings_model");
19
+
20
+ // When the user clicks anywhere outside of the modal, close it
21
+ window.onclick = function(event) {
22
+ if (event.target == gModal) {
23
+ gModal.style.display = "none";
24
+ }
25
+ }
26
+
27
+ // Get the <span> element that closes the modal
28
+ $("#atlt_strings_model").find(".close").on("click",function() {
29
+ $("#atlt_strings_model").fadeOut("slow");
30
+ });
31
+
32
+ // integrates auto traslator button in editor
33
+ function newaddAutoTranslationBtn(){
34
+ if($("#loco-toolbar").find("#cool-auto-translate-btn").length>0){
35
+ $("#loco-toolbar").find("#cool-auto-translate-btn").remove();
36
+ }
37
+ const locoActions= $("#loco-toolbar").find("#loco-actions");
38
+ const proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';
39
+
40
+ locoActions.append(proActiveBtn);
41
+
42
+ }
43
+
44
+ // create auto translate settings popup
45
+ function createSettingsPopup(){
46
+ let preloaderImg=extradata['preloader_path'];
47
+ let ytPreviewImg=extradata['yt_preview'];
48
+ let gtPreviewImg=extradata['gt_preview'];
49
+ let dplPreviewImg=extradata['dpl_preview'];
50
+ let modelHTML=`
51
+ <!-- The Modal -->
52
+ <div id="atlt-dialog" title="Auto Translate (No API Required)" style="display:none;">
53
+ <div class="atlt-settings">
54
+
55
+ <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Yandex Page Translate Widget</strong>
56
+ <div class="inputGroup">
57
+ <button id="atlt_yandex_transate_btn" class="notranslate button button-primary">Yandex Translate</button>
58
+ <span class="proonly-button alsofree">✔ Available</span>
59
+ <br/><a href="https://translate.yandex.com/" target="_blank"><img style="margin-top: 5px;" src="${ytPreviewImg}" alt="powered by Yandex Translate Widget"></a>
60
+ </div>
61
+ <hr/>
62
+
63
+ <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Google Page Translate Widget</strong>
64
+ <div class="inputGroup">
65
+ <button id="atlt_gtranslate_btn" disabled="disabled" class="notranslate button button-primary">Google Translate</button>
66
+ <span class="proonly-button"><a href="https://bit.ly/locoaddon" target="_blank" title="Buy Pro">PRO Only</a></span>
67
+ <br/><a href="https://translate.google.com/" target="_blank"><img style="margin-top: 5px;" src="${gtPreviewImg}" alt="powered by Google Translate Widget"></a>
68
+ </div>
69
+ <hr/>
70
+
71
+ <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Deepl Doc Translator</strong>
72
+ <div class="inputGroup">
73
+ <button disabled="disabled" id="atlt_deepl_btn" class="notranslate button button-primary">DeepL Translate</button>
74
+ <span class="proonly-button"><a href="https://bit.ly/locoaddon" target="_blank" title="Buy Pro">PRO Only</a></span>
75
+ <br/><a href="https://www.deepl.com/en/translator" target="_blank"><img style="margin-top: 5px;" src="${dplPreviewImg}" alt="powered by DeepL Translate"></a>
76
+ <br/>DeepL translation is beeter than Google, Microsoft & other auto-translation providers - <a href="https://techcrunch.com/2017/08/29/deepl-schools-other-online-translators-with-clever-machine-learning/" target="_blank">read review by techcruch</a>
77
+ </div>
78
+ <hr/>
79
+
80
+ <ul style="margin: 0;">
81
+ <li><span style="color:green">✔</span> Unlimited Translations</li>
82
+ <li><span style="color:green">✔</span> No API Key Required</li>
83
+ <li><span style="color:green">✔</span> Check Languages Support - <a href="https://yandex.com/support/translate/supported-langs.html" target="_blank">Yandex</a>, <a href="https://en.wikipedia.org/wiki/Google_Translate#Supported_languages" target="_blank">Google</a>, <a href="https://www.deepl.com/en/translator" target="_blank">DeepL</a></li>
84
+ </ul>
85
+
86
+ </div>
87
+ </div>
88
+ `;
89
+ $("body").append( modelHTML );
90
+ }
91
+
92
+ /**
93
+ * generate model popup HTML
94
+ */
95
+ function createStringsPopup(){
96
+ let modelHTML=`
97
+ <!-- The Modal -->
98
+ <div id="atlt_strings_model" class="modal atlt_custom_model">
99
+ <!-- Modal content -->
100
+ <div class="modal-content">
101
+ <div class="modal-header">
102
+ <span class="close ">&times;</span>
103
+ <h2 class="notranslate">Automatic Translations </h2>
104
+ <div class="save_btn_cont">
105
+ <button class="notranslate save_it button button-primary" disabled="true">Merge Translation</button>
106
+ </div>
107
+
108
+ <div style="display:none" class="ytstats">
109
+ Wahooo! You have saved your valauble time via auto translating
110
+ <strong class="totalChars"> </strong> characters using
111
+ <strong>
112
+ <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">
113
+ Loco Automatic Translate Addon</a>
114
+ </strong>
115
+ </div>
116
+
117
+ </div>
118
+ <div class="notice inline notice-info is-dismissible">Plugin will not translate any strings with HTML or special characters because Yandex Translator currently
119
+ does not support HTML and special characters translations.
120
+ You can edit translated strings inside Loco Translate Editor after merging the translations. Only special chracters (%s, %d) fixed at the time of merging of the translations.</div>
121
+ <div class="notice inline notice-info is-dismissible">Machine translations are not 100% correct.
122
+ Please verify strings before using on production website.</div>
123
+ <div class="modal-body">
124
+ <div class="my_translate_progress">Automatic translation is in progress....<br/>It will take few minutes, enjoy ☕ coffee in this time!</div>
125
+ <h3>Choose language</h3>
126
+ <div id="ytWidget">..Loading</div>
127
+ <br/>
128
+ <div class="string_container">
129
+ <table class="scrolldown" id="stringTemplate">
130
+ <thead>
131
+ <th class="notranslate">S.No</th>
132
+ <th class="notranslate">Source Text</th>
133
+ <th class="notranslate">Translation</th>
134
+ </thead>
135
+ <tbody id="yandex_string_tbl">
136
+ </tbody>
137
+ </table>
138
+ </div>
139
+ </div>
140
+ <div class="modal-footer">
141
+ <div class="save_btn_cont">
142
+ <button class="notranslate save_it button button-primary" disabled="true">Merge Translation</button>
143
+ </div>
144
+ <div style="display:none" class="ytstats">
145
+ Wahooo! You have saved your valauble time via auto translating
146
+ <strong class="totalChars"></strong> characters using
147
+ <strong>
148
+ <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">
149
+ Loco Automatic Translate Addon</a>
150
+ </strong>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ </div>`;
155
+
156
+ $("body").append( modelHTML );
157
+ }
158
+
159
+
160
+
161
+
162
+
163
+ }( window, jQuery );
assets/js/custom.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(window,$){createSettingsPopup(),createStringsPopup();var gModal=document.getElementById("atlt_strings_model");function newaddAutoTranslationBtn(){$("#loco-toolbar").find("#cool-auto-translate-btn").length>0&&$("#loco-toolbar").find("#cool-auto-translate-btn").remove();const locoActions=$("#loco-toolbar").find("#loco-actions"),proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';locoActions.append(proActiveBtn)}function createSettingsPopup(){let preloaderImg=extradata.preloader_path,ytPreviewImg,gtPreviewImg,dplPreviewImg,modelHTML=` \n \x3c!-- The Modal --\x3e\n <div id="atlt-dialog" title="Auto Translate (No API Required)" style="display:none;">\n <div class="atlt-settings">\n \n <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Yandex Page Translate Widget</strong>\n <div class="inputGroup">\n <button id="atlt_yandex_transate_btn" class="notranslate button button-primary">Yandex Translate</button>\n <span class="proonly-button alsofree">✔ Available</span>\n <br/><a href="https://translate.yandex.com/" target="_blank"><img style="margin-top: 5px;" src="${extradata.yt_preview}" alt="powered by Yandex Translate Widget"></a>\n </div>\n <hr/>\n\n <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Google Page Translate Widget</strong>\n <div class="inputGroup">\n <button id="atlt_gtranslate_btn" disabled="disabled" class="notranslate button button-primary">Google Translate</button>\n <span class="proonly-button"><a href="https://bit.ly/locoaddon" target="_blank" title="Buy Pro">PRO Only</a></span>\n <br/><a href="https://translate.google.com/" target="_blank"><img style="margin-top: 5px;" src="${extradata.gt_preview}" alt="powered by Google Translate Widget"></a>\n </div>\n <hr/>\n \n <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Deepl Doc Translator</strong>\n <div class="inputGroup">\n <button disabled="disabled" id="atlt_deepl_btn" class="notranslate button button-primary">DeepL Translate</button>\n <span class="proonly-button"><a href="https://bit.ly/locoaddon" target="_blank" title="Buy Pro">PRO Only</a></span>\n <br/><a href="https://www.deepl.com/en/translator" target="_blank"><img style="margin-top: 5px;" src="${extradata.dpl_preview}" alt="powered by DeepL Translate"></a>\n <br/>DeepL translation is beeter than Google, Microsoft & other auto-translation providers - <a href="https://techcrunch.com/2017/08/29/deepl-schools-other-online-translators-with-clever-machine-learning/" target="_blank">read review by techcruch</a>\n </div>\n <hr/>\n\n <ul style="margin: 0;">\n <li><span style="color:green">✔</span> Unlimited Translations</li>\n <li><span style="color:green">✔</span> No API Key Required</li>\n <li><span style="color:green">✔</span> Check Languages Support - <a href="https://yandex.com/support/translate/supported-langs.html" target="_blank">Yandex</a>, <a href="https://en.wikipedia.org/wiki/Google_Translate#Supported_languages" target="_blank">Google</a>, <a href="https://www.deepl.com/en/translator" target="_blank">DeepL</a></li>\n </ul>\n\n </div>\n </div>\n `;$("body").append(modelHTML)}function createStringsPopup(){let modelHTML=' \n \x3c!-- The Modal --\x3e\n <div id="atlt_strings_model" class="modal atlt_custom_model">\n \x3c!-- Modal content --\x3e\n <div class="modal-content">\n <div class="modal-header">\n <span class="close ">&times;</span>\n <h2 class="notranslate">Automatic Translations </h2>\n <div class="save_btn_cont">\n <button class="notranslate save_it button button-primary" disabled="true">Merge Translation</button>\n </div>\n\n <div style="display:none" class="ytstats">\n Wahooo! You have saved your valauble time via auto translating \n <strong class="totalChars"> </strong> characters using \n <strong> \n <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">\n Loco Automatic Translate Addon</a>\n </strong> \n </div>\n\n </div>\n <div class="notice inline notice-info is-dismissible">Plugin will not translate any strings with HTML or special characters because Yandex Translator currently\n does not support HTML and special characters translations. \n You can edit translated strings inside Loco Translate Editor after merging the translations. Only special chracters (%s, %d) fixed at the time of merging of the translations.</div>\n <div class="notice inline notice-info is-dismissible">Machine translations are not 100% correct.\n Please verify strings before using on production website.</div>\n <div class="modal-body">\n <div class="my_translate_progress">Automatic translation is in progress....<br/>It will take few minutes, enjoy ☕ coffee in this time!</div>\n <h3>Choose language</h3>\n <div id="ytWidget">..Loading</div>\n <br/>\n <div class="string_container"> \n <table class="scrolldown" id="stringTemplate">\n <thead>\n <th class="notranslate">S.No</th>\n <th class="notranslate">Source Text</th>\n <th class="notranslate">Translation</th>\n </thead>\n <tbody id="yandex_string_tbl">\n </tbody>\n </table>\n </div>\n </div>\n <div class="modal-footer">\n <div class="save_btn_cont">\n <button class="notranslate save_it button button-primary" disabled="true">Merge Translation</button>\n </div>\n <div style="display:none" class="ytstats">\n Wahooo! You have saved your valauble time via auto translating \n <strong class="totalChars"></strong> characters using \n <strong> \n <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">\n Loco Automatic Translate Addon</a>\n </strong> \n </div>\n </div>\n </div>\n </div>';$("body").append(modelHTML)}window.onclick=function(event){event.target==gModal&&(gModal.style.display="none")},$("#atlt_strings_model").find(".close").on("click",(function(){$("#atlt_strings_model").fadeOut("slow")}))}(window,jQuery);
assets/js/loco-js-editor.js CHANGED
@@ -1,32 +1,25 @@
1
-
2
  /**
3
  * Script for PO file editor pages
4
  */
5
  !function( window, $ ){
6
- var TotalCharacters=0;
7
- var HtmlStrings = 0;
8
- var requestChars=0;
9
-
10
- // ES6 Modules or TypeScript
11
- let event = document.createEvent('event');
12
- event.initEvent('atlt_run_translation');
13
- createSettingsPopup();
14
- $('#atlt-dialog .atlt-ok.button').on('click',function(){
15
- // hide dialog container by finding main parent DOM
16
- localStorage.removeItem('unSavedString');
17
- $("#atlt-dialog").parent('.ui-dialog').hide();
18
- });
19
  var loco = window.locoScope,
20
- conf = window.locoConf,
 
 
21
  syncParams = null,
22
  saveParams = null,
 
 
23
  // UI translation
24
  translator = loco.l10n,
25
  sprintf = loco.string.sprintf,
 
26
  // PO file data
27
  locale = conf.locale,
28
  messages = loco.po.init( locale ).wrap( conf.powrap ),
29
  template = ! locale,
 
30
  // form containing action buttons
31
  elForm = document.getElementById('loco-actions'),
32
  filePath = conf.popath,
@@ -39,13 +32,29 @@
39
  // prevent all write operations if readonly mode
40
  readonly = conf.readonly,
41
  editable = ! readonly,
 
42
  // Editor components
43
  editor,
44
  saveButton,
45
- innerDiv = document.getElementById('loco-editor-inner');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
-
48
- /**
49
  *
50
  */
51
  function doSyncAction( callback ){
@@ -97,6 +106,8 @@
97
  loco.ajax.post( 'sync', syncParams, onSuccess, callback );
98
  }
99
 
 
 
100
  function debugMerge( console, result ){
101
  var i = -1, t = result.add.length;
102
  while( ++i < t ){
@@ -108,32 +119,372 @@
108
  }
109
  }
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  /**
112
  * Post full editor contents to "posave" endpoint
113
  */
114
  function doSaveAction( callback ){
 
115
  function onSuccess( result ){
116
  callback && callback();
117
  editor.save( true );
118
  // Update saved time update
119
  $('#loco-po-modified').text( result.datetime||'[datetime error]' );
120
  }
121
- saveParams.locale = String( messages.locale() || '' );
122
  if( fsConnect ){
123
- fsConnect.applyCreds( saveParams );
124
  }
125
- // adding PO source last for easier debugging in network inspector
126
- saveParams.data = String( messages );
127
- loco.ajax.post( 'save', saveParams, onSuccess, callback );
 
 
 
 
 
 
128
  }
 
 
129
  function saveIfDirty(){
130
  editor.dirty && doSaveAction();
131
  }
 
 
 
132
  function onUnloadWarning(){
133
  // Translators: Warning appears when user tries to refresh or navigate away when editor work is unsaved
134
  return translator._("Your changes will be lost if you continue without saving");
135
  }
136
 
 
 
137
  function registerSaveButton( button ){
138
  saveButton = button;
139
  // enables and disable according to save/unsave events
@@ -147,7 +498,7 @@
147
  $(button).removeClass( 'button-primary loco-flagged' );
148
  } )
149
  ;
150
- function disable(){
151
  button.disabled = true;
152
  }
153
  function enable(){
@@ -167,15 +518,14 @@
167
  event.preventDefault();
168
  think();
169
  doSaveAction( unthink );
170
- setTimeout(function() {
171
- location.reload();
172
- },3500);
173
  return false;
174
  } );
175
  return true;
176
  };
177
 
178
- function registerSyncButton( button ){
 
 
179
  var project = conf.project;
180
  if( project ){
181
  function disable(){
@@ -223,7 +573,36 @@
223
  return true;
224
  }
225
 
226
- function registerFuzzyButton( button ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  var toggled = false,
228
  enabled = false
229
  ;
@@ -261,9 +640,11 @@ function registerFuzzyButton( button ){
261
  return false;
262
  } );
263
  return true;
264
- };
 
265
 
266
- function registerRevertButton( button ){
 
267
  // No need for revert when document is saved
268
  editor
269
  .on('poUnsaved', function(){
@@ -282,6 +663,8 @@ function registerFuzzyButton( button ){
282
  return true;
283
  };
284
 
 
 
285
  function registerInvisiblesButton( button ){
286
  var $button = $(button);
287
  button.disabled = false;
@@ -297,20 +680,24 @@ function registerFuzzyButton( button ){
297
  return true;
298
  }
299
 
 
 
300
  function registerCodeviewButton( button ){
301
  var $button = $(button);
302
  button.disabled = false;
303
  $button.click( function(event){
304
  event.preventDefault();
305
  var state = ! editor.getMono();
306
- editor.setMono( state );
307
  $button[ state ? 'addClass' : 'removeClass' ]('inverted');
 
308
  return false;
309
  } );
310
  locoScope.tooltip.init($button);
311
  return true;
312
  };
313
 
 
 
314
  function registerAddButton( button ){
315
  button.disabled = false;
316
  $(button).click( function( event ){
@@ -328,6 +715,8 @@ function registerFuzzyButton( button ){
328
  return true;
329
  };
330
 
 
 
331
  function registerDelButton( button ){
332
  button.disabled = false;
333
  $(button).click( function(event){
@@ -338,6 +727,8 @@ function registerFuzzyButton( button ){
338
  return true;
339
  };
340
 
 
 
341
  function registerDownloadButton( button, id ){
342
  button.disabled = false;
343
  $(button).click( function( event ){
@@ -362,11 +753,14 @@ function registerFuzzyButton( button ){
362
  return false;
363
  }
364
 
 
365
  /*/ dummy function for enabling buttons that do nothing (or do something inherently)
366
  function registerNoopButton( button ){
367
  return true;
368
  }*/
369
 
 
 
370
  /**
371
  * Update status message above editor.
372
  * This is dynamic version of PHP Loco_gettext_Metadata::getProgressSummary
@@ -393,15 +787,10 @@ function registerFuzzyButton( button ){
393
  }
394
  }
395
  $('#loco-po-status').text( stext );
396
- if( typeof window.locoEditorStats == 'undefined'){
397
- window.locoEditorStats = {totalWords:stats.t, totalTranslated:stats.p} ;
398
- }else{
399
- window.locoEditorStats.totalWords = stats.t;
400
- window.locoEditorStats.totalTranslated = stats.p;
401
- }
402
-
403
  }
404
 
 
 
405
  /**
406
  * Enable text filtering
407
  */
@@ -428,7 +817,9 @@ function registerFuzzyButton( button ){
428
  } )
429
  ;
430
  }
431
-
 
 
432
  // resize function fits editor to screen, accounting for headroom and touching bottom of screen.
433
  var resize = function(){
434
  function top( el, ancestor ){
@@ -464,10 +855,12 @@ function registerFuzzyButton( button ){
464
  .init( innerDiv )
465
  .localise( translator )
466
  ;
 
467
  loco.po.kbd
468
  .init( editor )
469
- .add( 'save', saveIfDirty )
470
- .enable('copy','clear','enter','next','prev','fuzzy','save','invis')
 
471
  ;
472
 
473
  // initialize toolbar button actions
@@ -479,7 +872,7 @@ function registerFuzzyButton( button ){
479
  // editor mode togglers
480
  invs: registerInvisiblesButton,
481
  code: registerCodeviewButton,
482
- // downloads / post-throughs
483
  source: registerDownloadButton,
484
  binary: template ? null : registerDownloadButton
485
  };
@@ -490,8 +883,8 @@ function registerFuzzyButton( button ){
490
  }
491
  // PO only
492
  else {
493
- buttons.fuzzy = registerFuzzyButton;
494
- };
495
  $('#loco-toolbar').find('button').each( function(i,el){
496
  var id = el.getAttribute('data-loco'), register = buttons[id];
497
  register && register(el,id) || $(el).hide();
@@ -512,8 +905,10 @@ function registerFuzzyButton( button ){
512
  updateStatus();
513
  window.onbeforeunload = null;
514
  } )
515
- .on( 'poUpdate', updateStatus );
516
-
 
 
517
 
518
  // load raw message data
519
  messages.load( conf.podata );
@@ -522,7 +917,8 @@ function registerFuzzyButton( button ){
522
  editor.load( messages );
523
 
524
  // locale should be cast to full object once set in editor
525
- if( locale = editor.targetLocale ){
 
526
  locale.isRTL() && $(innerDiv).addClass('trg-rtl');
527
  }
528
  // enable template mode when no target locale
@@ -530,549 +926,237 @@ function registerFuzzyButton( button ){
530
  editor.unlock();
531
  }
532
 
 
 
 
 
533
 
534
  /*
535
- |--------------------------------------------------------------------------
536
- | Auto Translator Custom Code
537
- |--------------------------------------------------------------------------
538
  */
539
- //encode URL query string
540
- function createEncodedString(allStringText){
541
- const queryString=allStringText.map((item)=>{
542
- return "&text="+ encodeURIComponent(item.source);
543
- }).join(",");
544
-
545
- return queryString;
546
- }
547
- // validate key
548
- function validLicenseKey(licenseKey){
549
- if(licenseKey!=undefined && licenseKey.length>1){
550
- let validKey= validate_pattern(licenseKey);
551
- if(validKey.length>1){
552
- return licenseKey;
553
- }
554
- }else{
555
- return false;
556
- }
557
-
558
- }
559
 
560
- // create Saved Time Message HTML
561
- function savedTimeInfo(statsObj){
562
- var info='';
563
- if(statsObj!=undefined && statsObj['time_saved']!==undefined){
564
- let timeSaved=statsObj['time_saved'];
565
- let totalChars=statsObj['totalChars'];
566
- var info =`<div class="saved_time_wrapper" style="margin:10px 0px">
567
- <span style="border: 3px solid #14b75d;display: inline-block;padding: 3px;">
568
- Wahooo! You have saved your
569
- <strong>${timeSaved}</strong>
570
- via auto translating <strong>${totalChars}</strong>
571
- characters using <strong> <br />
572
- <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">
573
- Loco Automatic Translate Addon</a></strong>
574
- </span></div>`;
575
- }
576
- return info;
577
  }
578
- // validate pattern
579
- function validate_pattern(str){
580
- let m;
581
- const regex = /^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/gm;
582
- let saveMatch=[];
583
- while ((m = regex.exec(str)) !== null) {
584
- // This is necessary to avoid infinite loops with zero-width matches
585
- if (m.index === regex.lastIndex) {
586
- regex.lastIndex++;
 
 
 
 
 
 
 
 
 
 
 
 
587
  }
588
- // The result can be accessed through the `m`-variable.
589
- m.forEach((match, groupIndex) => {
590
- saveMatch.push(match);
591
- // console.log(`Found match, group ${groupIndex}: ${match}`);
592
- });
593
  }
594
- return saveMatch;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595
  }
596
- function getTargetLang(){
597
- return window.locoConf.locale.lang?window.locoConf.locale.lang:null;
 
 
 
 
598
  }
599
- $(document).ready(function(){
600
- if( template ){
601
- return ;
 
 
 
 
 
 
 
 
 
 
 
 
602
  }
603
- const locoRawData=conf.podata;
604
- if(locoRawData!=undefined && locoRawData.length>0 ){
605
- // called auto traslate button
606
- addAutoTranslationBtn();
607
- }
608
 
609
- $(document).on("click", "#cool-auto-translate-btn", function() {
610
- $('#atlt-dialog').dialog({width:440,height:500});
611
- });
612
- // main translate handler
613
- $("#typehtmlWrapper").hide();
614
- $("input[name=api_type]").on( "click",function(){
615
- if($(this).val()=="google" || $(this).val()=="microsoft" || $(this).val()=="ibm"){
616
- $("#typehtmlWrapper").hide();
617
- $("#typeplain").attr("checked","checked");
618
- }else{
619
- $("#typehtmlWrapper").show();
620
- }
621
- });
622
-
623
- // integrate reset string traslation button
624
- $("#atlt_reset_all").on("click",function(){
625
- swal("What type of strings do you want to reset?",
626
- {
627
- dangerMode: true,
628
- icon: "warning",
629
- confirmButtonColor: '#8CD4F5',
630
-
631
- buttons: {
632
- plain: {
633
- text: "Plain Text Strings",
634
- value: "plain",
635
- class:"danger"
636
- },
637
- html: {
638
- text: "HTML Strings",
639
- value: "html",
640
- },
641
- all: {
642
- text: "All Strings",
643
- value: "all",
644
- },
645
- cancel: {
646
- text: "Cancel",
647
- value: null,
648
- visible: true,
649
- className: "",
650
- closeModal: false,
651
- },
652
- },
653
- })
654
- .then((value) => {
655
- switch (value) {
656
- case "all":
657
- resetTranslations(value);
658
- swal("Done!", "You have successfully reset all strings translations. Just close this popup & SAVE!","success");;
659
- break;
660
- case "plain":
661
- resetTranslations(value);
662
- swal("Done!", "You have successfully reset all plain text strings translations. Just close this popup & SAVE!", "success");
663
- break;
664
- case "html":
665
- resetTranslations(value);
666
- swal("Done!", "You have successfully reset all strings with HTML translations. Just close this popup & SAVE!", "success");
667
- break;
668
- default:
669
- swal("Cancelled, Just close this popup!");
670
- }
671
- });
672
-
673
  });
674
 
675
- // reset string array
676
- function resetTransArr(tranArr,type){
677
- var resetStrs=[];
678
- return resetStrs=tranArr.map(function(item){
679
- if(item.source!==undefined && item.target!==undefined ){
680
- if(type=="html"){
681
- if((isHTML(item.source))){
682
- item.target="";
683
- }else if(isAllowedChars(item.source) && isPlacehodersChars(item.source)===false){
684
- item.target="";
685
- }
686
- }
687
- if(type=="plain"){
688
- if( isPlacehodersChars(item.source)===true){
689
- item.target="";
690
  }
691
- else if(isHTML(item.source) || isAllowedChars(item.source)){
692
- }else{
693
- item.target="";
694
- }
 
695
  }
696
- if(type=="all"){
697
- item.target="";
698
- }
699
- return item;
700
- }
701
- });
702
- }
703
-
704
- // integrate reset translation button
705
- function resetTranslations(type){
706
- var resetArr=[];
707
- const saveBtn=$('[data-loco="save"]');
708
- if(conf.podata!==undefined){
709
- if(type=="plain"){
710
- resetArr=resetTransArr(conf.podata,"plain");
711
- }else if(type=="html"){
712
- resetArr=resetTransArr(conf.podata,"html");
713
- }else{
714
- resetArr=resetTransArr(conf.podata,"all");
715
- }
716
- messages = loco.po.init( locale ).wrap( conf.powrap );
717
- messages.load(resetArr);
718
- // editor event behaviours
719
- editor
720
- .on('poUnsaved', function(){
721
- window.onbeforeunload = onUnloadWarning;
722
- } )
723
- .on('poSave', function(){
724
- updateStatus();
725
- window.onbeforeunload = null;
726
- } )
727
- .on( 'poUpdate', updateStatus );
728
-
729
- // ready to render editor
730
- editor.load(messages);
731
- saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
732
- updateStatus();
733
  }
734
  }
735
- // handle form settings
736
- $("#atlt-settings-form").submit(function( event ) {
737
- event.preventDefault();
738
- const user_type=ATLT["info"].type;
739
- let strType ="plain";
740
- let apiType = $("input[name='api_type']:checked").val();
741
- let mainBtn=$("#cool-auto-translate-btn");
742
- var thisBtn=$("#cool-auto-translate-start");
743
- let sourceApiKey ='';
744
- var todayLimit= mainBtn.data('today-limit');
745
- var totalLimit= mainBtn.data('total-limit');
746
- let targetLang='';
747
-
748
- if(user_type=="free" && apiType=="google"){
749
- alert("Google Translation Only Available in the PRO version");
750
- return false;
751
- }
752
- if(user_type=="free" && apiType=="microsoft"){
753
- alert("Microsoft Translator Only Available in the PRO version");
754
- return false;
755
- }
756
- if((user_type==undefined || user_type=="pro") && ATLT["info"]["licenseKey"]==undefined){
757
- alert("Please enter Your License Key");
758
- return false;
759
- }
760
 
761
- if(conf['locale']["lang"]==!undefined){
762
- targetLang=conf['locale']["lang"];
763
- }else{
764
- targetLang=getTargetLang();
765
- }
766
- if(apiType=="google"){
767
- if(targetLang=="zh"){
768
- targetLang= targetLang+"-"+conf['locale']["region"];
769
- }
770
- sourceApiKey = ATLT["api_key"]["gApiKey"];
771
- }else if(apiType=="microsoft"){
772
- if(targetLang=="zh"){
773
- if(conf['locale']["region"]=="CN"){
774
- targetLang= targetLang+"-Hans";
775
- }else if(conf['locale']["region"]=="TW"){
776
- targetLang= targetLang+"-Hant";
777
- }else{
778
- targetLang= targetLang+"-"+conf['locale']["region"];
779
- }
780
- }
781
- sourceApiKey = ATLT["api_key"]["mApiKey"];
782
- }else if(apiType=="ibm"){
783
- sourceApiKey = ATLT["api_key"]["ibmApiKey"];
784
- }else{
785
- sourceApiKey = ATLT["api_key"]["yApiKey"];
786
- }
787
- // filter transable strings
788
- if(locoRawData!=undefined && locoRawData.length>0 && sourceApiKey!='' ){
789
- let plainStrArr=[];
790
- let htmlStrArr=[];
791
- let orgStrArr=[];
792
- orgStrArr=locoRawData;
793
- var countChars=0;
794
- if(strType=="plain"){
795
- plainStrArr= filterRawObject(locoRawData,"plain");
796
- if (plainStrArr !== null) {
797
- plainStrArr.map(function(index){
798
- countChars +=index.source.length;
799
- });
800
- }
801
- }else{
802
- htmlStrArr= filterRawObject(locoRawData,"html");
803
- if (htmlStrArr !== null) {
804
- plainStrArr.map(function(index){
805
- countChars +=index.length;
806
- });
807
- }
808
- }
809
-
810
- if (htmlStrArr !== null || plainStrArr !== null ) {
811
- if(countChars>parseInt(todayLimit)){
812
- alert('Your translation string are larger then available free limit.In order to extend limit Buy Pro license key');
813
- }else{
814
-
815
- if(strType=="plain"){
816
- if(plainStrArr.length==0){
817
- $("#atlt-dialog").parent('.ui-dialog').hide();
818
- mainBtn.attr('disabled','disabled');
819
- alert("You have no untranslated plain strings");
820
- window.location.reload();
821
- return;
822
- }
823
- dataObj = {
824
- textToTranslateArr:plainStrArr,
825
- strType:"plain",
826
- };
827
- }
828
- // create data object for later use
829
- dataObj.orgStrArr=orgStrArr;
830
- dataObj.thisBtn=thisBtn;
831
- dataObj.apiType=apiType;
832
- dataObj.targetLang=targetLang;
833
- if(apiType=="google" || apiType=="microsoft"){
834
- dataObj.endpoint='pro_autotranslate_handler';
835
- }else{
836
- dataObj.endpoint='free_autotranslate_handler';
837
- }
838
-
839
-
840
- // save data object globaly for later use
841
- window.locoEditorStats.dataObj = dataObj;
842
- jQuery(document).trigger('atlt_run_translation');
843
- thisBtn.val('Translating...');
844
- mainBtn.text("Translating..");
845
- $("#atlt_preloader").show();
846
- // load raw message data
847
-
848
- } //
849
-
850
- } // else close
851
- }
852
-
853
- });
854
-
855
- });
856
- // create translation events
857
- jQuery(document).on('atlt_run_translation',function(){
858
- let textToTranslate = window.locoEditorStats.dataObj.textToTranslateArr
859
- let totalTranslated = window.locoEditorStats.totalTranslated
860
-
861
- const nonce=ATLT["nonce"];
862
- const saveBtn=$('[data-loco="save"]');
863
- const orignalstringArr=window.locoEditorStats.dataObj.orgStrArr;
864
- const targetLang= window.locoEditorStats.dataObj.targetLang;
865
- let indexRequest = 50;
866
- if( ATLT.api_key['atlt_index-per-request'] != "" && typeof ATLT.api_key['atlt_index-per-request'] != "undefined" ){
867
- indexRequest = ATLT.api_key['atlt_index-per-request'];
868
- }
869
-
870
- //save pending array in window object for later use
871
- if( typeof textToTranslate == "object" && textToTranslate.length >= 1 ){
872
- // update object for later us
873
- let translationO = {
874
- textToTranslateArr:textToTranslate.slice(indexRequest), //save pending index for later us
875
- thisBtn:window.locoEditorStats.dataObj.thisBtn,
876
- strType:window.locoEditorStats.dataObj.strType,
877
- orgStrArr:window.locoEditorStats.dataObj.orgStrArr,
878
- apiType:window.locoEditorStats.dataObj.apiType,
879
- targetLang:targetLang,
880
- endpoint:window.locoEditorStats.dataObj.endpoint
881
- };
882
- window.locoEditorStats.dataObj = translationO;
883
-
884
- // send partial data request
885
- let data = {
886
- sourceLang:'en',
887
- targetLang:targetLang,
888
- textToTranslateArr:textToTranslate.slice(0,indexRequest),
889
- orginalArr:orignalstringArr,
890
- thisBtn:window.locoEditorStats.dataObj.thisBtn,
891
- strType:window.locoEditorStats.dataObj.strType,
892
- apiType:window.locoEditorStats.dataObj.apiType,
893
- saveBtn:saveBtn,
894
- endpoint:window.locoEditorStats.dataObj.endpoint,
895
- nonce:nonce
896
- };
897
- // slice data
898
- textToTranslate.slice(0,indexRequest).map(function(value,index){
899
- TotalCharacters += (value.source).length;
900
- requestChars+=(value.source).length;
901
- })
902
- atlt_translate(data);
903
- }
904
- })
905
-
906
- // Translate
907
- function atlt_translate(data) {
908
-
909
- atlt_ajax_translation_request(data, "POST").success(function(
910
- resp,status,xhr) {
911
- if(xhr.status==200 && resp!=null){
912
 
913
- const json_resp = JSON.parse(resp);
914
- let responseObj;
915
- let apiProvider=window.locoEditorStats.dataObj.apiType;
916
-
917
- if(json_resp['error'] && json_resp['error']['code']==800)
918
- {
919
- let errorMsz= json_resp['error']['message'];
920
- $('#atlt-dialog .atlt-final-message').html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>");
921
- $('#atlt-dialog .atlt-ok.button').show();
922
- $("#atlt_preloader").hide();
923
- $("#cool-auto-translate-btn").text('Error').attr('disabled','disabled');
924
- setTimeout(function() {
925
- location.reload();
926
- },4000);
927
- return false;
928
- }
929
 
930
- if(json_resp.translatedString!=null && json_resp.translatedString.length
931
- && json_resp['code']==200){
932
- responseObj=json_resp.translatedString;
933
- }else{
934
- let errorCode=json_resp['code'];
935
- let errorMsz=json_resp['error'];
936
- $('#atlt-dialog .atlt-final-message').html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>");
937
- $('#atlt-dialog .atlt-ok.button').show();
938
- $("#atlt_preloader").hide();
939
- $("#cool-auto-translate-btn").text('Error').attr('disabled','disabled');
940
- setTimeout(function() {
941
- location.reload();
942
- },4000);
943
- return false;
944
-
945
- }
946
-
947
- let totalTranslated = window.locoEditorStats.totalTranslated;
948
-
949
- let unSavedStr=[];
950
- if(responseObj!==undefined && responseObj.length){
951
- for(i=0;i< responseObj.length;i++){
952
- var text = responseObj[i];
953
- if( data.textToTranslateArr[i] === undefined ){
954
- break;
955
- }
956
- data.textToTranslateArr[i].target = text ;
957
- }
958
- }
959
 
960
- let translatedStrArr=data.textToTranslateArr;
 
 
 
 
 
 
 
 
 
 
 
 
961
 
962
- let Emptytargets = [];
963
- for(var x=0; x<translatedStrArr.length;++x){
964
- if(translatedStrArr[x].target !='' ){
965
- Emptytargets[x]=translatedStrArr[x].source;
966
- }
967
- }
968
- let items;
969
- if (localStorage.getItem('unSavedString')) {
970
- items = JSON.parse(localStorage.getItem('unSavedString'))
971
- } else {
972
- items = []
973
- }
974
 
975
- var unSavedStrArr = items.concat(Emptytargets);
976
- localStorage.setItem('unSavedString', JSON.stringify(unSavedStrArr));
977
- messages = loco.po.init( locale ).wrap( conf.powrap );
978
- // ready to render editor
979
- messages.load(conf.podata);
980
- // editor event behaviours
981
- editor
982
- .on('poUnsaved', function(){
983
- window.onbeforeunload = onUnloadWarning;
984
- } )
985
- .on('poSave', function(){
986
- updateStatus();
987
- window.onbeforeunload = null;
988
- } )
989
- .on( 'poUpdate', updateStatus );
990
-
991
- // ready to render editor
992
- editor.load(messages);
993
- data.saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
994
- updateStatus();
995
- // run through DOM and mark *(STAR) for newly translated
996
- markUnsavedString();
997
-
998
- requestChars=0;
999
- // update progress bar
1000
- $('#atlt-dialog .translated-label').text('Translated');
1001
- $('#atlt-dialog .translated-text').text(window.locoEditorStats.totalTranslated);
1002
-
1003
- $('#atlt-dialog .atlt-progress-bar-value').width(window.locoEditorStats.totalTranslated);
1004
-
1005
- let saved_time_html= savedTimeInfo(json_resp['stats']);
1006
- let finalHTML="<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>).";
1007
-
1008
- switch( window.locoEditorStats.totalTranslated ){
1009
- case "0%":
1010
- $('#atlt-dialog .translated-label').text('Translating...');
1011
- $('#atlt-dialog .translated-text').text('');
1012
- break;
1013
- case "100%":
1014
- data.thisBtn.hide();
1015
- $("#atlt_preloader").hide();
1016
- data.thisBtn.attr('disabled','disabled');
1017
- $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1018
- // change cursor to 'default' state
1019
- $('#atlt-dialog .atlt-final-message').html(finalHTML+saved_time_html);
1020
- $('#atlt-dialog .atlt-ok.button').show();
1021
- return;
1022
- break;
1023
- }
1024
-
1025
- // run through DOM and mark *(STAR) for newly translated
1026
- for(var x=0;x<=Emptytargets.length;x++){
1027
- var source = Emptytargets[x];
1028
- jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter(function(index){
1029
- return jQuery(this).text() == source
1030
- }).addClass('po-unsaved');
1031
- }
1032
 
1033
-
 
 
 
 
1034
 
1035
- if( (window.locoEditorStats.dataObj.textToTranslateArr).length == 0){
1036
- data.thisBtn.val('Translated').attr("disabled","true");
1037
- $("#atlt_preloader").hide();
1038
- // data.thisBtn.attr('disabled','disabled').hide('slow');
1039
- $("#cool-auto-translate-btn").text('Translated - SAVE NOW').attr('disabled','disabled');
1040
- // change cursor to 'default' state
1041
- $('#atlt-dialog .atlt-final-message').html(finalHTML+saved_time_html);
1042
- $('#atlt-dialog .atlt-ok.button').show();
1043
- return;
1044
  }
1045
-
1046
- jQuery(document).trigger('atlt_run_translation');
1047
-
1048
- } else{
1049
- data.thisBtn.hide('slow');
1050
- $("#atlt_preloader").hide();
1051
- $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
1052
- $('#atlt-dialog .atlt-ok.button').show();
1053
- alert('Unable to make request to the server at the moment. Try again later.');
1054
  }
1055
- }).fail(function(jqXHR){
1056
- console.log(jqXHR);
1057
- if(jqXHR.status==500 || jqXHR.status==0){
1058
- // internal server error or internet connection broke
1059
- data.thisBtn.hide('slow');
1060
- $("#atlt_preloader").hide();
1061
- $("#cool-auto-translate-btn").text('Translation').attr('disabled','disabled');
1062
- $('#atlt-dialog .atlt-ok.button').show();
1063
- alert('Unable to make request to the server at the moment. Try again later.');
1064
- }
1065
- });
1066
  }
1067
- // filter all saved strings
1068
- function filterSavedStrings(rawArray){
1069
- return filterdArr=rawArray.filter((item,index)=>{
1070
- if(item.target!="" &&(item.source!==undefined && item.source!="")){
1071
- return true;
1072
- }
1073
- });
1074
- }
1075
-
1076
  // filter string based upon type
1077
  function filterRawObject(rawArray,filterType){
1078
  filterdArr=[];
@@ -1081,15 +1165,6 @@ function filterRawObject(rawArray,filterType){
1081
  if( ValidURL(item.source)){
1082
  return false;
1083
  }
1084
- if(filterType=="html"){
1085
- if(isHTML(item.source)){
1086
- return true;
1087
- }else if(isAllowedChars(item.source) && isPlacehodersChars(item.source)==false){
1088
- return true;
1089
- }else{
1090
- return false;
1091
- }
1092
- }else{
1093
  if(isHTML(item.source)){
1094
  return false;
1095
  }
@@ -1103,115 +1178,11 @@ function filterRawObject(rawArray,filterType){
1103
  }else{
1104
  return true;
1105
  }
1106
- }
1107
  }
1108
  });
1109
  }
1110
 
1111
 
1112
- // auto traslator button in editor
1113
- function addAutoTranslationBtn(){
1114
- if($("#loco-toolbar").find("#cool-auto-translate-btn").length>0){
1115
- $("#loco-toolbar").find("#cool-auto-translate-btn").remove();
1116
- }
1117
- const locoActions= $("#loco-toolbar").find("#loco-actions");
1118
- const otherBtn='<button class="button has-icon icon-warn" id="atlt_reset_all">Reset Translations</button></fieldset>';
1119
- const allTranslated='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate" disabled>Translated</button></fieldset>';
1120
- let savedStrings=filterSavedStrings(conf.podata);
1121
-
1122
- let plainStrings= filterRawObject(conf.podata,"plain");
1123
- let htmlStrings = filterRawObject(conf.podata,"html");
1124
- const userType=ATLT["info"].type;
1125
- if((Array.isArray(plainStrings) && plainStrings.length) ||
1126
- (Array.isArray(htmlStrings)&& htmlStrings.length)
1127
- ){
1128
- const inActiveBtn='<fieldset><button title="Add API key to enable this feature." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button> <a style="font-size:9px;display:block;margin-left:8px;" target="_blank" href="https://www.ibm.com/in-en/cloud/watson-language-translator/pricing">Get Free API Key</a></fieldset>';
1129
- const disabledBtn='<fieldset><button title="Buy PRO." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button><div style="max-width:320px; display:inline-block;margin-top: 4px;"><span style="font-size:12px;display:inline-block;margin-left:8px;">You have exceeded free translation limit. In order to extend the limit - <a target="_blank" style="font-size:14px;display:inline-block;margin-left:8px;" target="_blank" href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing">Buy Premium License</a></span></div></fieldset>';
1130
- const apiKey=ATLT["api_key"]["yApiKey"];
1131
- const proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';
1132
- const allowed=ATLT["info"].allowed;
1133
- const today=ATLT["info"].today;
1134
- const total=ATLT["info"].total;
1135
- const aTodayChars=300000;
1136
- const aTodayChar=1000000;
1137
-
1138
- // not added API key
1139
- if( ATLT == undefined || ATLT["api_key"] =='' ){
1140
- if( userType=='free'){
1141
- locoActions.append(inActiveBtn);
1142
- return;
1143
- }else{
1144
- locoActions.append(proActiveBtn);
1145
- }
1146
- }else if(
1147
- ATLT["api_key"]["yApiKey"]=="" && ATLT["api_key"]["ibmApiKey"]==""){
1148
- if( userType=='free'){
1149
- locoActions.append(inActiveBtn);
1150
- return;
1151
- }else{
1152
- locoActions.append(proActiveBtn);
1153
- }
1154
- }
1155
- else if( allowed=="no" && userType=='free'){
1156
- // free not allowed
1157
- locoActions.append(disabledBtn);
1158
- return;
1159
- }else if(today!==undefined && parseInt(today)>aTodayChars
1160
- && userType=='free'){
1161
- // today free limit exceeded
1162
- locoActions.append(disabledBtn);
1163
- return;
1164
- }else if(total!==undefined && parseInt(total)>aTodayChar
1165
- && userType=='free'){
1166
- // monthly limit exceeded
1167
- locoActions.append(disabledBtn);
1168
- return;
1169
- }else if( window.locoEditorStats.totalTranslated != "100%"
1170
- && window.locoEditorStats.totalWords > 0 ){
1171
- //Pro user and added key then show button
1172
- if(userType=='pro' && ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])){
1173
- locoActions.append(proActiveBtn);
1174
- }else{
1175
- //if user is free and allowed the show button
1176
- if(today==undefined){
1177
- var todayChars=aTodayChars;
1178
- }else{
1179
- var todayChars=aTodayChars-parseInt(today);
1180
- }
1181
- var totalChars=aTodayChar-parseInt(total);
1182
- // append button for free
1183
- var freeBtn='<fieldset><button data-today-limit="'+todayChars+'" data-total-limit="'+totalChars+'" id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';
1184
- locoActions.append(freeBtn);
1185
- }
1186
- } else if( window.locoEditorStats.totalWords == 0){
1187
- return;
1188
- }
1189
- } else{
1190
- locoActions.append(allTranslated);
1191
- }
1192
-
1193
- if((Array.isArray(savedStrings) && savedStrings.length)){
1194
- if(userType=='pro' && ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"])){
1195
- if(ATLT["info"]["proInstalled"]=="yes"){
1196
- locoActions.append(otherBtn);
1197
- }
1198
-
1199
- }
1200
- }
1201
-
1202
- }
1203
- // mark unsaved after ajax translation process
1204
- function markUnsavedString(){
1205
- const unSavedString = JSON.parse(localStorage.getItem('unSavedString'));
1206
-
1207
- for(var x=0;x<=unSavedString.length;x++){
1208
- var source = unSavedString[x];
1209
- jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter(function(index){
1210
- return jQuery(this).text() == source
1211
- }).addClass('po-unsaved');
1212
- }
1213
- }
1214
-
1215
  // detect String contain URL
1216
  function ValidURL(str) {
1217
  var pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
@@ -1267,218 +1238,37 @@ function isContainChars(str){
1267
  return false;
1268
  }
1269
  }
1270
- // format numbers
1271
- function atltFormatNumber(num) {
1272
- return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
1273
- }
1274
-
1275
- // create popup model for translation settings
1276
- function createSettingsPopup(){
1277
- let preloaderImg=extradata['preloader_path'];
1278
- let gtPreviewImg=extradata['gt_preview'];
1279
- const userInfo=ATLT["info"].type;
1280
- const yAC=ATLT["info"].yAvailableChars;
1281
- const iAC=ATLT["info"].iAvailableChars;
1282
- const licenseKey=ATLT["info"]["licenseKey"];
1283
- const proInstalled=ATLT["info"]["proInstalled"];
1284
- let yfieldStatus="";
1285
- let ifieldStatus="";
1286
- let gfieldStatus="";
1287
- let mfieldStatus="";
1288
- let hfieldStatus="";
1289
- let htmlSupported="";
1290
- let contCls="";
1291
- let icontCls="";
1292
- let proLbl="";
1293
- let gContCls='';
1294
- let gHtml='';
1295
- let mContCls='';
1296
- let mHtml='';
1297
- let submitBtn='';
1298
- let yHtml='';
1299
- let iHtml='';
1300
- let yChecked='"';
1301
- let iChecked='checked="true"';
1302
- if(userInfo=="free"){
1303
- let gAC=0;
1304
- gfieldStatus="disabled";
1305
- mfieldStatus="disabled";
1306
- hfieldStatus="disabled";
1307
- contCls="html-disabled";
1308
- gContCls='g-disabled';
1309
- mContCls='m-disabled';
1310
- proLbl='<span class="atlt-pro-feature"><a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank" style="color:red;font-weight:bold;font-size:0.9em;" title="Only For Pro Users">PRO Only</a></span>';
1311
-
1312
- gHtml=proLbl+' ';
1313
- mHtml=proLbl+' ';
1314
- }else if(proInstalled=="no"){
1315
- gfieldStatus="disabled";
1316
- mfieldStatus="disabled";
1317
- hfieldStatus="disabled";
1318
- contCls="html-disabled";
1319
- gContCls='g-disabled';
1320
- mContCls='m-disabled';
1321
- proLbl='<span style="color:red;font-weight:bold;font-size:0.9em;" class="atlt-pro-feature">Please Install PRO version</span>';
1322
-
1323
- gHtml=proLbl+' ';
1324
- mHtml=proLbl+' ';
1325
- }else{
1326
-
1327
- if(ATLT["info"]["licenseKey"]!=undefined && validLicenseKey(ATLT["info"]["licenseKey"]))
1328
- {
1329
- if(ATLT["api_key"]["gApiKey"]!="" ){
1330
- let gAC=ATLT["info"].gAvailableChars;
1331
- if(gAC!==undefined && gAC>10000){
1332
- gHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+ atltFormatNumber(gAC)+' Free Char. Available This Month)</span>';
1333
- }else if(gAC<10000){
1334
- gHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>';
1335
- }
1336
- }else{
1337
- gfieldStatus="disabled";
1338
- gContCls='g-disabled';
1339
- gHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Google Translate API key)</span>';
1340
- }
1341
- if(ATLT["api_key"]["mApiKey"]!=undefined &&
1342
- ATLT["api_key"]["mApiKey"]!="" ){
1343
- mAC=ATLT["info"].mAvailableChars;
1344
- if(mAC!==undefined && mAC>10000){
1345
- mHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+ atltFormatNumber(mAC)+' Free Char. Available This Month)</span>';
1346
- }else if(mAC<10000){
1347
- mHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>';
1348
- }
1349
- }else{
1350
- mfieldStatus="disabled";
1351
- mContCls='m-disabled';
1352
- mHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Microsoft Translator API key)</span>';
1353
- }
1354
- }
1355
- }
1356
- if(ATLT["api_key"]["yApiKey"]!="")
1357
- {
1358
- if(yAC!==undefined){
1359
- yHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(yAC)+' Free Char. Available Monthly)</span>';
1360
- }
1361
- }else{
1362
- yfieldStatus="disabled";
1363
- yContCls='g-disabled';
1364
- yChecked='';
1365
- yHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Yandex Translate API v1 key)</span>';
1366
- }
1367
- if(ATLT["api_key"]["ibmApiKey"]=="" || ATLT["info"]["ibm_url"]==""){
1368
- ifieldStatus="disabled";
1369
- iContCls='g-disabled';
1370
- iChecked='';
1371
- iHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter IBM Translate API key/URL)</span>';
1372
- }else{
1373
- if(iAC!==undefined){
1374
- iHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(iAC)+' Free Char. Available Monthly)</span>';
1375
- }
1376
- }
1377
- if(userInfo=="free"){
1378
- plainStringLbl='Translate Plain Text Strings(No HTML/Special character supported)';
1379
- }else{
1380
- plainStringLbl='Translate Plain Text Strings';
1381
- }
1382
-
1383
- if( ATLT["api_key"]["yApiKey"]!="" || ATLT["api_key"]["gApiKey"]!="" || ATLT["api_key"]["mApiKey"]!="" || ATLT["api_key"]["ibmApiKey"]!="")
1384
- {
1385
- submitBtn='<input type="submit" class="button has-icon icon-translate" value="Start Translation" id="cool-auto-translate-start">';
1386
- }else{
1387
- submitBtn='<button class="atlt-ok button button-primary">OK</button>';
1388
 
1389
- }
1390
- let settingsHTML=`<div class="atlt-settings">
1391
- <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Google Page Translate Button<br/>(No API Key Required + Unlimited Translations!)</strong>
1392
- <div class="inputGroup">
1393
- <button id="atlt_gtranslate_btn" disabled="true" class="notranslate button button-primary">Google Translate</button>
1394
- <br/><img src="${gtPreviewImg}" alt="google translate widget preview"><br/>
1395
- ${proLbl}
1396
- ✅ Available Inside Pro Version 1.1<br/><span style="font-size:11px;font-weight:bold;">(Release date:- 27 June, 2020)</span>
1397
- </div>
1398
- <hr/>
1399
- <div class="atlt-settings">
1400
- <form id="atlt-settings-form" method="post" action="#">
1401
- <strong class="atlt-heading" style="margin:15px 0 10px;display:inline-block;">Translate Using A Translate API</strong>
1402
- <div class="inputGroup">
1403
- <input class="inputEle" type="radio" id="ibm_api"
1404
- ${iChecked} ${ifieldStatus} name="api_type" value="ibm">
1405
- <label for="ibm_api">IBM Translate ${iHtml}</label>
1406
- </div>
1407
- <div class="inputGroup">
1408
- <input class="inputEle" type="radio" id="yandex_api"
1409
- ${yChecked} ${yfieldStatus} name="api_type" value="yandex">
1410
- <label for="yandex_api">Yandex Translate ${yHtml}</label>
1411
- </div>
1412
 
1413
- <div class="inputGroup ${gContCls}">
1414
- <input class="inputEle" type="radio" id="google_api"
1415
- name="api_type" value="google" ${gfieldStatus}>
1416
- <label for="google_api">Google Translate ${gHtml}</label>
1417
- </div>
1418
- <div class="inputGroup ${mContCls}">
1419
- <input class="inputEle" type="radio" id="microsoft_api"
1420
- name="api_type" value="microsoft" ${mfieldStatus}>
1421
- <label for="microsoft_api">Microsoft Translator ${mHtml}</label>
1422
- <br/>
1423
- <small style="display:inline-block;margin-left:24px;margin-top:8px;font-weight:bold;">(<a href="https://locoaddon.com/supported-languages/" target="_blank">View all supported languages list</a>)</small>
1424
- </div>
1425
- <br/>
1426
- <fieldset>
1427
- ${submitBtn}
1428
- <img style="display:none;margin-left:10px;margin-top:-3px;" id="atlt_preloader" src="${preloaderImg}">
1429
- </fieldset>
1430
- </form>
1431
- </div>`;
1432
- // custom popup message box
1433
- let popup_html = `<div id="atlt-dialog-container">
1434
- <div style="display:none;" id="atlt-dialog" title="Automatic Translation Progress">
1435
- ${settingsHTML}
1436
- <p><span class="translated-label">Translated</span>
1437
- <span class="translated-text">0%</span></p>
1438
- <div class="atlt-progress-bar-track">
1439
- <div class="atlt-progress-bar-value">
1440
- </div></div>
1441
- <div class="atlt-final-message"></div>
1442
- <button style="display:none;" class="atlt-ok button button-primary">OK</button>
1443
- </div></div>`;
1444
- $("body").append( popup_html );
1445
- }
1446
 
1447
- // send ajax request
1448
- function atlt_ajax_translation_request(data,type){
1449
- let filteredArr=[];
1450
- filteredArr=data.textToTranslateArr.map((item)=>{
1451
- if( typeof item.source!= 'undefined'){
1452
- return item.source;
1453
- } });
1454
- const jsonData=JSON.stringify(filteredArr);
1455
-
1456
- return jQuery.ajax({
1457
- url: ajaxurl,
1458
- type:'POST',
1459
- data: {'action':data.endpoint,
1460
- 'sourceLan':data.sourceLang,
1461
- 'targetLan':data.targetLang,
1462
- 'totalCharacters': TotalCharacters,
1463
- 'requestChars':requestChars,
1464
- 'nonce':data.nonce,
1465
- 'strType':data.strType,
1466
- 'apiType':data.apiType,
1467
- 'data':jsonData
1468
- },
1469
- done:function(res){
1470
- // console.log(res)
1471
- }
1472
-
1473
-
1474
- });
1475
  }
1476
 
1477
- // ok, editor ready
1478
- updateStatus();
1479
-
 
 
 
1480
  // clean up
1481
- //delete window.locoConf;
1482
- //conf = buttons = null;
1483
 
1484
  }( window, jQuery );
 
1
  /**
2
  * Script for PO file editor pages
3
  */
4
  !function( window, $ ){
5
+
 
 
 
 
 
 
 
 
 
 
 
 
6
  var loco = window.locoScope,
7
+ conf = window.conf,
8
+ fileRefs = loco.po.ref.init(loco,conf),
9
+
10
  syncParams = null,
11
  saveParams = null,
12
+ ajaxUpload = conf.multipart,
13
+
14
  // UI translation
15
  translator = loco.l10n,
16
  sprintf = loco.string.sprintf,
17
+
18
  // PO file data
19
  locale = conf.locale,
20
  messages = loco.po.init( locale ).wrap( conf.powrap ),
21
  template = ! locale,
22
+
23
  // form containing action buttons
24
  elForm = document.getElementById('loco-actions'),
25
  filePath = conf.popath,
32
  // prevent all write operations if readonly mode
33
  readonly = conf.readonly,
34
  editable = ! readonly,
35
+
36
  // Editor components
37
  editor,
38
  saveButton,
39
+ innerDiv = document.getElementById('loco-editor-inner'),
40
+
41
+ // validation and suggestions
42
+ translationClients,
43
+ translationApiKeys = conf.apis || [],
44
+ suggestionCache = {},
45
+
46
+ // modal windows
47
+ $suggestModal,
48
+ $translateModal;
49
+
50
+ // warn if ajax uploads are enabled but not supported
51
+ if( ajaxUpload && ! ( window.FormData && window.Blob ) ){
52
+ ajaxUpload = false;
53
+ loco.notices.warn("Your browser doesn't support Ajax file uploads. Falling back to standard postdata");
54
+ }
55
+
56
 
57
+ /**
 
58
  *
59
  */
60
  function doSyncAction( callback ){
106
  loco.ajax.post( 'sync', syncParams, onSuccess, callback );
107
  }
108
 
109
+
110
+
111
  function debugMerge( console, result ){
112
  var i = -1, t = result.add.length;
113
  while( ++i < t ){
119
  }
120
  }
121
 
122
+
123
+
124
+ // API client getters
125
+ function createTranslationClients() {
126
+ var i = -1, info, clients = [], keys = translationApiKeys, num = keys.length;
127
+ while( ++i < num ){
128
+ try {
129
+ info = keys[i];
130
+ clients.push( loco.apis.create(info) );
131
+ }
132
+ catch( Er ){
133
+ loco.notices.error( String(Er) );
134
+ }
135
+ }
136
+ return clients;
137
+ }
138
+
139
+ function getTranslationClients(){
140
+ return translationClients || ( translationClients = createTranslationClients() );
141
+ }
142
+
143
+ function getTranslationClient(id){
144
+ // not indexed as object, annoyingly.
145
+ var client, clients = getTranslationClients(), num = clients.length, i = -1;
146
+ while( ++i < num ){
147
+ client = clients[i];
148
+ if( client.getId() === id ){
149
+ return client;
150
+ }
151
+ }
152
+ loco.notices.error('No '+id+' client');
153
+ }
154
+
155
+
156
+ // Calling external translation providers
157
+
158
+ function onHintEvent( /*event*/ ){
159
+ translationApiKeys.length ? loadSuggestions() : loadUnconfiguredApis();
160
+ }
161
+
162
+
163
+ function getTranslationModal(){
164
+ if( ! $translateModal ){
165
+ $translateModal = $('#loco-auto');
166
+ // http://api.jqueryui.com/dialog/
167
+ $translateModal.dialog({
168
+ dialogClass: 'loco-modal',
169
+ appendTo: '#loco.wrap',
170
+ title: $translateModal.attr('title'),
171
+ modal: true,
172
+ closeOnEscape: true,
173
+ resizable: false,
174
+ position: { my: "top", at: "top", of: '#loco-content' }
175
+ } );
176
+ }
177
+ return $translateModal;
178
+ }
179
+
180
+
181
+
182
+ function loadUnconfiguredApis(){
183
+ getTranslationModal().dialog('open');
184
+ }
185
+
186
+
187
+ function initAutoTranslate(){
188
+ var job,
189
+ credit,
190
+ translated = 0,
191
+ t = translator,
192
+ flagFuzzy = false,
193
+ $modal = getTranslationModal().dialog('open'),
194
+ $form = $modal.find('form'),
195
+ $butt = $form.find('button.button-primary'),
196
+ $stat = $('#loco-job-progress')
197
+ ;
198
+ function enable(){
199
+ $butt[0].disabled = false;
200
+ }
201
+ function disable(){
202
+ $butt[0].disabled = true;
203
+ }
204
+ function think(){
205
+ $butt.addClass('loco-loading');
206
+ }
207
+ function unthink(){
208
+ $butt.removeClass('loco-loading');
209
+ }
210
+ function showStatus( message ){
211
+ $stat.text(message);
212
+ }
213
+ // calculate job with current spec. not async. should be fast
214
+ function refreshJob( elForm ){
215
+ var apiId = $(elForm['api']).val(),
216
+ client = getTranslationClient(apiId),
217
+ overwrite = elForm['existing'].checked
218
+ ;
219
+ showStatus('Calculating....'); // <- won't render sync!
220
+ job = client.createJob();
221
+ job.init( messages, overwrite );
222
+ credit = client.toString();
223
+ showStatus(
224
+ sprintf( t._('%s unique source strings.'), job.length.format(0) )+' '+
225
+ // translators: characters meaning individual unicode characters of source text
226
+ sprintf( t._('%s characters will be sent for translation.'), job.chars.format(0) )
227
+ );
228
+ // job ready for dispatch.
229
+ job.length ? enable() : disable();
230
+ }
231
+ // refresh job if specification changes
232
+ function onJobChange( event ){
233
+ var elField = event.target, f = elField.name;
234
+ if( 'api' === f || 'existing' === f ){
235
+ refreshJob(elField.form);
236
+ }
237
+ return true;
238
+ }
239
+ // dispatch job if form submitted
240
+ function onJobDispatch( event ){
241
+ event.preventDefault();
242
+ think();
243
+ disable();
244
+ onProgress(0);
245
+ flagFuzzy = event.target['fuzzy'].checked;
246
+ job.dispatch().done(onJobComplete).each(onEachTranslatedMessage).prog(onProgress);
247
+ }
248
+ function onEachTranslatedMessage(message){
249
+ if( job ){
250
+ flagFuzzy && message.fuzzy(0,true);
251
+ editor.pasteMessage(message);
252
+ if( message === editor.active ){
253
+ editor.setStatus(message);
254
+ }
255
+ editor.unsave(message,0);
256
+ translated++;
257
+ }
258
+ }
259
+ // can't redraw translated count between messages, but can between batches!
260
+ function onProgress(didBatches,numBatches){
261
+ var percent = numBatches ? 100*didBatches/numBatches : 0;
262
+ // translators: %s%% is a percentage, e.g. 50%
263
+ showStatus( sprintf( t._('Translation progress %s%%'),percent.format(0)) );
264
+ }
265
+ function onJobComplete(){
266
+ unthink();
267
+ if( job ){
268
+ var remaining = job.length - translated;
269
+ if( remaining > 0 ) {
270
+ translated && loco.notices.warn( sprintf( t._('Translation job aborted with %s strings remaining'),remaining.format(0) ) );
271
+ }
272
+ if( translated > 0 ){
273
+ loco.notices.success( sprintf(t._('%s strings translated via '+credit), translated.format(0) ) ).stick();
274
+ // update stats and reindex
275
+ updateStatus();
276
+ editor.rebuildSearch();
277
+ }
278
+ job = null;
279
+ editor.fire('poAbort'); // <- hack allows re-enable of Auto buttons.
280
+ }
281
+ // close and destroy modal without recursion
282
+ if( $modal ){
283
+ $modal.off('dialogclose').dialog('close');
284
+ $modal = null;
285
+ }
286
+ }
287
+ // destructor
288
+ function onCloseModal(){
289
+ job.abort();
290
+ $modal = null;
291
+ onJobComplete();
292
+ }
293
+ // clean UI for new run
294
+ unthink();
295
+ disable();
296
+ // initialize default job and listen for changes to spec
297
+ $form.off('submit change')
298
+ refreshJob( $form[0] );
299
+ $form.on('change',onJobChange).on('submit',onJobDispatch);
300
+ $modal.off('dialogclose').on('dialogclose',onCloseModal)
301
+ }
302
+
303
+
304
+
305
+ function loadSuggestions(){
306
+ var t = translator,
307
+ message = editor.current(),
308
+ index = editor.getTargetOffset(),
309
+ source = message && message.source(null,index),
310
+ langAtts = 'lang="'+String(locale)+'" dir="'+(locale.isRTL()?'RTL':'LTR')+'"'
311
+ ;
312
+ if( source ){
313
+ function createSuggestionClosure( source, target ){
314
+ return function(event){
315
+ event.preventDefault();
316
+ event.stopPropagation();
317
+ destroyScope();
318
+
319
+ // use this translation.
320
+ var message = editor.current(), index = editor.getTargetOffset();
321
+ if( message && message.source(null,index) === source ){
322
+ message.translate(target,index);
323
+ editor.focus().reloadMessage(message)
324
+ // editor.fuzzy(true,message,index); // TODO make optional
325
+ }
326
+ else {
327
+ loco.notices.warn('Source changed since suggestion');
328
+ }
329
+ }
330
+ }
331
+ function completeSuggestion( source, target, locale, client ){
332
+ var id = client.getId(), href = client.getUrl(), name = String(client), $div = placeholders && placeholders[id];
333
+ $div && $div.replaceWith( $('<div class="loco-api loco-api-'+id+'"></div>')
334
+ .append( $('<a class="loco-api-credit" target="_blank"></a>').attr('href',href).text(name) )
335
+ .append( $('<blockquote '+langAtts+'></blockquote>').text(target||'[FAILED]') )
336
+ .append( $('<button class="button button-primary"></button>').text(t._('Use this translation')).on('click',createSuggestionClosure(source,target)) )
337
+ );
338
+ // adjust position after each write
339
+ $modal.dialog('option','position', { my: "center", at: "center", of: window });
340
+ // are we done?
341
+ if( ++loaded === length ){
342
+ $modal && $modal.dialog('option','title', t._('Suggested translations')+' — '+locale.label );
343
+ }
344
+ }
345
+ function initSuggestion( client ){
346
+ var $div = $('<div class="loco-api loco-api-loading"></div>').text('Calling '+client+' ...');
347
+ placeholders[ client.getId() ] = $div;
348
+ return $div;
349
+ }
350
+ function destroyScope( closeEvent ){
351
+ if( $modal && null == closeEvent ) {
352
+ $modal.dialog('close');
353
+ }
354
+ $modal = null;
355
+ placeholders = null;
356
+ // TODO abort existing requests not yet returned
357
+ }
358
+ // closure ensures client that made call is available
359
+ function createCallbackClosure( client ){
360
+ return function( source, target, locale ){
361
+ cached[ client.getId() ] = target;
362
+ completeSuggestion(source, target, locale, client );
363
+ }
364
+ }
365
+ // http://api.jqueryui.com/dialog/
366
+ function getModal(){
367
+ return $suggestModal || ( $suggestModal = $('<div id="loco-hint"></div>').dialog( {
368
+ dialogClass : 'loco-modal',
369
+ modal : true,
370
+ autoOpen : false,
371
+ closeOnEscape : true,
372
+ resizable : false,
373
+ minHeight : 400
374
+ } ) );
375
+ }
376
+ // open modal for loading suggestions, starting with source
377
+ var $modal = getModal().html('').append( $('<div class="loco-api"><p>Source text:</p></div>').append( $('<blockquote lang="en"></blockquote>').text(source) ) )
378
+ .dialog('option','title', t._('Loading suggestions')+'...' )
379
+ .off('dialogclose').on('dialogclose',destroyScope)
380
+ .dialog('open')
381
+ ;
382
+ // show existing translation if there is one
383
+ var target = message.translation(index);
384
+ if( target ){
385
+ $('<div class="loco-api"><p>Current translation:</p></div>')
386
+ .append( $('<blockquote '+langAtts+'></blockquote>').text(target) )
387
+ .append( $('<button class="button"></button>').text(t._('Keep this translation')).on('click',function(event){
388
+ event.preventDefault();
389
+ destroyScope();
390
+ }) )
391
+ .appendTo($modal)
392
+ ;
393
+ }
394
+ // request translation from each api in *parallel* browser should handle queueing if required
395
+ var client, clientId, clients = getTranslationClients(), length = clients.length, i = -1,
396
+ cached = suggestionCache[source] || ( suggestionCache[source] = {} ),
397
+ placeholders = {},
398
+ loaded = 0
399
+ ;
400
+ while( ++i < length ){
401
+ client = clients[i];
402
+ $modal.append( initSuggestion(client) );
403
+ // setTimeout( completeSuggestion, fakeDelay*(i+1), source,source,locale,client);
404
+ clientId = client.getId();
405
+ if( cached[clientId] ){
406
+ completeSuggestion(source,cached[clientId],locale,client);
407
+ }
408
+ else {
409
+ client.translate( source, locale, createCallbackClosure(client) );
410
+ }
411
+ }
412
+ }
413
+ }
414
+
415
+
416
+ /**
417
+ * Capture clicks on file references
418
+ */
419
+ function onMetaClick( event, target ){
420
+ function tryTag( node, name ){
421
+ if( node.tagName === name ){
422
+ return node;
423
+ }
424
+ return node.getElementsByTagName(name)[0];
425
+ }
426
+ var codeEl = tryTag(target,'CODE');
427
+ if( codeEl ){
428
+ fileRefs.load( codeEl.textContent );
429
+ }
430
+ }
431
+
432
+
433
+ /**
434
+ * @param params {Object}
435
+ * @return FormData
436
+ */
437
+ function initMultiPart( params ){
438
+ var p, data = new FormData;
439
+ for( p in params ){
440
+ if( params.hasOwnProperty(p) ) {
441
+ data.append(p, params[p]);
442
+ }
443
+ }
444
+ return data;
445
+ }
446
+
447
+
448
  /**
449
  * Post full editor contents to "posave" endpoint
450
  */
451
  function doSaveAction( callback ){
452
+
453
  function onSuccess( result ){
454
  callback && callback();
455
  editor.save( true );
456
  // Update saved time update
457
  $('#loco-po-modified').text( result.datetime||'[datetime error]' );
458
  }
459
+ var postData = $.extend( {locale:String(messages.locale()||'')}, saveParams||{} );
460
  if( fsConnect ){
461
+ fsConnect.applyCreds(postData);
462
  }
463
+ // submit PO as concrete file if configured
464
+ if( ajaxUpload ){
465
+ postData = initMultiPart(postData);
466
+ postData.append('po', new Blob([String(messages)],{type:'application/x-gettext'}), String(postData.path).split('/').pop()||'untitled.po' );
467
+ }
468
+ else {
469
+ postData.data = String(messages);
470
+ }
471
+ loco.ajax.post( 'save', postData, onSuccess, callback );
472
  }
473
+
474
+
475
  function saveIfDirty(){
476
  editor.dirty && doSaveAction();
477
  }
478
+
479
+
480
+
481
  function onUnloadWarning(){
482
  // Translators: Warning appears when user tries to refresh or navigate away when editor work is unsaved
483
  return translator._("Your changes will be lost if you continue without saving");
484
  }
485
 
486
+
487
+
488
  function registerSaveButton( button ){
489
  saveButton = button;
490
  // enables and disable according to save/unsave events
498
  $(button).removeClass( 'button-primary loco-flagged' );
499
  } )
500
  ;
501
+ function disable(){
502
  button.disabled = true;
503
  }
504
  function enable(){
518
  event.preventDefault();
519
  think();
520
  doSaveAction( unthink );
 
 
 
521
  return false;
522
  } );
523
  return true;
524
  };
525
 
526
+
527
+
528
+ function registerSyncButton( button ){
529
  var project = conf.project;
530
  if( project ){
531
  function disable(){
573
  return true;
574
  }
575
 
576
+
577
+ function registerAutoTranslateButton( button ){
578
+ function disable(){
579
+ button.disabled = true;
580
+ }
581
+ function enable(){
582
+ button.disabled = false;
583
+ }
584
+ // like Sync, only allow processing when file is saved
585
+ editor
586
+ .on('poUnsaved', function(){
587
+ disable();
588
+ } )
589
+ .on('poSave poAbort', function(){
590
+ enable();
591
+ } )
592
+ ;
593
+ // click opens modal unless open already
594
+ $(button).click( function( event ){
595
+ event.preventDefault();
596
+ initAutoTranslate();
597
+ return false;
598
+ } );
599
+ enable();
600
+ return true;
601
+ }
602
+
603
+
604
+
605
+ /*function registerFuzzyButton( button ){
606
  var toggled = false,
607
  enabled = false
608
  ;
640
  return false;
641
  } );
642
  return true;
643
+ };*/
644
+
645
 
646
+
647
+ function registerRevertButton( button ){
648
  // No need for revert when document is saved
649
  editor
650
  .on('poUnsaved', function(){
663
  return true;
664
  };
665
 
666
+
667
+
668
  function registerInvisiblesButton( button ){
669
  var $button = $(button);
670
  button.disabled = false;
680
  return true;
681
  }
682
 
683
+
684
+
685
  function registerCodeviewButton( button ){
686
  var $button = $(button);
687
  button.disabled = false;
688
  $button.click( function(event){
689
  event.preventDefault();
690
  var state = ! editor.getMono();
 
691
  $button[ state ? 'addClass' : 'removeClass' ]('inverted');
692
+ editor.setMono(state);
693
  return false;
694
  } );
695
  locoScope.tooltip.init($button);
696
  return true;
697
  };
698
 
699
+
700
+
701
  function registerAddButton( button ){
702
  button.disabled = false;
703
  $(button).click( function( event ){
715
  return true;
716
  };
717
 
718
+
719
+
720
  function registerDelButton( button ){
721
  button.disabled = false;
722
  $(button).click( function(event){
727
  return true;
728
  };
729
 
730
+
731
+
732
  function registerDownloadButton( button, id ){
733
  button.disabled = false;
734
  $(button).click( function( event ){
753
  return false;
754
  }
755
 
756
+
757
  /*/ dummy function for enabling buttons that do nothing (or do something inherently)
758
  function registerNoopButton( button ){
759
  return true;
760
  }*/
761
 
762
+
763
+
764
  /**
765
  * Update status message above editor.
766
  * This is dynamic version of PHP Loco_gettext_Metadata::getProgressSummary
787
  }
788
  }
789
  $('#loco-po-status').text( stext );
 
 
 
 
 
 
 
790
  }
791
 
792
+
793
+
794
  /**
795
  * Enable text filtering
796
  */
817
  } )
818
  ;
819
  }
820
+
821
+
822
+
823
  // resize function fits editor to screen, accounting for headroom and touching bottom of screen.
824
  var resize = function(){
825
  function top( el, ancestor ){
855
  .init( innerDiv )
856
  .localise( translator )
857
  ;
858
+
859
  loco.po.kbd
860
  .init( editor )
861
+ .add('save', saveIfDirty )
862
+ .add('hint', locale && editable && onHintEvent || noop )
863
+ .enable('copy','clear','enter','next','prev','fuzzy','save','invis','hint')
864
  ;
865
 
866
  // initialize toolbar button actions
872
  // editor mode togglers
873
  invs: registerInvisiblesButton,
874
  code: registerCodeviewButton,
875
+ // download buttons
876
  source: registerDownloadButton,
877
  binary: template ? null : registerDownloadButton
878
  };
883
  }
884
  // PO only
885
  else {
886
+ buttons.auto = registerAutoTranslateButton;
887
+ }
888
  $('#loco-toolbar').find('button').each( function(i,el){
889
  var id = el.getAttribute('data-loco'), register = buttons[id];
890
  register && register(el,id) || $(el).hide();
905
  updateStatus();
906
  window.onbeforeunload = null;
907
  } )
908
+ .on('poHint', onHintEvent )
909
+ .on('poUpdate', updateStatus )
910
+ .on('poMeta', onMetaClick )
911
+ ;
912
 
913
  // load raw message data
914
  messages.load( conf.podata );
917
  editor.load( messages );
918
 
919
  // locale should be cast to full object once set in editor
920
+ locale = editor.targetLocale;
921
+ if( locale ){
922
  locale.isRTL() && $(innerDiv).addClass('trg-rtl');
923
  }
924
  // enable template mode when no target locale
926
  editor.unlock();
927
  }
928
 
929
+ // ok, editor ready
930
+ updateStatus();
931
+
932
+ /*---------------------custom Code---------------*/
933
 
934
  /*
935
+ since version 1.1
936
+ Google Translate Popup handlers
 
937
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
938
 
939
+ newaddAutoTranslationBtn();
940
+
941
+
942
+ // integrates auto traslator button in editor
943
+ function newaddAutoTranslationBtn(){
944
+ if($("#loco-toolbar").find("#cool-auto-translate-btn").length>0){
945
+ $("#loco-toolbar").find("#cool-auto-translate-btn").remove();
 
 
 
 
 
 
 
 
 
 
946
  }
947
+ const locoActions= $("#loco-toolbar").find("#loco-actions");
948
+ const otherBtn='<button class="button has-icon icon-warn" id="atlt_reset_all">Reset Translations</button></fieldset>';
949
+ const allTranslated='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate" disabled>Translated</button></fieldset>';
950
+ const proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';
951
+ locoActions.append(proActiveBtn);
952
+ }
953
+
954
+ // open popup on autotranslate button click
955
+ $("#cool-auto-translate-btn").on("click",function(){
956
+ createPopup();
957
+ });
958
+ // create auto translate popup
959
+ function createPopup(){
960
+ $( "#atlt-dialog" ).dialog({
961
+ resizable: false,
962
+ height: "auto",
963
+ width: 400,
964
+ modal: true,
965
+ buttons: {
966
+ Cancel: function() {
967
+ $( this ).dialog( "close" );
968
  }
 
 
 
 
 
969
  }
970
+ });
971
+ }
972
+
973
+ // Get the button that opens the modal
974
+ // var gTranslateBtn = document.getElementById("atlt_gtranslate_btn");
975
+
976
+ // When the user clicks the button, open the modal
977
+ $("#atlt_yandex_transate_btn").on("click",function() {
978
+ var defaultcode = window.conf.locale.lang?window.conf.locale.lang:null;
979
+ switch(defaultcode){
980
+ case 'bel':
981
+ defaultlang='be';
982
+ break;
983
+ case 'he':
984
+ defaultlang='iw';
985
+ break;
986
+ case'snd':
987
+ defaultlang='sd';
988
+ break;
989
+ case 'jv':
990
+ defaultlang='jw';
991
+ break;
992
+ default:
993
+ defaultlang=defaultcode;
994
+ break;
995
  }
996
+ $(".save_it").prop("disabled",true);
997
+ $(".ytstats").hide();
998
+ localStorage.setItem("lang",defaultlang);
999
+ var arr = ['af','am', 'ar','az','ba','be','bg','bn', 'bs','ca','ceb','cs','cy','da','de','el','en','eo','es','et','eu', 'fa', 'fi','fr','ga','gd','gl','gu', 'he','hi','hr','ht','hu','hy','id','is','it','ja','jv','ka','kk','km','kn','ko','ky','la','lb','lo','lt','lv','mg','mhr','mi','mk', 'ml','mn', 'mr','mrj','ms','mt','my','ne','nl','no','pa','pap','pl','pt','ro','ru','si','sk','sl','sq', 'sr', 'su', 'sv','sw','ta','te','tg','th','tl','tr','tt','udm','uk','ur','uz','vi','xh','yi', 'zhCN'];
1000
+ if(arr.includes(defaultlang)){
1001
+ // googleTranslateElementInit();
1002
  }
1003
+ else{
1004
+ $(".string_container").after("<strong>Yandex Automatic Translator Does not support this language.</strong>");
1005
+ $(".string_container").hide();
1006
+ $(".save_it").hide();
1007
+ $("#ytWidget").hide();
1008
+ }
1009
+ // get only plain strings
1010
+ var plainStrArr= filterRawObject(conf.podata,"plain");
1011
+ if (plainStrArr.length>0) {
1012
+ printStringsInPopup(plainStrArr, type="yandex");
1013
+ }else{
1014
+ $("#ytWidget").hide();
1015
+ $(".string_container").after("<strong>There is no plain string available for translations.</strong>");
1016
+ $(".string_container").hide();
1017
+ $(".save_it").hide();
1018
  }
1019
+ $("#atlt-dialog").dialog("close");
1020
+ $("#atlt_strings_model").addClass("yandex-translator").fadeIn("slow");
 
 
 
1021
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1022
  });
1023
 
1024
+ /*
1025
+ load strings in popup table
1026
+ */
1027
+ function printStringsInPopup(jsonObj,type){
1028
+ var replaceit={};
1029
+ var html='';
1030
+ var totalTChars=0;
1031
+ var index=1;
1032
+ if(jsonObj){
1033
+ for (const key in jsonObj) {
1034
+ if (jsonObj.hasOwnProperty(key)) {
1035
+ const element = jsonObj[key];
1036
+ if(element.source!=''){
1037
+ if(type=="yandex"){
1038
+ html +='<tr id="'+key+'" ><td>'+index+'</td><td class="notranslate source">'+element.source+'</td>';
1039
  }
1040
+ else{
1041
+ if(key>2500){
1042
+ break;
1043
+ }
1044
+ html +='<tr id="'+key+'" ><td>'+index+'</td><td class="notranslate source">'+element.source+'</td>';
1045
  }
1046
+ if(type=="yandex"){
1047
+ html +='<td translate="yes" class="target translate">'+element.source+'</td></tr>';
1048
+ }else{
1049
+ html +='<td class="target translate"></td></tr>';
1050
+ }
1051
+ index++;
1052
+ totalTChars +=element.source.length;
1053
+ }
1054
+ }
1055
+ }
1056
+ $(".ytstats").each(function(){
1057
+ $(this).find(".totalChars").html(totalTChars);
1058
+ });
1059
+ }
1060
+ if(type=="yandex"){
1061
+ $("#yandex_string_tbl").append(html);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1062
  }
1063
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1064
 
1065
+ /*
1066
+ Save Translated Strings
1067
+ */
1068
+ var rpl = {
1069
+ '"% s"': '"%s"',
1070
+ '"% d"': '"%d"',
1071
+ '"% S"': '"%s"',
1072
+ '"% D"': '"%d"',
1073
+ '% s': ' %s ',
1074
+ '% S': ' %s ',
1075
+ '% d': ' %d ',
1076
+ '% D': ' %d ',
1077
+ '٪ s': ' %s ',
1078
+ S': ' %s ',
1079
+ d': ' %d ',
1080
+ D': ' %d ',
1081
+ '٪ س': ' %s '
1082
+ };
1083
+ var translatedObj=[];
1084
+ $(".save_it").on("click",function(){
1085
+ $("#stringTemplate tbody tr").each(function(index){
1086
+ var string=$(this).find("td.target").text();
1087
+ translatedObj.push(string);
1088
+ });
1089
+ saveTranslatedStrings(translatedObj);
1090
+ $(".atlt_custom_model").fadeOut("slow");
1091
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1092
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1093
 
1094
+ // mark unsaved after ajax translation process
1095
+ function markUnsavedString(){
1096
+ const unSavedString = JSON.parse(localStorage.getItem('unSavedString'));
1097
+
1098
+ for(var x=0;x<=unSavedString.length;x++){
1099
+ var source = unSavedString[x];
1100
+ jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter(function(index){
1101
+ return jQuery(this).text() == source
1102
+ }).addClass('po-unsaved');
1103
+ }
1104
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1105
 
1106
+ // save translated string in popup
1107
+ function saveTranslatedStrings(translatedObj){
1108
+ var plainStrArr= filterRawObject(conf.podata,"plain");
1109
+ const saveBtn=$('[data-loco="save"]');
1110
+ if(translatedObj!==undefined && translatedObj.length){
1111
+ for(i=0;i< translatedObj.length;i++){
1112
+ var text = translatedObj[i];
1113
+ if( plainStrArr[i] === undefined ){
1114
+ break;
1115
+ }
1116
+ plainStrArr[i].target = strtr(text,rpl) ;
1117
+ }
1118
+ }
1119
 
1120
+ messages = loco.po.init( locale ).wrap( conf.powrap );
1121
+ // ready to render editor
1122
+ messages.load(conf.podata);
 
 
 
 
 
 
 
 
 
1123
 
1124
+ markUnsaved(plainStrArr);
1125
+ // editor event behaviours
1126
+ editor
1127
+ .on('poUnsaved', function(){
1128
+ window.onbeforeunload = onUnloadWarning;
1129
+ } )
1130
+ .on('poSave', function(){
1131
+ updateStatus();
1132
+ window.onbeforeunload = null;
1133
+ } )
1134
+ .on( 'poUpdate', updateStatus );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1135
 
1136
+ // ready to render editor
1137
+ editor.load(messages);
1138
+ saveBtn.addClass( 'button-primary loco-flagged' ).removeAttr("disabled");
1139
+ updateStatus();
1140
+ }
1141
 
1142
+ // replace placeholders in strings
1143
+ function strtr(s, p, r) {
1144
+ return !!s && {
1145
+ 2: function () {
1146
+ for (var i in p) {
1147
+ s = strtr(s, i, p[i]);
 
 
 
1148
  }
1149
+ return s;
1150
+ },
1151
+ 3: function () {
1152
+ return s.replace(RegExp(p, 'g'), r);
1153
+ },
1154
+ 0: function () {
1155
+ return;
 
 
1156
  }
1157
+ }[arguments.length]();
 
 
 
 
 
 
 
 
 
 
1158
  }
1159
+
 
 
 
 
 
 
 
 
1160
  // filter string based upon type
1161
  function filterRawObject(rawArray,filterType){
1162
  filterdArr=[];
1165
  if( ValidURL(item.source)){
1166
  return false;
1167
  }
 
 
 
 
 
 
 
 
 
1168
  if(isHTML(item.source)){
1169
  return false;
1170
  }
1178
  }else{
1179
  return true;
1180
  }
 
1181
  }
1182
  });
1183
  }
1184
 
1185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1186
  // detect String contain URL
1187
  function ValidURL(str) {
1188
  var pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
1238
  return false;
1239
  }
1240
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1241
 
1242
+ // mark unsaved strings
1243
+ function markUnsaved(data){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1244
 
1245
+ for (const key in data) {
1246
+
1247
+ if (data.hasOwnProperty(key)) {
1248
+ let element = data[key]['message'];
1249
+ if(data[key]['source']==""){
1250
+ continue;
1251
+ }
1252
+ // flagFuzzy && message.fuzzy(0,true);
1253
+ editor.pasteMessage(element);
1254
+ if( element === editor.active ){
1255
+ editor.setStatus(element);
1256
+ }
1257
+ editor.unsave(element,0);
1258
+
1259
+ }
1260
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1262
  }
1263
 
1264
+ // format numbers
1265
+ function atltFormatNumber(num) {
1266
+ return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
1267
+ }
1268
+
1269
+ /*---------------------end------------------*/
1270
  // clean up
1271
+ // delete window.locoConf;
1272
+ //conf = buttons = null;
1273
 
1274
  }( window, jQuery );
assets/js/loco-js-editor.min.js CHANGED
@@ -1 +1 @@
1
- !function(window,$){var TotalCharacters=0,HtmlStrings=0,requestChars=0;let event;document.createEvent("event").initEvent("atlt_run_translation"),createSettingsPopup(),$("#atlt-dialog .atlt-ok.button").on("click",(function(){localStorage.removeItem("unSavedString"),$("#atlt-dialog").parent(".ui-dialog").hide()}));var loco=window.locoScope,conf=window.locoConf,syncParams=null,saveParams=null,translator=loco.l10n,sprintf=loco.string.sprintf,locale=conf.locale,messages=loco.po.init(locale).wrap(conf.powrap),template=!locale,elForm=document.getElementById("loco-actions"),filePath=conf.popath,syncPath=conf.potpath,elFilesys=document.getElementById("loco-fs"),fsConnect=elFilesys&&loco.fs.init(elFilesys),readonly,editable=!conf.readonly,editor,saveButton,innerDiv=document.getElementById("loco-editor-inner");function doSyncAction(callback){function onSuccess(result){var info=[],doc=messages,exp=result.po,src=result.pot,pot=loco.po.init().load(exp),done=doc.merge(pot),nadd=done.add.length,ndel=done.del.length,t=translator;editor.load(doc),nadd||ndel?(src?info.push(sprintf(t._("Merged from %s"),src)):info.push(t._("Merged from source code")),nadd&&info.push(sprintf(t._n("1 new string added","%s new strings added",nadd),nadd)),ndel&&info.push(sprintf(t._n("1 obsolete string removed","%s obsolete strings removed",ndel),ndel)),$(innerDiv).trigger("poUnsaved",[]),updateStatus(),window.console&&debugMerge(console,done)):src?info.push(sprintf(t._("Already up to date with %s"),src)):info.push(t._("Already up to date with source code")),loco.notices.success(info.join(". ")),$(innerDiv).trigger("poMerge",[result]),callback&&callback()}loco.ajax.post("sync",syncParams,onSuccess,callback)}function debugMerge(console,result){for(var i=-1,t=result.add.length;++i<t;)console.log(" + "+result.add[i].source());for(i=-1,t=result.del.length;++i<t;)console.log(" - "+result.del[i].source())}function doSaveAction(callback){function onSuccess(result){callback&&callback(),editor.save(!0),$("#loco-po-modified").text(result.datetime||"[datetime error]")}saveParams.locale=String(messages.locale()||""),fsConnect&&fsConnect.applyCreds(saveParams),saveParams.data=String(messages),loco.ajax.post("save",saveParams,onSuccess,callback)}function saveIfDirty(){editor.dirty&&doSaveAction()}function onUnloadWarning(){return translator._("Your changes will be lost if you continue without saving")}function registerSaveButton(button){function disable(){button.disabled=!0}function enable(){button.disabled=!1}function think(){disable(),$(button).addClass("loco-loading")}function unthink(){enable(),$(button).removeClass("loco-loading")}return saveButton=button,editor.on("poUnsaved",(function(){enable(),$(button).addClass("button-primary loco-flagged")})).on("poSave",(function(){disable(),$(button).removeClass("button-primary loco-flagged")})),saveParams=$.extend({path:filePath},conf.project||{}),$(button).click((function(event){return event.preventDefault(),think(),doSaveAction(unthink),setTimeout((function(){location.reload()}),3500),!1})),!0}function registerSyncButton(button){var project=conf.project;if(project){function disable(){button.disabled=!0}function enable(){button.disabled=!1}function think(){disable(),$(button).addClass("loco-loading")}function unthink(){enable(),$(button).removeClass("loco-loading")}editor.on("poUnsaved",(function(){disable()})).on("poSave",(function(){enable()})),syncParams={bundle:project.bundle,domain:project.domain,type:template?"pot":"po",sync:syncPath||""},$(button).click((function(event){return event.preventDefault(),think(),doSyncAction(unthink),!1})),enable()}return!0}function registerFuzzyButton(button){var toggled=!1,enabled=!1;function redraw(message,state){var allowed=message&&message.translated(0)||!1;enabled!==allowed&&(button.disabled=!allowed,enabled=allowed),state!==toggled&&($(button)[state?"addClass":"removeClass"]("inverted"),toggled=state)}return editor.on("poSelected",(function(event,message){redraw(message,message&&message.fuzzy()||!1)})).on("poEmpty",(function(event,blank,message,pluralIndex){0===pluralIndex&&blank===enabled&&redraw(message,toggled)})).on("poFuzzy",(function(event,message,newState){redraw(message,newState)})),$(button).click((function(event){return event.preventDefault(),editor.fuzzy(!editor.fuzzy()),!1})),!0}function registerRevertButton(button){return editor.on("poUnsaved",(function(){button.disabled=!1})).on("poSave",(function(){button.disabled=!0})),$(button).click((function(event){return event.preventDefault(),location.reload(),!1})),!0}function registerInvisiblesButton(button){var $button=$(button);return button.disabled=!1,editor.on("poInvs",(function(event,state){$button[state?"addClass":"removeClass"]("inverted")})),$button.click((function(event){return event.preventDefault(),editor.setInvs(!editor.getInvs()),!1})),locoScope.tooltip.init($button),!0}function registerCodeviewButton(button){var $button=$(button);return button.disabled=!1,$button.click((function(event){event.preventDefault();var state=!editor.getMono();return editor.setMono(state),$button[state?"addClass":"removeClass"]("inverted"),!1})),locoScope.tooltip.init($button),!0}function registerAddButton(button){return button.disabled=!1,$(button).click((function(event){event.preventDefault();var i=1,baseid,msgid,regex=/(\d+)$/;for(msgid=baseid="New message";messages.get(msgid);)i=regex.exec(msgid)?Math.max(i,RegExp.$1):i,msgid=baseid+" "+ ++i;return editor.add(msgid),!1})),!0}function registerDelButton(button){return button.disabled=!1,$(button).click((function(event){return event.preventDefault(),editor.del(),!1})),!0}function registerDownloadButton(button,id){return button.disabled=!1,$(button).click((function(event){var form=button.form,path=filePath;return"binary"===id&&(path=path.replace(/\.po$/,".mo")),form.path.value=path,form.source.value=messages.toString(),!0})),!0}function noop(event){return event.preventDefault(),!1}function updateStatus(){var t=translator,stats=editor.stats(),total=stats.t,fuzzy=stats.f,empty=stats.u,stext=sprintf(t._n("1 string","%s strings",total),total.format(0)),extra=[];locale&&(stext=sprintf(t._("%s%% translated"),stats.p.replace("%",""))+", "+stext,fuzzy&&extra.push(sprintf(t._("%s fuzzy"),fuzzy.format(0))),empty&&extra.push(sprintf(t._("%s untranslated"),empty.format(0))),extra.length&&(stext+=" ("+extra.join(", ")+")")),$("#loco-po-status").text(stext),void 0===window.locoEditorStats?window.locoEditorStats={totalWords:stats.t,totalTranslated:stats.p}:(window.locoEditorStats.totalWords=stats.t,window.locoEditorStats.totalTranslated=stats.p)}function initSearchFilter(elSearch){function showValidFilter(numFound){$(elSearch.parentNode)[numFound||null==numFound?"removeClass":"addClass"]("invalid")}editor.searchable(loco.fulltext.init()),elSearch.disabled=!1,elSearch.value="";var listener=loco.watchtext(elSearch,(function(value){var numFound;showValidFilter(editor.filter(value,!0))}));editor.on("poFilter",(function(event,value,numFound){listener.val(value||""),showValidFilter(numFound)})).on("poMerge",(function(event,result){var value=listener.val();value&&editor.filter(value)}))}var resize=function(){function top(el,ancestor){for(var y=el.offsetTop||0;(el=el.offsetParent)&&el!==ancestor;)y+=el.offsetTop||0;return y}var fixHeight,minHeight=parseInt($(innerDiv).css("min-height")||0);return function(){var padBottom=20,topBanner=top(innerDiv,document.body),winHeight=window.innerHeight,setHeight=Math.max(minHeight,winHeight-topBanner-20);fixHeight!==setHeight&&(innerDiv.style.height=String(setHeight)+"px",fixHeight=setHeight)}}();resize(),$(window).resize(resize),innerDiv.innerHTML="",editor=loco.po.ed.init(innerDiv).localise(translator),loco.po.kbd.init(editor).add("save",saveIfDirty).enable("copy","clear","enter","next","prev","fuzzy","save","invis");var buttons={save:editable&&registerSaveButton,sync:editable&&registerSyncButton,revert:registerRevertButton,invs:registerInvisiblesButton,code:registerCodeviewButton,source:registerDownloadButton,binary:template?null:registerDownloadButton};function createEncodedString(allStringText){const queryString=allStringText.map(item=>"&text="+encodeURIComponent(item.source)).join(",");return queryString}function validLicenseKey(licenseKey){if(!(null!=licenseKey&&licenseKey.length>1))return!1;{let validKey;if(validate_pattern(licenseKey).length>1)return licenseKey}}function savedTimeInfo(statsObj){var info="";if(null!=statsObj&&void 0!==statsObj.time_saved){let timeSaved,totalChars;var info=`<div class="saved_time_wrapper" style="margin:10px 0px">\n <span style="border: 3px solid #14b75d;display: inline-block;padding: 3px;">\n Wahooo! You have saved your \n <strong>${statsObj.time_saved}</strong> \n via auto translating <strong>${statsObj.totalChars}</strong> \n characters using <strong> <br />\n <a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" target="_new">\n Loco Automatic Translate Addon</a></strong>\n </span></div>`}return info}function validate_pattern(str){let m;const regex=/^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/gm;let saveMatch=[];for(;null!==(m=regex.exec(str));)m.index===regex.lastIndex&&regex.lastIndex++,m.forEach((match,groupIndex)=>{saveMatch.push(match)});return saveMatch}function getTargetLang(){return window.locoConf.locale.lang?window.locoConf.locale.lang:null}function atlt_translate(data){atlt_ajax_translation_request(data,"POST").success((function(resp,status,xhr){if(200==xhr.status&&null!=resp){const json_resp=JSON.parse(resp);let responseObj,apiProvider=window.locoEditorStats.dataObj.apiType;if(json_resp.error&&800==json_resp.error.code){let errorMsz=json_resp.error.message;return $("#atlt-dialog .atlt-final-message").html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>"),$("#atlt-dialog .atlt-ok.button").show(),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Error").attr("disabled","disabled"),setTimeout((function(){location.reload()}),4e3),!1}if(null==json_resp.translatedString||!json_resp.translatedString.length||200!=json_resp.code){let errorCode=json_resp.code,errorMsz=json_resp.error;return $("#atlt-dialog .atlt-final-message").html("<p style='color:red;margin:5px 2px;font-weight:bold;'>"+errorMsz+"</p>"),$("#atlt-dialog .atlt-ok.button").show(),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Error").attr("disabled","disabled"),setTimeout((function(){location.reload()}),4e3),!1}responseObj=json_resp.translatedString;let totalTranslated=window.locoEditorStats.totalTranslated,unSavedStr=[];if(void 0!==responseObj&&responseObj.length)for(i=0;i<responseObj.length;i++){var text=responseObj[i];if(void 0===data.textToTranslateArr[i])break;data.textToTranslateArr[i].target=text}let translatedStrArr=data.textToTranslateArr,Emptytargets=[],items;for(var x=0;x<translatedStrArr.length;++x)""!=translatedStrArr[x].target&&(Emptytargets[x]=translatedStrArr[x].source);items=localStorage.getItem("unSavedString")?JSON.parse(localStorage.getItem("unSavedString")):[];var unSavedStrArr=items.concat(Emptytargets);localStorage.setItem("unSavedString",JSON.stringify(unSavedStrArr)),(messages=loco.po.init(locale).wrap(conf.powrap)).load(conf.podata),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poUpdate",updateStatus),editor.load(messages),data.saveBtn.addClass("button-primary loco-flagged").removeAttr("disabled"),updateStatus(),markUnsavedString(),requestChars=0,$("#atlt-dialog .translated-label").text("Translated"),$("#atlt-dialog .translated-text").text(window.locoEditorStats.totalTranslated),$("#atlt-dialog .atlt-progress-bar-value").width(window.locoEditorStats.totalTranslated);let saved_time_html=savedTimeInfo(json_resp.stats),finalHTML="<strong style='font-size:18px;display:inline-block;margin:5px auto;'>Translation Complete!</strong><br/>(Close this popup & Click <strong>Save</strong>).";switch(window.locoEditorStats.totalTranslated){case"0%":$("#atlt-dialog .translated-label").text("Translating..."),$("#atlt-dialog .translated-text").text("");break;case"100%":return data.thisBtn.hide(),$("#atlt_preloader").hide(),data.thisBtn.attr("disabled","disabled"),$("#cool-auto-translate-btn").text("Translated - SAVE NOW").attr("disabled","disabled"),$("#atlt-dialog .atlt-final-message").html(finalHTML+saved_time_html),void $("#atlt-dialog .atlt-ok.button").show()}for(var x=0;x<=Emptytargets.length;x++){var source=Emptytargets[x];jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter((function(index){return jQuery(this).text()==source})).addClass("po-unsaved")}if(0==window.locoEditorStats.dataObj.textToTranslateArr.length)return data.thisBtn.val("Translated").attr("disabled","true"),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Translated - SAVE NOW").attr("disabled","disabled"),$("#atlt-dialog .atlt-final-message").html(finalHTML+saved_time_html),void $("#atlt-dialog .atlt-ok.button").show();jQuery(document).trigger("atlt_run_translation")}else data.thisBtn.hide("slow"),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Translation").attr("disabled","disabled"),$("#atlt-dialog .atlt-ok.button").show(),alert("Unable to make request to the server at the moment. Try again later.")})).fail((function(jqXHR){console.log(jqXHR),500!=jqXHR.status&&0!=jqXHR.status||(data.thisBtn.hide("slow"),$("#atlt_preloader").hide(),$("#cool-auto-translate-btn").text("Translation").attr("disabled","disabled"),$("#atlt-dialog .atlt-ok.button").show(),alert("Unable to make request to the server at the moment. Try again later."))}))}function filterSavedStrings(rawArray){return filterdArr=rawArray.filter((item,index)=>{if(""!=item.target&&void 0!==item.source&&""!=item.source)return!0})}function filterRawObject(rawArray,filterType){return filterdArr=[],filterdArr=rawArray.filter((item,index)=>{if(""!==item.source&&void 0!==item.source&&(void 0===item.target||""==item.target))return!ValidURL(item.source)&&("html"==filterType?!!isHTML(item.source)||!(!isAllowedChars(item.source)||0!=isPlacehodersChars(item.source)):!isHTML(item.source)&&(!!isPlacehodersChars(item.source)||!isSpecialChars(item.source)&&!item.source.includes("#")))})}function addAutoTranslationBtn(){$("#loco-toolbar").find("#cool-auto-translate-btn").length>0&&$("#loco-toolbar").find("#cool-auto-translate-btn").remove();const locoActions=$("#loco-toolbar").find("#loco-actions"),otherBtn='<button class="button has-icon icon-warn" id="atlt_reset_all">Reset Translations</button></fieldset>',allTranslated='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate" disabled>Translated</button></fieldset>';let savedStrings=filterSavedStrings(conf.podata),plainStrings=filterRawObject(conf.podata,"plain"),htmlStrings=filterRawObject(conf.podata,"html");const userType=ATLT.info.type;if(Array.isArray(plainStrings)&&plainStrings.length||Array.isArray(htmlStrings)&&htmlStrings.length){const inActiveBtn='<fieldset><button title="Add API key to enable this feature." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button> <a style="font-size:9px;display:block;margin-left:8px;" target="_blank" href="https://www.ibm.com/in-en/cloud/watson-language-translator/pricing">Get Free API Key</a></fieldset>',disabledBtn='<fieldset><button title="Buy PRO." id="cool-auto-translate-btn" disabled class="button has-icon icon-translate">Auto Translate</button><div style="max-width:320px; display:inline-block;margin-top: 4px;"><span style="font-size:12px;display:inline-block;margin-left:8px;">You have exceeded free translation limit. In order to extend the limit - <a target="_blank" style="font-size:14px;display:inline-block;margin-left:8px;" target="_blank" href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing">Buy Premium License</a></span></div></fieldset>',apiKey=ATLT.api_key.yApiKey,proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>',allowed=ATLT.info.allowed,today=ATLT.info.today,total=ATLT.info.total,aTodayChars=3e5,aTodayChar=1e6;if(null==ATLT||""==ATLT.api_key){if("free"==userType)return void locoActions.append(inActiveBtn);locoActions.append(proActiveBtn)}else if(""==ATLT.api_key.yApiKey&&""==ATLT.api_key.ibmApiKey){if("free"==userType)return void locoActions.append(inActiveBtn);locoActions.append(proActiveBtn)}else{if("no"==allowed&&"free"==userType)return void locoActions.append(disabledBtn);if(void 0!==today&&parseInt(today)>aTodayChars&&"free"==userType)return void locoActions.append(disabledBtn);if(void 0!==total&&parseInt(total)>aTodayChar&&"free"==userType)return void locoActions.append(disabledBtn);if("100%"!=window.locoEditorStats.totalTranslated&&window.locoEditorStats.totalWords>0)if("pro"==userType&&null!=ATLT.info.licenseKey&&validLicenseKey(ATLT.info.licenseKey))locoActions.append(proActiveBtn);else{if(null==today)var todayChars=aTodayChars;else var todayChars=aTodayChars-parseInt(today);var totalChars,freeBtn='<fieldset><button data-today-limit="'+todayChars+'" data-total-limit="'+(aTodayChar-parseInt(total))+'" id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';locoActions.append(freeBtn)}else if(0==window.locoEditorStats.totalWords)return}}else locoActions.append(allTranslated);Array.isArray(savedStrings)&&savedStrings.length&&"pro"==userType&&null!=ATLT.info.licenseKey&&validLicenseKey(ATLT.info.licenseKey)&&"yes"==ATLT.info.proInstalled&&locoActions.append(otherBtn)}function markUnsavedString(){const unSavedString=JSON.parse(localStorage.getItem("unSavedString"));for(var x=0;x<=unSavedString.length;x++){var source=unSavedString[x];jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter((function(index){return jQuery(this).text()==source})).addClass("po-unsaved")}}function ValidURL(str){var pattern;return!!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(str)}function isHTML(str){var rgex;return void 0!==str&&/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i.test(str)}function isSpecialChars(str){var rgex;return void 0!==str&&/[@#^$%&*{}|<>]/g.test(str)}function isAllowedChars(str){var rgex;return void 0!==str&&/[!@#$%^&*(),?":|<>]/g.test(str)}function isPlacehodersChars(str){var rgex;return void 0!==str&&/%s|%d/g.test(str)}function isContainChars(str){var rgex;return void 0!==str&&/[{}[]/g.test(str)}function atltFormatNumber(num){return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,")}function createSettingsPopup(){let preloaderImg=extradata.preloader_path,gtPreviewImg=extradata.gt_preview;const userInfo=ATLT.info.type,yAC=ATLT.info.yAvailableChars,iAC=ATLT.info.iAvailableChars,licenseKey=ATLT.info.licenseKey,proInstalled=ATLT.info.proInstalled;let yfieldStatus="",ifieldStatus="",gfieldStatus="",mfieldStatus="",hfieldStatus="",htmlSupported="",contCls="",icontCls="",proLbl="",gContCls="",gHtml="",mContCls="",mHtml="",submitBtn="",yHtml="",iHtml="",yChecked='"',iChecked='checked="true"';if("free"==userInfo){let gAC=0;gfieldStatus="disabled",mfieldStatus="disabled",hfieldStatus="disabled",contCls="html-disabled",gContCls="g-disabled",mContCls="m-disabled",proLbl='<span class="atlt-pro-feature"><a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank" style="color:red;font-weight:bold;font-size:0.9em;" title="Only For Pro Users">PRO Only</a></span>',gHtml=proLbl+" ",mHtml=proLbl+" "}else if("no"==proInstalled)gfieldStatus="disabled",mfieldStatus="disabled",hfieldStatus="disabled",contCls="html-disabled",gContCls="g-disabled",mContCls="m-disabled",proLbl='<span style="color:red;font-weight:bold;font-size:0.9em;" class="atlt-pro-feature">Please Install PRO version</span>',gHtml=proLbl+" ",mHtml=proLbl+" ";else if(null!=ATLT.info.licenseKey&&validLicenseKey(ATLT.info.licenseKey)){if(""!=ATLT.api_key.gApiKey){let gAC=ATLT.info.gAvailableChars;void 0!==gAC&&gAC>1e4?gHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(gAC)+" Free Char. Available This Month)</span>":gAC<1e4&&(gHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>')}else gfieldStatus="disabled",gContCls="g-disabled",gHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Google Translate API key)</span>';null!=ATLT.api_key.mApiKey&&""!=ATLT.api_key.mApiKey?(mAC=ATLT.info.mAvailableChars,void 0!==mAC&&mAC>1e4?mHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(mAC)+" Free Char. Available This Month)</span>":mAC<1e4&&(mHtml='<span class="used-chars" style="font-weight:bold;font-size:0.9em;">(You have consumed all free characters.)</span>')):(mfieldStatus="disabled",mContCls="m-disabled",mHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Microsoft Translator API key)</span>')}""!=ATLT.api_key.yApiKey?void 0!==yAC&&(yHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(yAC)+" Free Char. Available Monthly)</span>"):(yfieldStatus="disabled",yContCls="g-disabled",yChecked="",yHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter Yandex Translate API v1 key)</span>'),""==ATLT.api_key.ibmApiKey||""==ATLT.info.ibm_url?(ifieldStatus="disabled",iContCls="g-disabled",iChecked="",iHtml='<span class="error" style="color:red;font-size:0.85em;">(Please enter IBM Translate API key/URL)</span>'):void 0!==iAC&&(iHtml='<span class="available-chars" style="font-weight:bold;font-size:0.9em;"> ('+atltFormatNumber(iAC)+" Free Char. Available Monthly)</span>"),plainStringLbl="free"==userInfo?"Translate Plain Text Strings(No HTML/Special character supported)":"Translate Plain Text Strings",submitBtn=""!=ATLT.api_key.yApiKey||""!=ATLT.api_key.gApiKey||""!=ATLT.api_key.mApiKey||""!=ATLT.api_key.ibmApiKey?'<input type="submit" class="button has-icon icon-translate" value="Start Translation" id="cool-auto-translate-start">':'<button class="atlt-ok button button-primary">OK</button>';let settingsHTML,popup_html=`<div id="atlt-dialog-container">\n <div style="display:none;" id="atlt-dialog" title="Automatic Translation Progress">\n ${`<div class="atlt-settings">\n <strong class="atlt-heading" style="margin-bottom:10px;display:inline-block;">Translate Using Google Page Translate Button<br/>(No API Key Required + Unlimited Translations!)</strong>\n <div class="inputGroup">\n <button id="atlt_gtranslate_btn" disabled="true" class="notranslate button button-primary">Google Translate</button>\n <br/><img src="${gtPreviewImg}" alt="google translate widget preview"><br/>\n ${proLbl}\n ✅ Available Inside Pro Version 1.1<br/><span style="font-size:11px;font-weight:bold;">(Release date:- 27 June, 2020)</span>\n </div>\n <hr/>\n <div class="atlt-settings">\n <form id="atlt-settings-form" method="post" action="#">\n <strong class="atlt-heading" style="margin:15px 0 10px;display:inline-block;">Translate Using A Translate API</strong>\n <div class="inputGroup">\n <input class="inputEle" type="radio" id="ibm_api" \n ${iChecked} ${ifieldStatus} name="api_type" value="ibm">\n <label for="ibm_api">IBM Translate ${iHtml}</label>\n </div>\n <div class="inputGroup">\n <input class="inputEle" type="radio" id="yandex_api" \n ${yChecked} ${yfieldStatus} name="api_type" value="yandex">\n <label for="yandex_api">Yandex Translate ${yHtml}</label>\n </div>\n \n <div class="inputGroup ${gContCls}">\n <input class="inputEle" type="radio" id="google_api" \n name="api_type" value="google" ${gfieldStatus}>\n <label for="google_api">Google Translate ${gHtml}</label>\n </div>\n <div class="inputGroup ${mContCls}">\n <input class="inputEle" type="radio" id="microsoft_api" \n name="api_type" value="microsoft" ${mfieldStatus}>\n <label for="microsoft_api">Microsoft Translator ${mHtml}</label>\n <br/>\n <small style="display:inline-block;margin-left:24px;margin-top:8px;font-weight:bold;">(<a href="https://locoaddon.com/supported-languages/" target="_blank">View all supported languages list</a>)</small>\n </div>\n <br/>\n <fieldset>\n ${submitBtn}\n <img style="display:none;margin-left:10px;margin-top:-3px;" id="atlt_preloader" src="${preloaderImg}">\n </fieldset>\n </form>\n </div>`}\n <p><span class="translated-label">Translated</span>\n <span class="translated-text">0%</span></p>\n <div class="atlt-progress-bar-track">\n <div class="atlt-progress-bar-value">\n </div></div>\n <div class="atlt-final-message"></div>\n <button style="display:none;" class="atlt-ok button button-primary">OK</button>\n </div></div>`;$("body").append(popup_html)}function atlt_ajax_translation_request(data,type){let filteredArr=[];filteredArr=data.textToTranslateArr.map(item=>{if(void 0!==item.source)return item.source});const jsonData=JSON.stringify(filteredArr);return jQuery.ajax({url:ajaxurl,type:"POST",data:{action:data.endpoint,sourceLan:data.sourceLang,targetLan:data.targetLang,totalCharacters:TotalCharacters,requestChars:requestChars,nonce:data.nonce,strType:data.strType,apiType:data.apiType,data:jsonData},done:function(res){}})}template?(buttons.add=editable&&registerAddButton,buttons.del=editable&&registerDelButton):buttons.fuzzy=registerFuzzyButton,$("#loco-toolbar").find("button").each((function(i,el){var id=el.getAttribute("data-loco"),register=buttons[id];register&&register(el,id)||$(el).hide()})),$(elForm).submit(noop),initSearchFilter(document.getElementById("loco-search")),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poUpdate",updateStatus),messages.load(conf.podata),editor.load(messages),(locale=editor.targetLocale)?locale.isRTL()&&$(innerDiv).addClass("trg-rtl"):editor.unlock(),$(document).ready((function(){if(template)return;const locoRawData=conf.podata;function resetTransArr(tranArr,type){var resetStrs=[];return tranArr.map((function(item){if(void 0!==item.source&&void 0!==item.target)return"html"==type&&(isHTML(item.source)?item.target="":isAllowedChars(item.source)&&0==isPlacehodersChars(item.source)&&(item.target="")),"plain"==type&&(1==isPlacehodersChars(item.source)?item.target="":isHTML(item.source)||isAllowedChars(item.source)||(item.target="")),"all"==type&&(item.target=""),item}))}function resetTranslations(type){var resetArr=[];const saveBtn=$('[data-loco="save"]');void 0!==conf.podata&&(resetArr=resetTransArr(conf.podata,"plain"==type?"plain":"html"==type?"html":"all"),(messages=loco.po.init(locale).wrap(conf.powrap)).load(resetArr),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poUpdate",updateStatus),editor.load(messages),saveBtn.addClass("button-primary loco-flagged").removeAttr("disabled"),updateStatus())}null!=locoRawData&&locoRawData.length>0&&addAutoTranslationBtn(),$(document).on("click","#cool-auto-translate-btn",(function(){$("#atlt-dialog").dialog({width:440,height:500})})),$("#typehtmlWrapper").hide(),$("input[name=api_type]").on("click",(function(){"google"==$(this).val()||"microsoft"==$(this).val()||"ibm"==$(this).val()?($("#typehtmlWrapper").hide(),$("#typeplain").attr("checked","checked")):$("#typehtmlWrapper").show()})),$("#atlt_reset_all").on("click",(function(){swal("What type of strings do you want to reset?",{dangerMode:!0,icon:"warning",confirmButtonColor:"#8CD4F5",buttons:{plain:{text:"Plain Text Strings",value:"plain",class:"danger"},html:{text:"HTML Strings",value:"html"},all:{text:"All Strings",value:"all"},cancel:{text:"Cancel",value:null,visible:!0,className:"",closeModal:!1}}}).then(value=>{switch(value){case"all":resetTranslations(value),swal("Done!","You have successfully reset all strings translations. Just close this popup & SAVE!","success");break;case"plain":resetTranslations(value),swal("Done!","You have successfully reset all plain text strings translations. Just close this popup & SAVE!","success");break;case"html":resetTranslations(value),swal("Done!","You have successfully reset all strings with HTML translations. Just close this popup & SAVE!","success");break;default:swal("Cancelled, Just close this popup!")}})})),$("#atlt-settings-form").submit((function(event){event.preventDefault();const user_type=ATLT.info.type;let strType="plain",apiType=$("input[name='api_type']:checked").val(),mainBtn=$("#cool-auto-translate-btn");var thisBtn=$("#cool-auto-translate-start");let sourceApiKey="";var todayLimit=mainBtn.data("today-limit"),totalLimit=mainBtn.data("total-limit");let targetLang="";if("free"==user_type&&"google"==apiType)return alert("Google Translation Only Available in the PRO version"),!1;if("free"==user_type&&"microsoft"==apiType)return alert("Microsoft Translator Only Available in the PRO version"),!1;if((null==user_type||"pro"==user_type)&&null==ATLT.info.licenseKey)return alert("Please enter Your License Key"),!1;if(targetLang=1==conf.locale.lang?conf.locale.lang:getTargetLang(),"google"==apiType?("zh"==targetLang&&(targetLang=targetLang+"-"+conf.locale.region),sourceApiKey=ATLT.api_key.gApiKey):"microsoft"==apiType?("zh"==targetLang&&("CN"==conf.locale.region?targetLang+="-Hans":"TW"==conf.locale.region?targetLang+="-Hant":targetLang=targetLang+"-"+conf.locale.region),sourceApiKey=ATLT.api_key.mApiKey):sourceApiKey="ibm"==apiType?ATLT.api_key.ibmApiKey:ATLT.api_key.yApiKey,null!=locoRawData&&locoRawData.length>0&&""!=sourceApiKey){let plainStrArr=[],htmlStrArr=[],orgStrArr=[];orgStrArr=locoRawData;var countChars=0;if(plainStrArr=filterRawObject(locoRawData,"plain"),null!==plainStrArr&&plainStrArr.map((function(index){countChars+=index.source.length})),null!==htmlStrArr||null!==plainStrArr)if(countChars>parseInt(todayLimit))alert("Your translation string are larger then available free limit.In order to extend limit Buy Pro license key");else{if(0==plainStrArr.length)return $("#atlt-dialog").parent(".ui-dialog").hide(),mainBtn.attr("disabled","disabled"),alert("You have no untranslated plain strings"),void window.location.reload();dataObj={textToTranslateArr:plainStrArr,strType:"plain"},dataObj.orgStrArr=orgStrArr,dataObj.thisBtn=thisBtn,dataObj.apiType=apiType,dataObj.targetLang=targetLang,dataObj.endpoint="google"==apiType||"microsoft"==apiType?"pro_autotranslate_handler":"free_autotranslate_handler",window.locoEditorStats.dataObj=dataObj,jQuery(document).trigger("atlt_run_translation"),thisBtn.val("Translating..."),mainBtn.text("Translating.."),$("#atlt_preloader").show()}}}))})),jQuery(document).on("atlt_run_translation",(function(){let textToTranslate=window.locoEditorStats.dataObj.textToTranslateArr,totalTranslated=window.locoEditorStats.totalTranslated;const nonce=ATLT.nonce,saveBtn=$('[data-loco="save"]'),orignalstringArr=window.locoEditorStats.dataObj.orgStrArr,targetLang=window.locoEditorStats.dataObj.targetLang;let indexRequest=50;if(""!=ATLT.api_key["atlt_index-per-request"]&&void 0!==ATLT.api_key["atlt_index-per-request"]&&(indexRequest=ATLT.api_key["atlt_index-per-request"]),"object"==typeof textToTranslate&&textToTranslate.length>=1){let translationO={textToTranslateArr:textToTranslate.slice(indexRequest),thisBtn:window.locoEditorStats.dataObj.thisBtn,strType:window.locoEditorStats.dataObj.strType,orgStrArr:window.locoEditorStats.dataObj.orgStrArr,apiType:window.locoEditorStats.dataObj.apiType,targetLang:targetLang,endpoint:window.locoEditorStats.dataObj.endpoint};window.locoEditorStats.dataObj=translationO;let data={sourceLang:"en",targetLang:targetLang,textToTranslateArr:textToTranslate.slice(0,indexRequest),orginalArr:orignalstringArr,thisBtn:window.locoEditorStats.dataObj.thisBtn,strType:window.locoEditorStats.dataObj.strType,apiType:window.locoEditorStats.dataObj.apiType,saveBtn:saveBtn,endpoint:window.locoEditorStats.dataObj.endpoint,nonce:nonce};textToTranslate.slice(0,indexRequest).map((function(value,index){TotalCharacters+=value.source.length,requestChars+=value.source.length})),atlt_translate(data)}})),updateStatus()}(window,jQuery);
1
+ !function(window,$){var loco=window.locoScope,conf=window.conf,fileRefs=loco.po.ref.init(loco,conf),syncParams=null,saveParams=null,ajaxUpload=conf.multipart,translator=loco.l10n,sprintf=loco.string.sprintf,locale=conf.locale,messages=loco.po.init(locale).wrap(conf.powrap),template=!locale,elForm=document.getElementById("loco-actions"),filePath=conf.popath,syncPath=conf.potpath,elFilesys=document.getElementById("loco-fs"),fsConnect=elFilesys&&loco.fs.init(elFilesys),readonly,editable=!conf.readonly,editor,saveButton,innerDiv=document.getElementById("loco-editor-inner"),translationClients,translationApiKeys=conf.apis||[],suggestionCache={},$suggestModal,$translateModal;function doSyncAction(callback){function onSuccess(result){var info=[],doc=messages,exp=result.po,src=result.pot,pot=loco.po.init().load(exp),done=doc.merge(pot),nadd=done.add.length,ndel=done.del.length,t=translator;editor.load(doc),nadd||ndel?(src?info.push(sprintf(t._("Merged from %s"),src)):info.push(t._("Merged from source code")),nadd&&info.push(sprintf(t._n("1 new string added","%s new strings added",nadd),nadd)),ndel&&info.push(sprintf(t._n("1 obsolete string removed","%s obsolete strings removed",ndel),ndel)),$(innerDiv).trigger("poUnsaved",[]),updateStatus(),window.console&&debugMerge(console,done)):src?info.push(sprintf(t._("Already up to date with %s"),src)):info.push(t._("Already up to date with source code")),loco.notices.success(info.join(". ")),$(innerDiv).trigger("poMerge",[result]),callback&&callback()}loco.ajax.post("sync",syncParams,onSuccess,callback)}function debugMerge(console,result){for(var i=-1,t=result.add.length;++i<t;)console.log(" + "+result.add[i].source());for(i=-1,t=result.del.length;++i<t;)console.log(" - "+result.del[i].source())}function createTranslationClients(){for(var i=-1,info,clients=[],keys=translationApiKeys,num=keys.length;++i<num;)try{info=keys[i],clients.push(loco.apis.create(info))}catch(Er){loco.notices.error(String(Er))}return clients}function getTranslationClients(){return translationClients||(translationClients=createTranslationClients())}function getTranslationClient(id){for(var client,clients=getTranslationClients(),num=clients.length,i=-1;++i<num;)if((client=clients[i]).getId()===id)return client;loco.notices.error("No "+id+" client")}function onHintEvent(){translationApiKeys.length?loadSuggestions():loadUnconfiguredApis()}function getTranslationModal(){return $translateModal||($translateModal=$("#loco-auto")).dialog({dialogClass:"loco-modal",appendTo:"#loco.wrap",title:$translateModal.attr("title"),modal:!0,closeOnEscape:!0,resizable:!1,position:{my:"top",at:"top",of:"#loco-content"}}),$translateModal}function loadUnconfiguredApis(){getTranslationModal().dialog("open")}function initAutoTranslate(){var job,credit,translated=0,t=translator,flagFuzzy=!1,$modal=getTranslationModal().dialog("open"),$form=$modal.find("form"),$butt=$form.find("button.button-primary"),$stat=$("#loco-job-progress");function enable(){$butt[0].disabled=!1}function disable(){$butt[0].disabled=!0}function think(){$butt.addClass("loco-loading")}function unthink(){$butt.removeClass("loco-loading")}function showStatus(message){$stat.text(message)}function refreshJob(elForm){var apiId,client=getTranslationClient($(elForm.api).val()),overwrite=elForm.existing.checked;showStatus("Calculating...."),(job=client.createJob()).init(messages,overwrite),credit=client.toString(),showStatus(sprintf(t._("%s unique source strings."),job.length.format(0))+" "+sprintf(t._("%s characters will be sent for translation."),job.chars.format(0))),job.length?enable():disable()}function onJobChange(event){var elField=event.target,f=elField.name;return"api"!==f&&"existing"!==f||refreshJob(elField.form),!0}function onJobDispatch(event){event.preventDefault(),think(),disable(),onProgress(0),flagFuzzy=event.target.fuzzy.checked,job.dispatch().done(onJobComplete).each(onEachTranslatedMessage).prog(onProgress)}function onEachTranslatedMessage(message){job&&(flagFuzzy&&message.fuzzy(0,!0),editor.pasteMessage(message),message===editor.active&&editor.setStatus(message),editor.unsave(message,0),translated++)}function onProgress(didBatches,numBatches){var percent=numBatches?100*didBatches/numBatches:0;showStatus(sprintf(t._("Translation progress %s%%"),percent.format(0)))}function onJobComplete(){if(unthink(),job){var remaining=job.length-translated;remaining>0&&translated&&loco.notices.warn(sprintf(t._("Translation job aborted with %s strings remaining"),remaining.format(0))),translated>0&&(loco.notices.success(sprintf(t._("%s strings translated via "+credit),translated.format(0))).stick(),updateStatus(),editor.rebuildSearch()),job=null,editor.fire("poAbort")}$modal&&($modal.off("dialogclose").dialog("close"),$modal=null)}function onCloseModal(){job.abort(),$modal=null,onJobComplete()}unthink(),disable(),$form.off("submit change"),refreshJob($form[0]),$form.on("change",onJobChange).on("submit",onJobDispatch),$modal.off("dialogclose").on("dialogclose",onCloseModal)}function loadSuggestions(){var t=translator,message=editor.current(),index=editor.getTargetOffset(),source=message&&message.source(null,index),langAtts='lang="'+String(locale)+'" dir="'+(locale.isRTL()?"RTL":"LTR")+'"';if(source){function createSuggestionClosure(source,target){return function(event){event.preventDefault(),event.stopPropagation(),destroyScope();var message=editor.current(),index=editor.getTargetOffset();message&&message.source(null,index)===source?(message.translate(target,index),editor.focus().reloadMessage(message)):loco.notices.warn("Source changed since suggestion")}}function completeSuggestion(source,target,locale,client){var id=client.getId(),href=client.getUrl(),name=String(client),$div=placeholders&&placeholders[id];$div&&$div.replaceWith($('<div class="loco-api loco-api-'+id+'"></div>').append($('<a class="loco-api-credit" target="_blank"></a>').attr("href",href).text(name)).append($("<blockquote "+langAtts+"></blockquote>").text(target||"[FAILED]")).append($('<button class="button button-primary"></button>').text(t._("Use this translation")).on("click",createSuggestionClosure(source,target)))),$modal.dialog("option","position",{my:"center",at:"center",of:window}),++loaded===length&&$modal&&$modal.dialog("option","title",t._("Suggested translations")+" — "+locale.label)}function initSuggestion(client){var $div=$('<div class="loco-api loco-api-loading"></div>').text("Calling "+client+" ...");return placeholders[client.getId()]=$div,$div}function destroyScope(closeEvent){$modal&&null==closeEvent&&$modal.dialog("close"),$modal=null,placeholders=null}function createCallbackClosure(client){return function(source,target,locale){cached[client.getId()]=target,completeSuggestion(source,target,locale,client)}}function getModal(){return $suggestModal||($suggestModal=$('<div id="loco-hint"></div>').dialog({dialogClass:"loco-modal",modal:!0,autoOpen:!1,closeOnEscape:!0,resizable:!1,minHeight:400}))}var $modal=getModal().html("").append($('<div class="loco-api"><p>Source text:</p></div>').append($('<blockquote lang="en"></blockquote>').text(source))).dialog("option","title",t._("Loading suggestions")+"...").off("dialogclose").on("dialogclose",destroyScope).dialog("open"),target=message.translation(index);target&&$('<div class="loco-api"><p>Current translation:</p></div>').append($("<blockquote "+langAtts+"></blockquote>").text(target)).append($('<button class="button"></button>').text(t._("Keep this translation")).on("click",(function(event){event.preventDefault(),destroyScope()}))).appendTo($modal);for(var client,clientId,clients=getTranslationClients(),length=clients.length,i=-1,cached=suggestionCache[source]||(suggestionCache[source]={}),placeholders={},loaded=0;++i<length;)client=clients[i],$modal.append(initSuggestion(client)),clientId=client.getId(),cached[clientId]?completeSuggestion(source,cached[clientId],locale,client):client.translate(source,locale,createCallbackClosure(client))}}function onMetaClick(event,target){function tryTag(node,name){return node.tagName===name?node:node.getElementsByTagName(name)[0]}var codeEl=tryTag(target,"CODE");codeEl&&fileRefs.load(codeEl.textContent)}function initMultiPart(params){var p,data=new FormData;for(p in params)params.hasOwnProperty(p)&&data.append(p,params[p]);return data}function doSaveAction(callback){function onSuccess(result){callback&&callback(),editor.save(!0),$("#loco-po-modified").text(result.datetime||"[datetime error]")}var postData=$.extend({locale:String(messages.locale()||"")},saveParams||{});fsConnect&&fsConnect.applyCreds(postData),ajaxUpload?(postData=initMultiPart(postData)).append("po",new Blob([String(messages)],{type:"application/x-gettext"}),String(postData.path).split("/").pop()||"untitled.po"):postData.data=String(messages),loco.ajax.post("save",postData,onSuccess,callback)}function saveIfDirty(){editor.dirty&&doSaveAction()}function onUnloadWarning(){return translator._("Your changes will be lost if you continue without saving")}function registerSaveButton(button){function disable(){button.disabled=!0}function enable(){button.disabled=!1}function think(){disable(),$(button).addClass("loco-loading")}function unthink(){enable(),$(button).removeClass("loco-loading")}return saveButton=button,editor.on("poUnsaved",(function(){enable(),$(button).addClass("button-primary loco-flagged")})).on("poSave",(function(){disable(),$(button).removeClass("button-primary loco-flagged")})),saveParams=$.extend({path:filePath},conf.project||{}),$(button).click((function(event){return event.preventDefault(),think(),doSaveAction(unthink),!1})),!0}function registerSyncButton(button){var project=conf.project;if(project){function disable(){button.disabled=!0}function enable(){button.disabled=!1}function think(){disable(),$(button).addClass("loco-loading")}function unthink(){enable(),$(button).removeClass("loco-loading")}editor.on("poUnsaved",(function(){disable()})).on("poSave",(function(){enable()})),syncParams={bundle:project.bundle,domain:project.domain,type:template?"pot":"po",sync:syncPath||""},$(button).click((function(event){return event.preventDefault(),think(),doSyncAction(unthink),!1})),enable()}return!0}function registerAutoTranslateButton(button){function disable(){button.disabled=!0}function enable(){button.disabled=!1}return editor.on("poUnsaved",(function(){disable()})).on("poSave poAbort",(function(){enable()})),$(button).click((function(event){return event.preventDefault(),initAutoTranslate(),!1})),enable(),!0}function registerRevertButton(button){return editor.on("poUnsaved",(function(){button.disabled=!1})).on("poSave",(function(){button.disabled=!0})),$(button).click((function(event){return event.preventDefault(),location.reload(),!1})),!0}function registerInvisiblesButton(button){var $button=$(button);return button.disabled=!1,editor.on("poInvs",(function(event,state){$button[state?"addClass":"removeClass"]("inverted")})),$button.click((function(event){return event.preventDefault(),editor.setInvs(!editor.getInvs()),!1})),locoScope.tooltip.init($button),!0}function registerCodeviewButton(button){var $button=$(button);return button.disabled=!1,$button.click((function(event){event.preventDefault();var state=!editor.getMono();return $button[state?"addClass":"removeClass"]("inverted"),editor.setMono(state),!1})),locoScope.tooltip.init($button),!0}function registerAddButton(button){return button.disabled=!1,$(button).click((function(event){event.preventDefault();var i=1,baseid,msgid,regex=/(\d+)$/;for(msgid=baseid="New message";messages.get(msgid);)i=regex.exec(msgid)?Math.max(i,RegExp.$1):i,msgid=baseid+" "+ ++i;return editor.add(msgid),!1})),!0}function registerDelButton(button){return button.disabled=!1,$(button).click((function(event){return event.preventDefault(),editor.del(),!1})),!0}function registerDownloadButton(button,id){return button.disabled=!1,$(button).click((function(event){var form=button.form,path=filePath;return"binary"===id&&(path=path.replace(/\.po$/,".mo")),form.path.value=path,form.source.value=messages.toString(),!0})),!0}function noop(event){return event.preventDefault(),!1}function updateStatus(){var t=translator,stats=editor.stats(),total=stats.t,fuzzy=stats.f,empty=stats.u,stext=sprintf(t._n("1 string","%s strings",total),total.format(0)),extra=[];locale&&(stext=sprintf(t._("%s%% translated"),stats.p.replace("%",""))+", "+stext,fuzzy&&extra.push(sprintf(t._("%s fuzzy"),fuzzy.format(0))),empty&&extra.push(sprintf(t._("%s untranslated"),empty.format(0))),extra.length&&(stext+=" ("+extra.join(", ")+")")),$("#loco-po-status").text(stext)}function initSearchFilter(elSearch){function showValidFilter(numFound){$(elSearch.parentNode)[numFound||null==numFound?"removeClass":"addClass"]("invalid")}editor.searchable(loco.fulltext.init()),elSearch.disabled=!1,elSearch.value="";var listener=loco.watchtext(elSearch,(function(value){var numFound;showValidFilter(editor.filter(value,!0))}));editor.on("poFilter",(function(event,value,numFound){listener.val(value||""),showValidFilter(numFound)})).on("poMerge",(function(event,result){var value=listener.val();value&&editor.filter(value)}))}!ajaxUpload||window.FormData&&window.Blob||(ajaxUpload=!1,loco.notices.warn("Your browser doesn't support Ajax file uploads. Falling back to standard postdata"));var resize=function(){function top(el,ancestor){for(var y=el.offsetTop||0;(el=el.offsetParent)&&el!==ancestor;)y+=el.offsetTop||0;return y}var fixHeight,minHeight=parseInt($(innerDiv).css("min-height")||0);return function(){var padBottom=20,topBanner=top(innerDiv,document.body),winHeight=window.innerHeight,setHeight=Math.max(minHeight,winHeight-topBanner-20);fixHeight!==setHeight&&(innerDiv.style.height=String(setHeight)+"px",fixHeight=setHeight)}}();resize(),$(window).resize(resize),innerDiv.innerHTML="",editor=loco.po.ed.init(innerDiv).localise(translator),loco.po.kbd.init(editor).add("save",saveIfDirty).add("hint",locale&&editable&&onHintEvent||noop).enable("copy","clear","enter","next","prev","fuzzy","save","invis","hint");var buttons={save:editable&&registerSaveButton,sync:editable&&registerSyncButton,revert:registerRevertButton,invs:registerInvisiblesButton,code:registerCodeviewButton,source:registerDownloadButton,binary:template?null:registerDownloadButton};function newaddAutoTranslationBtn(){$("#loco-toolbar").find("#cool-auto-translate-btn").length>0&&$("#loco-toolbar").find("#cool-auto-translate-btn").remove();const locoActions=$("#loco-toolbar").find("#loco-actions"),otherBtn='<button class="button has-icon icon-warn" id="atlt_reset_all">Reset Translations</button></fieldset>',allTranslated='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate" disabled>Translated</button></fieldset>',proActiveBtn='<fieldset><button id="cool-auto-translate-btn" class="button has-icon icon-translate">Auto Translate</button></fieldset>';locoActions.append(proActiveBtn)}function createPopup(){$("#atlt-dialog").dialog({resizable:!1,height:"auto",width:400,modal:!0,buttons:{Cancel:function(){$(this).dialog("close")}}})}function printStringsInPopup(jsonObj,type){var html="",totalTChars=0,index=1;if(jsonObj){for(const key in jsonObj)if(jsonObj.hasOwnProperty(key)){const element=jsonObj[key];if(""!=element.source){if("yandex"==type)html+='<tr id="'+key+'" ><td>'+index+'</td><td class="notranslate source">'+element.source+"</td>";else{if(key>2500)break;html+='<tr id="'+key+'" ><td>'+index+'</td><td class="notranslate source">'+element.source+"</td>"}html+="yandex"==type?'<td translate="yes" class="target translate">'+element.source+"</td></tr>":'<td class="target translate"></td></tr>',index++,totalTChars+=element.source.length}}$(".ytstats").each((function(){$(this).find(".totalChars").html(totalTChars)}))}"yandex"==type&&$("#yandex_string_tbl").append(html)}template?(buttons.add=editable&&registerAddButton,buttons.del=editable&&registerDelButton):buttons.auto=registerAutoTranslateButton,$("#loco-toolbar").find("button").each((function(i,el){var id=el.getAttribute("data-loco"),register=buttons[id];register&&register(el,id)||$(el).hide()})),$(elForm).submit(noop),initSearchFilter(document.getElementById("loco-search")),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poHint",onHintEvent).on("poUpdate",updateStatus).on("poMeta",onMetaClick),messages.load(conf.podata),editor.load(messages),(locale=editor.targetLocale)?locale.isRTL()&&$(innerDiv).addClass("trg-rtl"):editor.unlock(),updateStatus(),newaddAutoTranslationBtn(),$("#cool-auto-translate-btn").on("click",(function(){createPopup()})),$("#atlt_yandex_transate_btn").on("click",(function(){var defaultcode=window.conf.locale.lang?window.conf.locale.lang:null,arr;switch(defaultcode){case"bel":defaultlang="be";break;case"he":defaultlang="iw";break;case"snd":defaultlang="sd";break;case"jv":defaultlang="jw";break;default:defaultlang=defaultcode}$(".save_it").prop("disabled",!0),$(".ytstats").hide(),localStorage.setItem("lang",defaultlang),["af","am","ar","az","ba","be","bg","bn","bs","ca","ceb","cs","cy","da","de","el","en","eo","es","et","eu","fa","fi","fr","ga","gd","gl","gu","he","hi","hr","ht","hu","hy","id","is","it","ja","jv","ka","kk","km","kn","ko","ky","la","lb","lo","lt","lv","mg","mhr","mi","mk","ml","mn","mr","mrj","ms","mt","my","ne","nl","no","pa","pap","pl","pt","ro","ru","si","sk","sl","sq","sr","su","sv","sw","ta","te","tg","th","tl","tr","tt","udm","uk","ur","uz","vi","xh","yi","zhCN"].includes(defaultlang)||($(".string_container").after("<strong>Yandex Automatic Translator Does not support this language.</strong>"),$(".string_container").hide(),$(".save_it").hide(),$("#ytWidget").hide());var plainStrArr=filterRawObject(conf.podata,"plain");plainStrArr.length>0?printStringsInPopup(plainStrArr,type="yandex"):($("#ytWidget").hide(),$(".string_container").after("<strong>There is no plain string available for translations.</strong>"),$(".string_container").hide(),$(".save_it").hide()),$("#atlt-dialog").dialog("close"),$("#atlt_strings_model").addClass("yandex-translator").fadeIn("slow")}));var rpl={'"% s"':'"%s"','"% d"':'"%d"','"% S"':'"%s"','"% D"':'"%d"',"% s":" %s ","% S":" %s ","% d":" %d ","% D":" %d ","٪ s":" %s ","٪ S":" %s ","٪ d":" %d ","٪ D":" %d ","٪ س":" %s "},translatedObj=[];function markUnsavedString(){const unSavedString=JSON.parse(localStorage.getItem("unSavedString"));for(var x=0;x<=unSavedString.length;x++){var source=unSavedString[x];jQuery("#po-list-tbody div[for='po-list-col-source'] div").filter((function(index){return jQuery(this).text()==source})).addClass("po-unsaved")}}function saveTranslatedStrings(translatedObj){var plainStrArr=filterRawObject(conf.podata,"plain");const saveBtn=$('[data-loco="save"]');if(void 0!==translatedObj&&translatedObj.length)for(i=0;i<translatedObj.length;i++){var text=translatedObj[i];if(void 0===plainStrArr[i])break;plainStrArr[i].target=strtr(text,rpl)}(messages=loco.po.init(locale).wrap(conf.powrap)).load(conf.podata),markUnsaved(plainStrArr),editor.on("poUnsaved",(function(){window.onbeforeunload=onUnloadWarning})).on("poSave",(function(){updateStatus(),window.onbeforeunload=null})).on("poUpdate",updateStatus),editor.load(messages),saveBtn.addClass("button-primary loco-flagged").removeAttr("disabled"),updateStatus()}function strtr(s,p,r){return!!s&&{2:function(){for(var i in p)s=strtr(s,i,p[i]);return s},3:function(){return s.replace(RegExp(p,"g"),r)},0:function(){}}[arguments.length]()}function filterRawObject(rawArray,filterType){return filterdArr=[],filterdArr=rawArray.filter((item,index)=>{if(""!==item.source&&void 0!==item.source&&(void 0===item.target||""==item.target))return!ValidURL(item.source)&&(!isHTML(item.source)&&(!!isPlacehodersChars(item.source)||!isSpecialChars(item.source)&&!item.source.includes("#")))})}function ValidURL(str){var pattern;return!!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(str)}function isHTML(str){var rgex;return void 0!==str&&/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i.test(str)}function isSpecialChars(str){var rgex;return void 0!==str&&/[@#^$%&*{}|<>]/g.test(str)}function isAllowedChars(str){var rgex;return void 0!==str&&/[!@#$%^&*(),?":|<>]/g.test(str)}function isPlacehodersChars(str){var rgex;return void 0!==str&&/%s|%d/g.test(str)}function isContainChars(str){var rgex;return void 0!==str&&/[{}[]/g.test(str)}function markUnsaved(data){for(const key in data)if(data.hasOwnProperty(key)){let element=data[key].message;if(""==data[key].source)continue;editor.pasteMessage(element),element===editor.active&&editor.setStatus(element),editor.unsave(element,0)}}function atltFormatNumber(num){return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,")}$(".save_it").on("click",(function(){$("#stringTemplate tbody tr").each((function(index){var string=$(this).find("td.target").text();translatedObj.push(string)})),saveTranslatedStrings(translatedObj),$(".atlt_custom_model").fadeOut("slow")}))}(window,jQuery);
assets/js/widget.js ADDED
@@ -0,0 +1,442 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ (function ($,win, doc, nav, params, namespace, undefined) {
3
+ 'use strict';
4
+
5
+ var util = {
6
+ keycode: {
7
+ ESCAPE: 27
8
+ },
9
+ getRequest: function () {
10
+ if (win.XDomainRequest) {
11
+ return new win.XDomainRequest();
12
+ }
13
+ if (win.XMLHttpRequest) {
14
+ return new win.XMLHttpRequest();
15
+ }
16
+ return null;
17
+ },
18
+ loadScript: function (src, parent, callback) {
19
+ var script = doc.createElement('script');
20
+ script.src = src;
21
+
22
+ script.addEventListener('load', function onLoad() {
23
+ this.removeEventListener('load', onLoad, false);
24
+ callback();
25
+ }, false);
26
+
27
+ parent.appendChild(script);
28
+ },
29
+ loadResource: function (url, callback) {
30
+ var request = this.getRequest();
31
+
32
+ if (!request) {
33
+ return null;
34
+ }
35
+
36
+ request.onload = function () {
37
+ callback(this.responseText);
38
+ };
39
+ request.open('GET', url, true);
40
+
41
+ win.setTimeout(function () {
42
+ request.send();
43
+ }, 0);
44
+
45
+ return request;
46
+ },
47
+ getStyleList: function (element) {
48
+ var value = element.getAttribute('class');
49
+ if (!value) {
50
+ return [];
51
+ }
52
+ return value.replace(/\s+/g, ' ').trim().split(' ');
53
+ },
54
+ hasStyleName: function (element, name) {
55
+ var list = this.getStyleList(element);
56
+ return !!list.length && list.indexOf(name) >= 0;
57
+ },
58
+ addStyleName: function (element, name) {
59
+ var list = this.getStyleList(element);
60
+ list.push(name);
61
+ element.setAttribute('class', list.join(' '));
62
+ },
63
+ removeStyleName: function (element, name) {
64
+ var list = this.getStyleList(element), index = list.indexOf(name);
65
+ if (index >= 0) {
66
+ list.splice(index, 1);
67
+ element.setAttribute('class', list.join(' '));
68
+ }
69
+ },
70
+ isSupportedBrowser: function () {
71
+ return 'localStorage' in win &&
72
+ 'querySelector' in doc &&
73
+ 'addEventListener' in win &&
74
+ 'getComputedStyle' in win && doc.compatMode === 'CSS1Compat';
75
+ }
76
+ };
77
+
78
+ // Button
79
+
80
+ var Button = function Button(element, contentElement) {
81
+ var self = this;
82
+
83
+ element.addEventListener('click', function (event) {
84
+ self.onClick(event);
85
+ }, false);
86
+
87
+ this._element = element;
88
+ this._contentElement = contentElement || this._element;
89
+ };
90
+
91
+ Button.prototype.onClick = function () {};
92
+
93
+ Button.prototype.setText = function (text) {
94
+ this._contentElement.textContent = text;
95
+ return this;
96
+ };
97
+
98
+ // Select
99
+
100
+ var Select = function Select(form, itemName) {
101
+ var self = this;
102
+
103
+ form.reset();
104
+
105
+ form.addEventListener('click', function (event) {
106
+ var target = event.target;
107
+ if ('value' in target) {
108
+ self.onSelect(target.value);
109
+ }
110
+ }, false);
111
+
112
+ form.addEventListener('change', function (event) {
113
+ var target = event.target;
114
+ if (target.checked) {
115
+ self.onChange(target.value);
116
+ }
117
+ }, false);
118
+
119
+ this._form = form;
120
+ this._itemName = itemName;
121
+ };
122
+
123
+ Select.prototype.onSelect = function () {};
124
+
125
+ Select.prototype.onChange = function () {};
126
+
127
+ Select.prototype.isHidden = function () {
128
+ return this._form.hasAttribute('hidden');
129
+ };
130
+
131
+ Select.prototype.getItems = function () {
132
+ return this._form[this._itemName] || [];
133
+ };
134
+
135
+ Select.prototype.getValue = function () {
136
+ var i, n, items = this.getItems();
137
+ for (i = 0, n = items.length; i < n; i++) {
138
+ if (items[i].checked) {
139
+ return items[i].value;
140
+ }
141
+ }
142
+ return '';
143
+ };
144
+
145
+ Select.prototype.setValue = function (value) {
146
+ var i, n, items = this.getItems();
147
+ if (value === this.getValue()) {
148
+ return this;
149
+ }
150
+ for (i = 0, n = items.length; i < n; i++) {
151
+ if (items[i].value === value) {
152
+ items[i].checked = true;
153
+ this.onChange(value);
154
+ break;
155
+ }
156
+ }
157
+ return this;
158
+ };
159
+
160
+ Select.prototype.setHidden = function (hidden) {
161
+ hidden = !!hidden;
162
+ if (hidden !== this.isHidden()) {
163
+ this._form[(hidden ? 'set' : 'remove') + 'Attribute']('hidden', '');
164
+ this.onHiddenChange(hidden);
165
+ }
166
+ return this;
167
+ };
168
+
169
+ Select.prototype.onHiddenChange = function () {};
170
+
171
+ // Widget
172
+
173
+ var Widget = function Widget(options) {
174
+ var self = this,
175
+ active,
176
+ select = options.select,
177
+ element = options.element,
178
+ storage = options.storage,
179
+ autoMode = options.autoMode,
180
+ pageLang = options.pageLang,
181
+ userLang = options.userLang,
182
+ translator = options.translator,
183
+ leftButton = options.leftButton,
184
+ rightButton = options.rightButton,
185
+ closeButton = options.closeButton,
186
+ defaultLang;
187
+
188
+ this._element = element;
189
+ this._pageLang = pageLang;
190
+ this._translator = translator;
191
+
192
+ this.onStateChange = function (name, enable) {
193
+ if (name === 'active') {
194
+ storage.setValue('active', enable);
195
+ }
196
+ };
197
+
198
+ select.onSelect = function (lang) {
199
+ this.setHidden(true);
200
+ self.translate(lang);
201
+ updatePopupSettings();
202
+ };
203
+
204
+ select.onChange = function (lang) {
205
+ storage.setValue('lang', lang);
206
+ rightButton.setText(lang);
207
+ self.setState('invalid', lang === pageLang);
208
+ updatePopupSettings();
209
+ };
210
+
211
+ select.onHiddenChange = function (hidden) {
212
+ var docElem = doc.documentElement, formRect;
213
+ self.setState('expanded', !hidden);
214
+ if (!hidden) {
215
+ self.setState('right', false)
216
+ .setState('bottom', false);
217
+ element.focus();
218
+ formRect = this._form.getBoundingClientRect();
219
+
220
+ if (formRect.right + (win.pageXOffset || docElem.scrollLeft) + 1 >= Math.max(docElem.clientWidth, docElem.scrollWidth)) {
221
+ self.setState('right', true);
222
+ }
223
+
224
+ if (formRect.bottom + (win.pageYOffset || docElem.scrollTop) + 1 >= Math.max(docElem.clientHeight, docElem.scrollHeight)) {
225
+ self.setState('bottom', true);
226
+ }
227
+ }
228
+ };
229
+
230
+ element.addEventListener('blur', function () {
231
+ select.setHidden(true);
232
+ }, false);
233
+
234
+ element.addEventListener('keydown', function (event) {
235
+ switch (event.keyCode) {
236
+ case util.keycode.ESCAPE:
237
+ select.setHidden(true);
238
+ break;
239
+ }
240
+ }, false);
241
+
242
+ translator.on('error', function () {
243
+ this.abort();
244
+ self.setState('busy', false)
245
+ .setState('error', true);
246
+ });
247
+
248
+ translator.on('progress', function (progress) {
249
+ switch (progress) {
250
+ case 0:
251
+ self.setState('busy', true)
252
+ .setState('active', true);
253
+ break;
254
+
255
+ case 100:
256
+ self.setState('done', true)
257
+ .setState('busy', false);
258
+ break;
259
+ }
260
+ });
261
+ function updatePopupSettings(){
262
+ var container=$("#atlt_strings_model");
263
+ container.find(".string_container").scrollTop(0);
264
+ var scrollHeight= container.find('.string_container').get(0).scrollHeight;
265
+ var scrollSpeed=1000;
266
+ if(scrollHeight > scrollSpeed){
267
+ scrollSpeed = scrollHeight;
268
+ }
269
+ if(scrollHeight!==undefined && scrollHeight>100)
270
+ {
271
+ container.find(".my_translate_progress").fadeIn("slow");
272
+ setTimeout(() => {
273
+ container.find(".string_container").animate({
274
+ scrollTop:scrollHeight+2000
275
+ },scrollSpeed*2,'linear');
276
+ }, 1000);
277
+
278
+ container.find('.string_container').on('scroll', function() {
279
+ if($(this).scrollTop() + $(this).innerHeight() + 50 >= $(this)[0].scrollHeight) {
280
+ setTimeout(() => {
281
+ container.find(".save_it").prop("disabled",false);
282
+ container.find(".ytstats").fadeIn("slow");
283
+ container.find(".my_translate_progress").fadeOut("slow");
284
+ container.find(".string_container").stop();
285
+ $('body').css('top', '0');
286
+ }, 1500);
287
+ }
288
+ });
289
+
290
+ if( container.find('.string_container').innerHeight() + 10 >= scrollHeight) {
291
+ setTimeout(() => {
292
+ container.find(".save_it").prop("disabled",false);
293
+ container.find(".ytstats").fadeIn("slow");
294
+ container.find(".my_translate_progress").fadeOut("slow");
295
+ container.find(".string_container").stop();
296
+ $('body').css('top', '0');
297
+ }, 1500);
298
+ }
299
+ }
300
+ else{
301
+ setTimeout(() => {
302
+ container.find(".save_it").prop("disabled",false);
303
+ container.find(".ytstats").fadeIn("slow");
304
+ }, 2000);
305
+ }
306
+ }
307
+
308
+ leftButton.onClick = function () {
309
+ select.setHidden(true);
310
+ self.translate(select.getValue());
311
+ updatePopupSettings();
312
+ };
313
+
314
+ rightButton.onClick = function () {
315
+ if (self.hasState('active')) {
316
+ translator.undo();
317
+ self.setState('busy', false)
318
+ .setState('done', false)
319
+ .setState('error', false)
320
+ .setState('active', false);
321
+ } else {
322
+ select.setHidden(!select.isHidden());
323
+ }
324
+ };
325
+
326
+ closeButton.onClick = function () {
327
+ select.setHidden(true);
328
+ };
329
+ // defaultLang = storage.getValue('lang') || userLang;
330
+ var defaultcode = window.conf.locale.lang?window.conf.locale.lang:null;
331
+ defaultLang = defaultcode;
332
+ if (defaultLang) {
333
+ select.setValue(defaultLang);
334
+ active = storage.getValue('active');
335
+ if (active || (autoMode && active === undefined)) {
336
+ // this.translate(defaultLang);
337
+ }
338
+ }
339
+ };
340
+ Widget.prototype.hasState = function (name) {
341
+ return util.hasStyleName(this._element, 'yt-state_' + name);
342
+ };
343
+
344
+ Widget.prototype.setState = function (name, enable) {
345
+ var hasState = this.hasState(name);
346
+ enable = !!enable;
347
+ if (enable === hasState) {
348
+ return this;
349
+ }
350
+ util[(enable ? 'add' : 'remove') + 'StyleName'](
351
+ this._element, 'yt-state_' + name
352
+ );
353
+ this.onStateChange(name, enable);
354
+ return this;
355
+ };
356
+
357
+ Widget.prototype.translate = function (targetLang) {
358
+ if (targetLang && !this.hasState('active')) {
359
+ this._translator.translate(this._pageLang, targetLang);
360
+ }
361
+ return this;
362
+ };
363
+
364
+ Widget.prototype.onStateChange = function () {};
365
+
366
+ // Storage
367
+
368
+ var Storage = function Storage(name) {
369
+ this._name = name;
370
+ try {
371
+ this._data = win.JSON.parse(win.localStorage[name]);
372
+ } catch (error) {
373
+ this._data = {};
374
+ }
375
+ };
376
+
377
+ Storage.prototype.getValue = function (prop) {
378
+ return this._data[prop];
379
+ };
380
+
381
+ Storage.prototype.setValue = function (prop, value) {
382
+ this._data[prop] = value;
383
+ try {
384
+ win.localStorage[this._name] = win.JSON.stringify(this._data);
385
+ } catch (error) {}
386
+ };
387
+
388
+ var wrapper = doc.getElementById(params.widgetId);
389
+
390
+ if (!wrapper || !util.isSupportedBrowser()) {
391
+ return;
392
+ }
393
+
394
+ var initWidget = function () {
395
+ util.loadScript('https://yastatic.net/s3/translate/v20.7.4/js/tr_page.js', wrapper, function () {
396
+ util.loadResource('https://translate.yandex.net/website-widget/v1/widget.html',
397
+ function (responseText) {
398
+ var element;
399
+
400
+ if (!responseText) {
401
+ return;
402
+ }
403
+
404
+ wrapper.innerHTML = responseText;
405
+ element = wrapper.querySelector('.yt-widget');
406
+ if (params.widgetTheme) {
407
+ element.setAttribute('data-theme', params.widgetTheme);
408
+ }
409
+
410
+ new Widget({
411
+ select: new Select(element.querySelector('.yt-listbox'), 'yt-lang'),
412
+ element: element,
413
+ storage: new Storage('yt-widget'),
414
+ autoMode: params.autoMode === 'true',
415
+ pageLang: params.pageLang,
416
+ userLang: (nav.language || nav.userLanguage || '').split('-')[0],
417
+ translator: new namespace.PageTranslator({
418
+ srv: 'tr-url-widget',
419
+ sid:'dwdf2343sdfsdf234324',
420
+ // sid: '5eba4470.5f1ec29a.43208802.74722d75726c2d776964676574',
421
+ url: 'https://translate.yandex.net/api/v1/tr.json/translate',
422
+ autoSync: true,
423
+ maxPortionLength: 600
424
+ }),
425
+ leftButton: new Button(element.querySelector('.yt-button_type_left')),
426
+ rightButton: new Button(
427
+ element.querySelector('.yt-button_type_right'),
428
+ element.querySelector('.yt-button_type_right > .yt-button__text')
429
+ ),
430
+ closeButton: new Button(element.querySelector('.yt-button_type_close'))
431
+ });
432
+ }
433
+ );
434
+ });
435
+ };
436
+
437
+ if (doc.readyState === 'complete' || doc.readyState === 'interactive') {
438
+ initWidget();
439
+ } else {
440
+ doc.addEventListener('DOMContentLoaded', initWidget, false);
441
+ }
442
+ })(jQuery,this, this.document, this.navigator, {"widgetId":"ytWidget","pageLang":"en","widgetTheme":"light","autoMode":"false"}, this.yt = this.yt || {});
assets/sweetalert/sweetalert.min.js DELETED
@@ -1 +0,0 @@
1
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.swal=e():t.swal=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,o){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=8)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o="swal-button";e.CLASS_NAMES={MODAL:"swal-modal",OVERLAY:"swal-overlay",SHOW_MODAL:"swal-overlay--show-modal",MODAL_TITLE:"swal-title",MODAL_TEXT:"swal-text",ICON:"swal-icon",ICON_CUSTOM:"swal-icon--custom",CONTENT:"swal-content",FOOTER:"swal-footer",BUTTON_CONTAINER:"swal-button-container",BUTTON:o,CONFIRM_BUTTON:o+"--confirm",CANCEL_BUTTON:o+"--cancel",DANGER_BUTTON:o+"--danger",BUTTON_LOADING:o+"--loading",BUTTON_LOADER:o+"__loader"},e.default=e.CLASS_NAMES},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.getNode=function(t){var e="."+t;return document.querySelector(e)},e.stringToNode=function(t){var e=document.createElement("div");return e.innerHTML=t.trim(),e.firstChild},e.insertAfter=function(t,e){var n=e.nextSibling;e.parentNode.insertBefore(t,n)},e.removeNode=function(t){t.parentElement.removeChild(t)},e.throwErr=function(t){throw t=t.replace(/ +(?= )/g,""),"SweetAlert: "+(t=t.trim())},e.isPlainObject=function(t){if("[object Object]"!==Object.prototype.toString.call(t))return!1;var e=Object.getPrototypeOf(t);return null===e||e===Object.prototype},e.ordinalSuffixOf=function(t){var e=t%10,n=t%100;return 1===e&&11!==n?t+"st":2===e&&12!==n?t+"nd":3===e&&13!==n?t+"rd":t+"th"}},function(t,e,n){"use strict";function o(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),o(n(25));var r=n(26);e.overlayMarkup=r.default,o(n(27)),o(n(28)),o(n(29));var i=n(0),a=i.default.MODAL_TITLE,s=i.default.MODAL_TEXT,c=i.default.ICON,l=i.default.FOOTER;e.iconMarkup='\n <div class="'+c+'"></div>',e.titleMarkup='\n <div class="'+a+'"></div>\n',e.textMarkup='\n <div class="'+s+'"></div>',e.footerMarkup='\n <div class="'+l+'"></div>\n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1);e.CONFIRM_KEY="confirm",e.CANCEL_KEY="cancel";var r={visible:!0,text:null,value:null,className:"",closeModal:!0},i=Object.assign({},r,{visible:!1,text:"Cancel",value:null}),a=Object.assign({},r,{text:"OK",value:!0});e.defaultButtonList={cancel:i,confirm:a};var s=function(t){switch(t){case e.CONFIRM_KEY:return a;case e.CANCEL_KEY:return i;default:var n=t.charAt(0).toUpperCase()+t.slice(1);return Object.assign({},r,{text:n,value:t})}},c=function(t,e){var n=s(t);return!0===e?Object.assign({},n,{visible:!0}):"string"==typeof e?Object.assign({},n,{visible:!0,text:e}):o.isPlainObject(e)?Object.assign({visible:!0},n,e):Object.assign({},n,{visible:!1})},l=function(t){for(var e={},n=0,o=Object.keys(t);n<o.length;n++){var r=o[n],a=t[r],s=c(r,a);e[r]=s}return e.cancel||(e.cancel=i),e},u=function(t){var n={};switch(t.length){case 1:n[e.CANCEL_KEY]=Object.assign({},i,{visible:!1});break;case 2:n[e.CANCEL_KEY]=c(e.CANCEL_KEY,t[0]),n[e.CONFIRM_KEY]=c(e.CONFIRM_KEY,t[1]);break;default:o.throwErr("Invalid number of 'buttons' in array ("+t.length+").\n If you want more than 2 buttons, you need to use an object!")}return n};e.getButtonListOpts=function(t){var n=e.defaultButtonList;return"string"==typeof t?n[e.CONFIRM_KEY]=c(e.CONFIRM_KEY,t):Array.isArray(t)?n=u(t):o.isPlainObject(t)?n=l(t):!0===t?n=u([!0,!0]):!1===t?n=u([!1,!1]):void 0===t&&(n=e.defaultButtonList),n}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(2),i=n(0),a=i.default.MODAL,s=i.default.OVERLAY,c=n(30),l=n(31),u=n(32),f=n(33);e.injectElIntoModal=function(t){var e=o.getNode(a),n=o.stringToNode(t);return e.appendChild(n),n};var d=function(t){t.className=a,t.textContent=""},p=function(t,e){d(t);var n=e.className;n&&t.classList.add(n)};e.initModalContent=function(t){var e=o.getNode(a);p(e,t),c.default(t.icon),l.initTitle(t.title),l.initText(t.text),f.default(t.content),u.default(t.buttons,t.dangerMode)};var m=function(){var t=o.getNode(s),e=o.stringToNode(r.modalMarkup);t.appendChild(e)};e.default=m},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(3),r={isOpen:!1,promise:null,actions:{},timer:null},i=Object.assign({},r);e.resetState=function(){i=Object.assign({},r)},e.setActionValue=function(t){if("string"==typeof t)return a(o.CONFIRM_KEY,t);for(var e in t)a(e,t[e])};var a=function(t,e){i.actions[t]||(i.actions[t]={}),Object.assign(i.actions[t],{value:e})};e.setActionOptionsFor=function(t,e){var n=(void 0===e?{}:e).closeModal,o=void 0===n||n;Object.assign(i.actions[t],{closeModal:o})},e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(3),i=n(0),a=i.default.OVERLAY,s=i.default.SHOW_MODAL,c=i.default.BUTTON,l=i.default.BUTTON_LOADING,u=n(5);e.openModal=function(){o.getNode(a).classList.add(s),u.default.isOpen=!0};var f=function(){o.getNode(a).classList.remove(s),u.default.isOpen=!1};e.onAction=function(t){void 0===t&&(t=r.CANCEL_KEY);var e=u.default.actions[t],n=e.value;if(!1===e.closeModal){var i=c+"--"+t;o.getNode(i).classList.add(l)}else f();u.default.promise.resolve(n)},e.getState=function(){var t=Object.assign({},u.default);return delete t.promise,delete t.timer,t},e.stopLoading=function(){for(var t=document.querySelectorAll("."+c),e=0;e<t.length;e++){t[e].classList.remove(l)}}},function(t,e){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){(function(e){t.exports=e.sweetAlert=n(9)}).call(e,n(7))},function(t,e,n){(function(e){t.exports=e.swal=n(10)}).call(e,n(7))},function(t,e,n){"undefined"!=typeof window&&n(11),n(16);var o=n(23).default;t.exports=o},function(t,e,n){var o=n(12);"string"==typeof o&&(o=[[t.i,o,""]]);var r={insertAt:"top"};r.transform=void 0;n(14)(o,r);o.locals&&(t.exports=o.locals)},function(t,e,n){e=t.exports=n(13)(void 0),e.push([t.i,'.swal-icon--error{border-color:#f27474;-webkit-animation:animateErrorIcon .5s;animation:animateErrorIcon .5s}.swal-icon--error__x-mark{position:relative;display:block;-webkit-animation:animateXMark .5s;animation:animateXMark .5s}.swal-icon--error__line{position:absolute;height:5px;width:47px;background-color:#f27474;display:block;top:37px;border-radius:2px}.swal-icon--error__line--left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.swal-icon--error__line--right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}@-webkit-keyframes animateErrorIcon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}to{-webkit-transform:rotateX(0deg);transform:rotateX(0deg);opacity:1}}@keyframes animateErrorIcon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}to{-webkit-transform:rotateX(0deg);transform:rotateX(0deg);opacity:1}}@-webkit-keyframes animateXMark{0%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}to{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}@keyframes animateXMark{0%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}to{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}.swal-icon--warning{border-color:#f8bb86;-webkit-animation:pulseWarning .75s infinite alternate;animation:pulseWarning .75s infinite alternate}.swal-icon--warning__body{width:5px;height:47px;top:10px;border-radius:2px;margin-left:-2px}.swal-icon--warning__body,.swal-icon--warning__dot{position:absolute;left:50%;background-color:#f8bb86}.swal-icon--warning__dot{width:7px;height:7px;border-radius:50%;margin-left:-4px;bottom:-11px}@-webkit-keyframes pulseWarning{0%{border-color:#f8d486}to{border-color:#f8bb86}}@keyframes pulseWarning{0%{border-color:#f8d486}to{border-color:#f8bb86}}.swal-icon--success{border-color:#a5dc86}.swal-icon--success:after,.swal-icon--success:before{content:"";border-radius:50%;position:absolute;width:60px;height:120px;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal-icon--success:before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.swal-icon--success:after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px;-webkit-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}.swal-icon--success__ring{width:80px;height:80px;border:4px solid hsla(98,55%,69%,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.swal-icon--success__hide-corners{width:5px;height:90px;background-color:#fff;padding:1px;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal-icon--success__line{height:5px;background-color:#a5dc86;display:block;border-radius:2px;position:absolute;z-index:2}.swal-icon--success__line--tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-animation:animateSuccessTip .75s;animation:animateSuccessTip .75s}.swal-icon--success__line--long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-animation:animateSuccessLong .75s;animation:animateSuccessLong .75s}@-webkit-keyframes rotatePlaceholder{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}to{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}@keyframes rotatePlaceholder{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}to{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}@-webkit-keyframes animateSuccessTip{0%{width:0;left:1px;top:19px}54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}to{width:25px;left:14px;top:45px}}@keyframes animateSuccessTip{0%{width:0;left:1px;top:19px}54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}to{width:25px;left:14px;top:45px}}@-webkit-keyframes animateSuccessLong{0%{width:0;right:46px;top:54px}65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}to{width:47px;right:8px;top:38px}}@keyframes animateSuccessLong{0%{width:0;right:46px;top:54px}65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}to{width:47px;right:8px;top:38px}}.swal-icon--info{border-color:#c9dae1}.swal-icon--info:before{width:5px;height:29px;bottom:17px;border-radius:2px;margin-left:-2px}.swal-icon--info:after,.swal-icon--info:before{content:"";position:absolute;left:50%;background-color:#c9dae1}.swal-icon--info:after{width:7px;height:7px;border-radius:50%;margin-left:-3px;top:19px}.swal-icon{width:80px;height:80px;border-width:4px;border-style:solid;border-radius:50%;padding:0;position:relative;box-sizing:content-box;margin:20px auto}.swal-icon:first-child{margin-top:32px}.swal-icon--custom{width:auto;height:auto;max-width:100%;border:none;border-radius:0}.swal-icon img{max-width:100%;max-height:100%}.swal-title{color:rgba(0,0,0,.65);font-weight:600;text-transform:none;position:relative;display:block;padding:13px 16px;font-size:27px;line-height:normal;text-align:center;margin-bottom:0}.swal-title:first-child{margin-top:26px}.swal-title:not(:first-child){padding-bottom:0}.swal-title:not(:last-child){margin-bottom:13px}.swal-text{font-size:16px;position:relative;float:none;line-height:normal;vertical-align:top;text-align:left;display:inline-block;margin:0;padding:0 10px;font-weight:400;color:rgba(0,0,0,.64);max-width:calc(100% - 20px);overflow-wrap:break-word;box-sizing:border-box}.swal-text:first-child{margin-top:45px}.swal-text:last-child{margin-bottom:45px}.swal-footer{text-align:right;padding-top:13px;margin-top:13px;padding:13px 16px;border-radius:inherit;border-top-left-radius:0;border-top-right-radius:0}.swal-button-container{margin:5px;display:inline-block;position:relative}.swal-button{background-color:#7cd1f9;color:#fff;border:none;box-shadow:none;border-radius:5px;font-weight:600;font-size:14px;padding:10px 24px;margin:0;cursor:pointer}.swal-button:not([disabled]):hover{background-color:#78cbf2}.swal-button:active{background-color:#70bce0}.swal-button:focus{outline:none;box-shadow:0 0 0 1px #fff,0 0 0 3px rgba(43,114,165,.29)}.swal-button[disabled]{opacity:.5;cursor:default}.swal-button::-moz-focus-inner{border:0}.swal-button--cancel{color:#555;background-color:#efefef}.swal-button--cancel:not([disabled]):hover{background-color:#e8e8e8}.swal-button--cancel:active{background-color:#d7d7d7}.swal-button--cancel:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px rgba(116,136,150,.29)}.swal-button--danger{background-color:#e64942}.swal-button--danger:not([disabled]):hover{background-color:#df4740}.swal-button--danger:active{background-color:#cf423b}.swal-button--danger:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px rgba(165,43,43,.29)}.swal-content{padding:0 20px;margin-top:20px;font-size:medium}.swal-content:last-child{margin-bottom:20px}.swal-content__input,.swal-content__textarea{-webkit-appearance:none;background-color:#fff;border:none;font-size:14px;display:block;box-sizing:border-box;width:100%;border:1px solid rgba(0,0,0,.14);padding:10px 13px;border-radius:2px;transition:border-color .2s}.swal-content__input:focus,.swal-content__textarea:focus{outline:none;border-color:#6db8ff}.swal-content__textarea{resize:vertical}.swal-button--loading{color:transparent}.swal-button--loading~.swal-button__loader{opacity:1}.swal-button__loader{position:absolute;height:auto;width:43px;z-index:2;left:50%;top:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);text-align:center;pointer-events:none;opacity:0}.swal-button__loader div{display:inline-block;float:none;vertical-align:baseline;width:9px;height:9px;padding:0;border:none;margin:2px;opacity:.4;border-radius:7px;background-color:hsla(0,0%,100%,.9);transition:background .2s;-webkit-animation:swal-loading-anim 1s infinite;animation:swal-loading-anim 1s infinite}.swal-button__loader div:nth-child(3n+2){-webkit-animation-delay:.15s;animation-delay:.15s}.swal-button__loader div:nth-child(3n+3){-webkit-animation-delay:.3s;animation-delay:.3s}@-webkit-keyframes swal-loading-anim{0%{opacity:.4}20%{opacity:.4}50%{opacity:1}to{opacity:.4}}@keyframes swal-loading-anim{0%{opacity:.4}20%{opacity:.4}50%{opacity:1}to{opacity:.4}}.swal-overlay{position:fixed;top:0;bottom:0;left:0;right:0;text-align:center;font-size:0;overflow-y:auto;background-color:rgba(0,0,0,.4);z-index:10000;pointer-events:none;opacity:0;transition:opacity .3s}.swal-overlay:before{content:" ";display:inline-block;vertical-align:middle;height:100%}.swal-overlay--show-modal{opacity:1;pointer-events:auto}.swal-overlay--show-modal .swal-modal{opacity:1;pointer-events:auto;box-sizing:border-box;-webkit-animation:showSweetAlert .3s;animation:showSweetAlert .3s;will-change:transform}.swal-modal{width:478px;opacity:0;pointer-events:none;background-color:#fff;text-align:center;border-radius:5px;position:static;margin:20px auto;display:inline-block;vertical-align:middle;-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 50%;transform-origin:50% 50%;z-index:10001;transition:opacity .2s,-webkit-transform .3s;transition:transform .3s,opacity .2s;transition:transform .3s,opacity .2s,-webkit-transform .3s}@media (max-width:500px){.swal-modal{width:calc(100% - 20px)}}@-webkit-keyframes showSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1)}1%{-webkit-transform:scale(.5);transform:scale(.5)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}to{-webkit-transform:scale(1);transform:scale(1)}}@keyframes showSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1)}1%{-webkit-transform:scale(.5);transform:scale(.5)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}to{-webkit-transform:scale(1);transform:scale(1)}}',""])},function(t,e){function n(t,e){var n=t[1]||"",r=t[3];if(!r)return n;if(e&&"function"==typeof btoa){var i=o(r);return[n].concat(r.sources.map(function(t){return"/*# sourceURL="+r.sourceRoot+t+" */"})).concat([i]).join("\n")}return[n].join("\n")}function o(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var o=n(e,t);return e[2]?"@media "+e[2]+"{"+o+"}":o}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var o={},r=0;r<this.length;r++){var i=this[r][0];"number"==typeof i&&(o[i]=!0)}for(r=0;r<t.length;r++){var a=t[r];"number"==typeof a[0]&&o[a[0]]||(n&&!a[2]?a[2]=n:n&&(a[2]="("+a[2]+") and ("+n+")"),e.push(a))}},e}},function(t,e,n){function o(t,e){for(var n=0;n<t.length;n++){var o=t[n],r=m[o.id];if(r){r.refs++;for(var i=0;i<r.parts.length;i++)r.parts[i](o.parts[i]);for(;i<o.parts.length;i++)r.parts.push(u(o.parts[i],e))}else{for(var a=[],i=0;i<o.parts.length;i++)a.push(u(o.parts[i],e));m[o.id]={id:o.id,refs:1,parts:a}}}}function r(t,e){for(var n=[],o={},r=0;r<t.length;r++){var i=t[r],a=e.base?i[0]+e.base:i[0],s=i[1],c=i[2],l=i[3],u={css:s,media:c,sourceMap:l};o[a]?o[a].parts.push(u):n.push(o[a]={id:a,parts:[u]})}return n}function i(t,e){var n=v(t.insertInto);if(!n)throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");var o=w[w.length-1];if("top"===t.insertAt)o?o.nextSibling?n.insertBefore(e,o.nextSibling):n.appendChild(e):n.insertBefore(e,n.firstChild),w.push(e);else{if("bottom"!==t.insertAt)throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");n.appendChild(e)}}function a(t){if(null===t.parentNode)return!1;t.parentNode.removeChild(t);var e=w.indexOf(t);e>=0&&w.splice(e,1)}function s(t){var e=document.createElement("style");return t.attrs.type="text/css",l(e,t.attrs),i(t,e),e}function c(t){var e=document.createElement("link");return t.attrs.type="text/css",t.attrs.rel="stylesheet",l(e,t.attrs),i(t,e),e}function l(t,e){Object.keys(e).forEach(function(n){t.setAttribute(n,e[n])})}function u(t,e){var n,o,r,i;if(e.transform&&t.css){if(!(i=e.transform(t.css)))return function(){};t.css=i}if(e.singleton){var l=h++;n=g||(g=s(e)),o=f.bind(null,n,l,!1),r=f.bind(null,n,l,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=c(e),o=p.bind(null,n,e),r=function(){a(n),n.href&&URL.revokeObjectURL(n.href)}):(n=s(e),o=d.bind(null,n),r=function(){a(n)});return o(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;o(t=e)}else r()}}function f(t,e,n,o){var r=n?"":o.css;if(t.styleSheet)t.styleSheet.cssText=x(e,r);else{var i=document.createTextNode(r),a=t.childNodes;a[e]&&t.removeChild(a[e]),a.length?t.insertBefore(i,a[e]):t.appendChild(i)}}function d(t,e){var n=e.css,o=e.media;if(o&&t.setAttribute("media",o),t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}function p(t,e,n){var o=n.css,r=n.sourceMap,i=void 0===e.convertToAbsoluteUrls&&r;(e.convertToAbsoluteUrls||i)&&(o=y(o)),r&&(o+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+" */");var a=new Blob([o],{type:"text/css"}),s=t.href;t.href=URL.createObjectURL(a),s&&URL.revokeObjectURL(s)}var m={},b=function(t){var e;return function(){return void 0===e&&(e=t.apply(this,arguments)),e}}(function(){return window&&document&&document.all&&!window.atob}),v=function(t){var e={};return function(n){return void 0===e[n]&&(e[n]=t.call(this,n)),e[n]}}(function(t){return document.querySelector(t)}),g=null,h=0,w=[],y=n(15);t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");e=e||{},e.attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||(e.singleton=b()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var n=r(t,e);return o(n,e),function(t){for(var i=[],a=0;a<n.length;a++){var s=n[a],c=m[s.id];c.refs--,i.push(c)}if(t){o(r(t,e),e)}for(var a=0;a<i.length;a++){var c=i[a];if(0===c.refs){for(var l=0;l<c.parts.length;l++)c.parts[l]();delete m[c.id]}}}};var x=function(){var t=[];return function(e,n){return t[e]=n,t.filter(Boolean).join("\n")}}()},function(t,e){t.exports=function(t){var e="undefined"!=typeof window&&window.location;if(!e)throw new Error("fixUrls requires window.location");if(!t||"string"!=typeof t)return t;var n=e.protocol+"//"+e.host,o=n+e.pathname.replace(/\/[^\/]*$/,"/");return t.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,function(t,e){var r=e.trim().replace(/^"(.*)"$/,function(t,e){return e}).replace(/^'(.*)'$/,function(t,e){return e});if(/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(r))return t;var i;return i=0===r.indexOf("//")?r:0===r.indexOf("/")?n+r:o+r.replace(/^\.\//,""),"url("+JSON.stringify(i)+")"})}},function(t,e,n){var o=n(17);"undefined"==typeof window||window.Promise||(window.Promise=o),n(21),String.prototype.includes||(String.prototype.includes=function(t,e){"use strict";return"number"!=typeof e&&(e=0),!(e+t.length>this.length)&&-1!==this.indexOf(t,e)}),Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(t,e){if(null==this)throw new TypeError('"this" is null or not defined');var n=Object(this),o=n.length>>>0;if(0===o)return!1;for(var r=0|e,i=Math.max(r>=0?r:o-Math.abs(r),0);i<o;){if(function(t,e){return t===e||"number"==typeof t&&"number"==typeof e&&isNaN(t)&&isNaN(e)}(n[i],t))return!0;i++}return!1}}),"undefined"!=typeof window&&function(t){t.forEach(function(t){t.hasOwnProperty("remove")||Object.defineProperty(t,"remove",{configurable:!0,enumerable:!0,writable:!0,value:function(){this.parentNode.removeChild(this)}})})}([Element.prototype,CharacterData.prototype,DocumentType.prototype])},function(t,e,n){(function(e){!function(n){function o(){}function r(t,e){return function(){t.apply(e,arguments)}}function i(t){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof t)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(t,this)}function a(t,e){for(;3===t._state;)t=t._value;if(0===t._state)return void t._deferreds.push(e);t._handled=!0,i._immediateFn(function(){var n=1===t._state?e.onFulfilled:e.onRejected;if(null===n)return void(1===t._state?s:c)(e.promise,t._value);var o;try{o=n(t._value)}catch(t){return void c(e.promise,t)}s(e.promise,o)})}function s(t,e){try{if(e===t)throw new TypeError("A promise cannot be resolved with itself.");if(e&&("object"==typeof e||"function"==typeof e)){var n=e.then;if(e instanceof i)return t._state=3,t._value=e,void l(t);if("function"==typeof n)return void f(r(n,e),t)}t._state=1,t._value=e,l(t)}catch(e){c(t,e)}}function c(t,e){t._state=2,t._value=e,l(t)}function l(t){2===t._state&&0===t._deferreds.length&&i._immediateFn(function(){t._handled||i._unhandledRejectionFn(t._value)});for(var e=0,n=t._deferreds.length;e<n;e++)a(t,t._deferreds[e]);t._deferreds=null}function u(t,e,n){this.onFulfilled="function"==typeof t?t:null,this.onRejected="function"==typeof e?e:null,this.promise=n}function f(t,e){var n=!1;try{t(function(t){n||(n=!0,s(e,t))},function(t){n||(n=!0,c(e,t))})}catch(t){if(n)return;n=!0,c(e,t)}}var d=setTimeout;i.prototype.catch=function(t){return this.then(null,t)},i.prototype.then=function(t,e){var n=new this.constructor(o);return a(this,new u(t,e,n)),n},i.all=function(t){var e=Array.prototype.slice.call(t);return new i(function(t,n){function o(i,a){try{if(a&&("object"==typeof a||"function"==typeof a)){var s=a.then;if("function"==typeof s)return void s.call(a,function(t){o(i,t)},n)}e[i]=a,0==--r&&t(e)}catch(t){n(t)}}if(0===e.length)return t([]);for(var r=e.length,i=0;i<e.length;i++)o(i,e[i])})},i.resolve=function(t){return t&&"object"==typeof t&&t.constructor===i?t:new i(function(e){e(t)})},i.reject=function(t){return new i(function(e,n){n(t)})},i.race=function(t){return new i(function(e,n){for(var o=0,r=t.length;o<r;o++)t[o].then(e,n)})},i._immediateFn="function"==typeof e&&function(t){e(t)}||function(t){d(t,0)},i._unhandledRejectionFn=function(t){"undefined"!=typeof console&&console&&console.warn("Possible Unhandled Promise Rejection:",t)},i._setImmediateFn=function(t){i._immediateFn=t},i._setUnhandledRejectionFn=function(t){i._unhandledRejectionFn=t},void 0!==t&&t.exports?t.exports=i:n.Promise||(n.Promise=i)}(this)}).call(e,n(18).setImmediate)},function(t,e,n){function o(t,e){this._id=t,this._clearFn=e}var r=Function.prototype.apply;e.setTimeout=function(){return new o(r.call(setTimeout,window,arguments),clearTimeout)},e.setInterval=function(){return new o(r.call(setInterval,window,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t&&t.close()},o.prototype.unref=o.prototype.ref=function(){},o.prototype.close=function(){this._clearFn.call(window,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},n(19),e.setImmediate=setImmediate,e.clearImmediate=clearImmediate},function(t,e,n){(function(t,e){!function(t,n){"use strict";function o(t){"function"!=typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),n=0;n<e.length;n++)e[n]=arguments[n+1];var o={callback:t,args:e};return l[c]=o,s(c),c++}function r(t){delete l[t]}function i(t){var e=t.callback,o=t.args;switch(o.length){case 0:e();break;case 1:e(o[0]);break;case 2:e(o[0],o[1]);break;case 3:e(o[0],o[1],o[2]);break;default:e.apply(n,o)}}function a(t){if(u)setTimeout(a,0,t);else{var e=l[t];if(e){u=!0;try{i(e)}finally{r(t),u=!1}}}}if(!t.setImmediate){var s,c=1,l={},u=!1,f=t.document,d=Object.getPrototypeOf&&Object.getPrototypeOf(t);d=d&&d.setTimeout?d:t,"[object process]"==={}.toString.call(t.process)?function(){s=function(t){e.nextTick(function(){a(t)})}}():function(){if(t.postMessage&&!t.importScripts){var e=!0,n=t.onmessage;return t.onmessage=function(){e=!1},t.postMessage("","*"),t.onmessage=n,e}}()?function(){var e="setImmediate$"+Math.random()+"$",n=function(n){n.source===t&&"string"==typeof n.data&&0===n.data.indexOf(e)&&a(+n.data.slice(e.length))};t.addEventListener?t.addEventListener("message",n,!1):t.attachEvent("onmessage",n),s=function(n){t.postMessage(e+n,"*")}}():t.MessageChannel?function(){var t=new MessageChannel;t.port1.onmessage=function(t){a(t.data)},s=function(e){t.port2.postMessage(e)}}():f&&"onreadystatechange"in f.createElement("script")?function(){var t=f.documentElement;s=function(e){var n=f.createElement("script");n.onreadystatechange=function(){a(e),n.onreadystatechange=null,t.removeChild(n),n=null},t.appendChild(n)}}():function(){s=function(t){setTimeout(a,0,t)}}(),d.setImmediate=o,d.clearImmediate=r}}("undefined"==typeof self?void 0===t?this:t:self)}).call(e,n(7),n(20))},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function r(t){if(u===setTimeout)return setTimeout(t,0);if((u===n||!u)&&setTimeout)return u=setTimeout,setTimeout(t,0);try{return u(t,0)}catch(e){try{return u.call(null,t,0)}catch(e){return u.call(this,t,0)}}}function i(t){if(f===clearTimeout)return clearTimeout(t);if((f===o||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(t);try{return f(t)}catch(e){try{return f.call(null,t)}catch(e){return f.call(this,t)}}}function a(){b&&p&&(b=!1,p.length?m=p.concat(m):v=-1,m.length&&s())}function s(){if(!b){var t=r(a);b=!0;for(var e=m.length;e;){for(p=m,m=[];++v<e;)p&&p[v].run();v=-1,e=m.length}p=null,b=!1,i(t)}}function c(t,e){this.fun=t,this.array=e}function l(){}var u,f,d=t.exports={};!function(){try{u="function"==typeof setTimeout?setTimeout:n}catch(t){u=n}try{f="function"==typeof clearTimeout?clearTimeout:o}catch(t){f=o}}();var p,m=[],b=!1,v=-1;d.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];m.push(new c(t,e)),1!==m.length||b||r(s)},c.prototype.run=function(){this.fun.apply(null,this.array)},d.title="browser",d.browser=!0,d.env={},d.argv=[],d.version="",d.versions={},d.on=l,d.addListener=l,d.once=l,d.off=l,d.removeListener=l,d.removeAllListeners=l,d.emit=l,d.prependListener=l,d.prependOnceListener=l,d.listeners=function(t){return[]},d.binding=function(t){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(t){throw new Error("process.chdir is not supported")},d.umask=function(){return 0}},function(t,e,n){"use strict";n(22).polyfill()},function(t,e,n){"use strict";function o(t,e){if(void 0===t||null===t)throw new TypeError("Cannot convert first argument to object");for(var n=Object(t),o=1;o<arguments.length;o++){var r=arguments[o];if(void 0!==r&&null!==r)for(var i=Object.keys(Object(r)),a=0,s=i.length;a<s;a++){var c=i[a],l=Object.getOwnPropertyDescriptor(r,c);void 0!==l&&l.enumerable&&(n[c]=r[c])}}return n}function r(){Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:o})}t.exports={assign:o,polyfill:r}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(24),r=n(6),i=n(5),a=n(36),s=function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];if("undefined"!=typeof window){var n=a.getOpts.apply(void 0,t);return new Promise(function(t,e){i.default.promise={resolve:t,reject:e},o.default(n),setTimeout(function(){r.openModal()})})}};s.close=r.onAction,s.getState=r.getState,s.setActionValue=i.setActionValue,s.stopLoading=r.stopLoading,s.setDefaults=a.setDefaults,e.default=s},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(0),i=r.default.MODAL,a=n(4),s=n(34),c=n(35),l=n(1);e.init=function(t){o.getNode(i)||(document.body||l.throwErr("You can only use SweetAlert AFTER the DOM has loaded!"),s.default(),a.default()),a.initModalContent(t),c.default(t)},e.default=e.init},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.MODAL;e.modalMarkup='\n <div class="'+r+'" role="dialog" aria-modal="true"></div>',e.default=e.modalMarkup},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.OVERLAY,i='<div \n class="'+r+'"\n tabIndex="-1">\n </div>';e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.ICON;e.errorIconMarkup=function(){var t=r+"--error",e=t+"__line";return'\n <div class="'+t+'__x-mark">\n <span class="'+e+" "+e+'--left"></span>\n <span class="'+e+" "+e+'--right"></span>\n </div>\n '},e.warningIconMarkup=function(){var t=r+"--warning";return'\n <span class="'+t+'__body">\n <span class="'+t+'__dot"></span>\n </span>\n '},e.successIconMarkup=function(){var t=r+"--success";return'\n <span class="'+t+"__line "+t+'__line--long"></span>\n <span class="'+t+"__line "+t+'__line--tip"></span>\n\n <div class="'+t+'__ring"></div>\n <div class="'+t+'__hide-corners"></div>\n '}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.CONTENT;e.contentMarkup='\n <div class="'+r+'">\n\n </div>\n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.BUTTON_CONTAINER,i=o.default.BUTTON,a=o.default.BUTTON_LOADER;e.buttonMarkup='\n <div class="'+r+'">\n\n <button\n class="'+i+'"\n ></button>\n\n <div class="'+a+'">\n <div></div>\n <div></div>\n <div></div>\n </div>\n\n </div>\n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(4),r=n(2),i=n(0),a=i.default.ICON,s=i.default.ICON_CUSTOM,c=["error","warning","success","info"],l={error:r.errorIconMarkup(),warning:r.warningIconMarkup(),success:r.successIconMarkup()},u=function(t,e){var n=a+"--"+t;e.classList.add(n);var o=l[t];o&&(e.innerHTML=o)},f=function(t,e){e.classList.add(s);var n=document.createElement("img");n.src=t,e.appendChild(n)},d=function(t){if(t){var e=o.injectElIntoModal(r.iconMarkup);c.includes(t)?u(t,e):f(t,e)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(2),r=n(4),i=function(t){navigator.userAgent.includes("AppleWebKit")&&(t.style.display="none",t.offsetHeight,t.style.display="")};e.initTitle=function(t){if(t){var e=r.injectElIntoModal(o.titleMarkup);e.textContent=t,i(e)}},e.initText=function(t){if(t){var e=document.createDocumentFragment();t.split("\n").forEach(function(t,n,o){e.appendChild(document.createTextNode(t)),n<o.length-1&&e.appendChild(document.createElement("br"))});var n=r.injectElIntoModal(o.textMarkup);n.appendChild(e),i(n)}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(4),i=n(0),a=i.default.BUTTON,s=i.default.DANGER_BUTTON,c=n(3),l=n(2),u=n(6),f=n(5),d=function(t,e,n){var r=e.text,i=e.value,d=e.className,p=e.closeModal,m=o.stringToNode(l.buttonMarkup),b=m.querySelector("."+a),v=a+"--"+t;if(b.classList.add(v),d){(Array.isArray(d)?d:d.split(" ")).filter(function(t){return t.length>0}).forEach(function(t){b.classList.add(t)})}n&&t===c.CONFIRM_KEY&&b.classList.add(s),b.textContent=r;var g={};return g[t]=i,f.setActionValue(g),f.setActionOptionsFor(t,{closeModal:p}),b.addEventListener("click",function(){return u.onAction(t)}),m},p=function(t,e){var n=r.injectElIntoModal(l.footerMarkup);for(var o in t){var i=t[o],a=d(o,i,e);i.visible&&n.appendChild(a)}0===n.children.length&&n.remove()};e.default=p},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(3),r=n(4),i=n(2),a=n(5),s=n(6),c=n(0),l=c.default.CONTENT,u=function(t){t.addEventListener("input",function(t){var e=t.target,n=e.value;a.setActionValue(n)}),t.addEventListener("keyup",function(t){if("Enter"===t.key)return s.onAction(o.CONFIRM_KEY)}),setTimeout(function(){t.focus(),a.setActionValue("")},0)},f=function(t,e,n){var o=document.createElement(e),r=l+"__"+e;o.classList.add(r);for(var i in n){var a=n[i];o[i]=a}"input"===e&&u(o),t.appendChild(o)},d=function(t){if(t){var e=r.injectElIntoModal(i.contentMarkup),n=t.element,o=t.attributes;"string"==typeof n?f(e,n,o):e.appendChild(n)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(2),i=function(){var t=o.stringToNode(r.overlayMarkup);document.body.appendChild(t)};e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(5),r=n(6),i=n(1),a=n(3),s=n(0),c=s.default.MODAL,l=s.default.BUTTON,u=s.default.OVERLAY,f=function(t){t.preventDefault(),v()},d=function(t){t.preventDefault(),g()},p=function(t){if(o.default.isOpen)switch(t.key){case"Escape":return r.onAction(a.CANCEL_KEY)}},m=function(t){if(o.default.isOpen)switch(t.key){case"Tab":return f(t)}},b=function(t){if(o.default.isOpen)return"Tab"===t.key&&t.shiftKey?d(t):void 0},v=function(){var t=i.getNode(l);t&&(t.tabIndex=0,t.focus())},g=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l),n=e.length-1,o=e[n];o&&o.focus()},h=function(t){t[t.length-1].addEventListener("keydown",m)},w=function(t){t[0].addEventListener("keydown",b)},y=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l);e.length&&(h(e),w(e))},x=function(t){if(i.getNode(u)===t.target)return r.onAction(a.CANCEL_KEY)},_=function(t){var e=i.getNode(u);e.removeEventListener("click",x),t&&e.addEventListener("click",x)},k=function(t){o.default.timer&&clearTimeout(o.default.timer),t&&(o.default.timer=window.setTimeout(function(){return r.onAction(a.CANCEL_KEY)},t))},O=function(t){t.closeOnEsc?document.addEventListener("keyup",p):document.removeEventListener("keyup",p),t.dangerMode?v():g(),y(),_(t.closeOnClickOutside),k(t.timer)};e.default=O},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(3),i=n(37),a=n(38),s={title:null,text:null,icon:null,buttons:r.defaultButtonList,content:null,className:null,closeOnClickOutside:!0,closeOnEsc:!0,dangerMode:!1,timer:null},c=Object.assign({},s);e.setDefaults=function(t){c=Object.assign({},s,t)};var l=function(t){var e=t&&t.button,n=t&&t.buttons;return void 0!==e&&void 0!==n&&o.throwErr("Cannot set both 'button' and 'buttons' options!"),void 0!==e?{confirm:e}:n},u=function(t){return o.ordinalSuffixOf(t+1)},f=function(t,e){o.throwErr(u(e)+" argument ('"+t+"') is invalid")},d=function(t,e){var n=t+1,r=e[n];o.isPlainObject(r)||void 0===r||o.throwErr("Expected "+u(n)+" argument ('"+r+"') to be a plain object")},p=function(t,e){var n=t+1,r=e[n];void 0!==r&&o.throwErr("Unexpected "+u(n)+" argument ("+r+")")},m=function(t,e,n,r){var i=typeof e,a="string"===i,s=e instanceof Element;if(a){if(0===n)return{text:e};if(1===n)return{text:e,title:r[0]};if(2===n)return d(n,r),{icon:e};f(e,n)}else{if(s&&0===n)return d(n,r),{content:e};if(o.isPlainObject(e))return p(n,r),e;f(e,n)}};e.getOpts=function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n={};t.forEach(function(e,o){var r=m(0,e,o,t);Object.assign(n,r)});var o=l(n);n.buttons=r.getButtonListOpts(o),delete n.button,n.content=i.getContentOpts(n.content);var u=Object.assign({},s,c,n);return Object.keys(u).forEach(function(t){a.DEPRECATED_OPTS[t]&&a.logDeprecation(t)}),u}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r={element:"input",attributes:{placeholder:""}};e.getContentOpts=function(t){var e={};return o.isPlainObject(t)?Object.assign(e,t):t instanceof Element?{element:t}:"input"===t?r:null}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.logDeprecation=function(t){var n=e.DEPRECATED_OPTS[t],o=n.onlyRename,r=n.replacement,i=n.subOption,a=n.link,s=o?"renamed":"deprecated",c='SweetAlert warning: "'+t+'" option has been '+s+".";if(r){c+=" Please use"+(i?' "'+i+'" in ':" ")+'"'+r+'" instead.'}var l="https://sweetalert.js.org";c+=a?" More details: "+l+a:" More details: "+l+"/guides/#upgrading-from-1x",console.warn(c)},e.DEPRECATED_OPTS={type:{replacement:"icon",link:"/docs/#icon"},imageUrl:{replacement:"icon",link:"/docs/#icon"},customClass:{replacement:"className",onlyRename:!0,link:"/docs/#classname"},imageSize:{},showCancelButton:{replacement:"buttons",link:"/docs/#buttons"},showConfirmButton:{replacement:"button",link:"/docs/#button"},confirmButtonText:{replacement:"button",link:"/docs/#button"},confirmButtonColor:{},cancelButtonText:{replacement:"buttons",link:"/docs/#buttons"},closeOnConfirm:{replacement:"button",subOption:"closeModal",link:"/docs/#button"},closeOnCancel:{replacement:"buttons",subOption:"closeModal",link:"/docs/#buttons"},showLoaderOnConfirm:{replacement:"buttons"},animation:{},inputType:{replacement:"content",link:"/docs/#content"},inputValue:{replacement:"content",link:"/docs/#content"},inputPlaceholder:{replacement:"content",link:"/docs/#content"},html:{replacement:"content",link:"/docs/#content"},allowEscapeKey:{replacement:"closeOnEsc",onlyRename:!0,link:"/docs/#closeonesc"},allowClickOutside:{replacement:"closeOnClickOutside",onlyRename:!0,link:"/docs/#closeonclickoutside"}}}])});
 
automatic-translator-addon-for-loco-translate.php CHANGED
@@ -1,20 +1,19 @@
1
  <?php
2
  /*
3
  Plugin Name:Automatic Translate Addon For Loco Translate
4
- Description:Auto language translator add-on for Loco Translate official plugin version 2.3.3 or lower to translate plugins and themes translation files into any language via fully automatic machine translations via IBM Watson Translate API.
5
- Version:1.9.1
6
  License:GPL2
7
  Text Domain:loco-translate-addon
8
  Domain Path:languages
9
  Author:Cool Plugins
10
  Author URI:https://coolplugins.net/
11
- */
12
  namespace LocoAutoTranslateAddon;
13
  use LocoAutoTranslateAddon\Helpers\Helpers;
14
- use LocoAutoTranslateAddon\Helpers\Atlt_rollback;
15
  /**
16
  * @package Loco Automatic Translate Addon
17
- * @version 1.9
18
  */
19
  if (!defined('ABSPATH')) {
20
  die('WordPress Environment Not Found!');
@@ -23,7 +22,7 @@ if (!defined('ABSPATH')) {
23
  define('ATLT_FILE', __FILE__);
24
  define('ATLT_URL', plugin_dir_url(ATLT_FILE));
25
  define('ATLT_PATH', plugin_dir_path(ATLT_FILE));
26
- define('ATLT_VERSION', '1.9.1');
27
 
28
  class LocoAutoTranslate
29
  {
@@ -33,64 +32,61 @@ class LocoAutoTranslate
33
  register_deactivation_hook( ATLT_FILE, array( $this, 'atlt_deactivate' ) );
34
  if(is_admin()){
35
 
36
- // Only loged in user can perform this AJAX request
37
- add_action('wp_ajax_atlt_rollback_request', array($this, 'atlt_rollback_request'));
38
- add_action('plugins_loaded', array($this, 'atlt_check_required_loco_plugin'));
39
- /*** Template Setting Page Link inside Plugins List */
40
- add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this,'atlt_settings_page_link'));
41
- add_action( 'admin_enqueue_scripts', array( $this,'atlt_enqueue_scripts') );
42
- add_action('wp_ajax_free_autotranslate_handler',array($this,'atlt_free_autotranslate_handler'), 100);
43
- add_action('wp_ajax_free_test_api_provider',array($this,'atlt_free_test_api_provider'));
44
- add_action('init',array($this,'checkStatus'));
45
- add_action('init',array($this,'updateSettings'));
46
- add_action('plugins_loaded', array($this,'include_files'));
47
- }
48
- }
49
-
50
- /**
51
- * This function hooked with AJAX to rollback loco translate plugin
52
- */
53
- public function atlt_rollback_request(){
54
-
55
- require ATLT_PATH . 'includes/Helpers/Atlt_rollback.php';
56
- $request = new Atlt_rollback();
57
- $response = $request->rollback();
58
- die(json_encode($response) );
59
-
60
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- public function use_loco_autotranslate_notice(){
63
- //get the current screen
64
- $screen = get_current_screen();
65
- $show_in_screens = array('loco-translate_page_loco-atlt',
66
- 'loco-translate_page_loco-atlt-register',
67
- 'loco-translate_page_loco-plugin',
68
- 'loco-translate_page_loco-theme');
69
- //return if not plugin settings page
70
- //To get the exact your screen ID just do ver_dump($screen)
71
-
72
- $rollback_notice = '';
73
- if( $screen->id != 'loco-translate_page_loco-atlt' ){
74
- $link = admin_url( 'admin.php?page=loco-atlt' );
75
- $rollback_notice = __(' You can rollback through <a href="'.$link.'">settings</a> page.', 'loco-translate-addon');
76
  }
77
 
78
- if (in_array($screen->id, $show_in_screens ) )
79
- {
80
- $loco_vesion=loco_plugin_version();
81
- if (version_compare( $loco_vesion, '2.4', '>=')) {
82
- if (current_user_can('activate_plugins')) {
83
- $url= admin_url( 'admin.php?page=loco-config&action=apis');
84
- echo '<div class="error"><p style="font-size:16px;">' .
85
- sprintf(__(
86
- '<strong style="color:red">Notice from <a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/" target="_blank">Loco Addon</a> Owner:</strong> <strong>Automatic Translate Addon For Loco Translate</strong> is only compatible with Loco Translate official plugin version <strong>2.3.3</strong> or lower. Currently you are using Loco Translate official plugin version 2.4.0 or higher. Please rollback to use all features of automatic translate addon.'.$rollback_notice,
87
- 'loco-translate-addon'),
88
- esc_url($url)
89
- ) . '</p></div>';
90
- }
91
- }
92
- }
93
- }
94
  // update settings
95
  public function updateSettings(){
96
  if(get_option( 'atlt-ratingDiv')){
@@ -102,7 +98,6 @@ class LocoAutoTranslate
102
  * create 'settings' link in plugins page
103
  */
104
  public function atlt_settings_page_link($links){
105
- $links[] = '<a style="font-weight:bold" href="'. esc_url( get_admin_url(null, 'admin.php?page=loco-atlt') ) .'">Settings</a>';
106
  $links[] = '<a style="font-weight:bold" href="'. esc_url( get_admin_url(null, 'admin.php?page=loco-atlt-register') ) .'">License</a>';
107
  return $links;
108
  }
@@ -117,133 +112,14 @@ class LocoAutoTranslate
117
 
118
  if ( is_admin() ) {
119
  include_once ATLT_PATH .'includes/Helpers/Helpers.php';
120
- include_once ATLT_PATH . 'includes/Core/class.settings-api.php';
121
- include_once ATLT_PATH . 'includes/Core/class.settings-panel.php';
122
- new Core\Settings_Panel();
123
  include_once ATLT_PATH . "includes/ReviewNotice/class.review-notice.php";
124
  new ALTLReviewNotice\ALTLReviewNotice();
125
  include_once ATLT_PATH . 'includes/Feedback/class.feedback-form.php';
126
  new FeedbackForm\FeedbackForm();
127
  include_once ATLT_PATH . 'includes/Register/LocoAutomaticTranslateAddonPro.php';
128
-
129
- include_once ATLT_PATH .'includes/ibm-translator/class.ibm-translator.php';
130
  }
131
 
132
  }
133
- /*
134
- |----------------------------------------------------------------------
135
- | Ajax callback handler
136
- |----------------------------------------------------------------------
137
- */
138
- public function atlt_free_autotranslate_handler()
139
- {
140
- // verify request
141
- if ( ! wp_verify_nonce($_REQUEST['nonce'], 'atlt_nonce' ) ) {
142
- echo $this->errorResponse('Request Time Out. Please refresh your browser window.');
143
- die();
144
- } else {
145
- // user status
146
- $status=Helpers::atltVerification();
147
- if($status['type']=="free" && $status['allowed']=="no"){
148
- echo $this->errorResponse('You have consumed API daily limit');
149
- die();
150
- }
151
-
152
- // get request vars
153
- if (empty($_REQUEST['data'])) {
154
- echo $this->errorResponse('No String Found');
155
- die();
156
- }
157
- if(isset($_REQUEST['data'])){
158
- $responseArr=array();
159
- $response=array();
160
- $requestData = $_REQUEST['data'];
161
- $targetLang=$_REQUEST['targetLan'];
162
- $sourceLang=$_REQUEST['sourceLan'];
163
- if($targetLang=="nb" || $targetLang=="nn"){
164
- $targetLang="no";
165
- }
166
- $request_chars = $_REQUEST['requestChars'];
167
- $totalChars = $_REQUEST['totalCharacters'];
168
- $requestType=$_REQUEST['strType'];
169
- $apiType=$_REQUEST['apiType'];
170
- $stringArr= json_decode(stripslashes($requestData),true);
171
-
172
- if($apiType=="yandex"){
173
- // grab API keys
174
- $api_key = Helpers::getAPIkey("yandex");
175
- if(empty($api_key)|| $api_key==""){
176
- echo $this->errorResponse('You have not Entered yandex API Key');
177
- die();
178
- }
179
- $apiKey = $api_key;
180
- if(Helpers::yandexSLangList($targetLang)==false){
181
- echo $this->errorResponse('Yandex Translator Does not support this language');
182
- die();
183
- }
184
- if(is_array( $stringArr)&& !empty($stringArr))
185
- {
186
- $response=$this->yandex_api_call($stringArr,$targetLang,$sourceLang,$requestType,$apiKey);
187
- if(is_array($response) && $response['code']==200)
188
- {
189
- // grab translation count data
190
- $responseArr['code']=200;
191
- $responseArr['translatedString']= $response['text'];
192
- $responseArr['stats']= $this->saveStringsCount($request_chars,$totalChars,$apiType);
193
- }else if(isset($response['code'])){
194
- $responseArr['code']=$response['code'];
195
- $responseArr['error']=$response['message'];
196
- }else{
197
- $responseArr['error']=$response;
198
- $responseArr['code']=500;
199
- }
200
- }
201
- }else{
202
- // grab API keys
203
- $api_key = Helpers::getAPIkey("ibm");
204
- if(empty($api_key)|| $api_key==""){
205
- echo $this->errorResponse('You have not Entered IBM API Key');
206
- die();
207
- }
208
- $apiKey = $api_key;
209
- $keys_arr= get_option('atlt_register');
210
- if(isset($keys_arr['atlt_ibm-translate-url'])){
211
- $args['base'] =$keys_arr['atlt_ibm-translate-url'].'/v3/translate?version=2018-05-01';
212
- }
213
- if(Helpers::ibmSLangList($targetLang)==false){
214
- echo $this->errorResponse('IBM Translator Does not support this language');
215
- die();
216
- }
217
- if(is_array( $stringArr)&& !empty($stringArr))
218
- {
219
- $args['key']= $apiKey;
220
- $args['from']=$sourceLang;
221
- $args['to']=$targetLang;
222
- $args['text']=$stringArr;
223
- $ibm_obj= new ibmTranslator();
224
- $response=$ibm_obj->translate($args);
225
- if(is_array($response) && $response['code']==200)
226
- {
227
- // grab translation count data
228
- $responseArr['code']=200;
229
- $responseArr['translatedString']= $response['translation'];
230
- $responseArr['stats']= $this->saveStringsCount($request_chars,$totalChars,$apiType);
231
- }else if(isset($response['code'])){
232
- $responseArr['code']=$response['code'];
233
- $responseArr['error']=$response['error'];
234
- }else{
235
- $responseArr['error']=$response;
236
- $responseArr['code']=500;
237
- }
238
-
239
- }
240
- }
241
-
242
- die(json_encode($responseArr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
243
- }
244
- }
245
- }
246
-
247
 
248
  /*
249
  |----------------------------------------------------------------------
@@ -251,12 +127,47 @@ class LocoAutoTranslate
251
  |----------------------------------------------------------------------
252
  */
253
  public function checkStatus(){
254
- Helpers::checkPeriod();
255
  $key=Helpers::getLicenseKey();
256
  if(Helpers::validKey( $key) && Helpers::proInstalled()==false){
257
  add_action('admin_notices', array($this, 'atlt_pro_install_notice'));
258
  }
259
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  /*
261
  |----------------------------------------------------------------------
262
  | check if required "Loco Translate" plugin is active
@@ -268,10 +179,6 @@ class LocoAutoTranslate
268
  if (!function_exists('loco_plugin_self')) {
269
  add_action('admin_notices', array($this, 'atlt_plugin_required_admin_notice'));
270
  }
271
-
272
- if (function_exists('loco_plugin_self')) {
273
- add_action('admin_notices',array($this,'use_loco_autotranslate_notice'));
274
- }
275
  load_plugin_textdomain('loco-translate-addon', false, basename(dirname(__FILE__)) . '/languages/');
276
  }
277
 
@@ -282,7 +189,6 @@ class LocoAutoTranslate
282
  */
283
  public function atlt_pro_install_notice()
284
  {
285
-
286
  if (current_user_can('activate_plugins')) {
287
  $key=Helpers::getLicenseKey();
288
  $url =esc_url( add_query_arg( 'license-key',$key , 'https://locoaddon.com/data/download-plugin.php' ) );
@@ -328,265 +234,76 @@ class LocoAutoTranslate
328
  }
329
  }
330
 
331
- /*
332
- |----------------------------------------------------------------------
333
- | Verify API's working or not
334
- |----------------------------------------------------------------------
335
- */
336
- public function atlt_free_test_api_provider(){
337
- if ( ! wp_verify_nonce($_REQUEST['nonce'], 'atlt_nonce' ) ) {
338
- die(json_encode(array('code' =>500, 'message' => 'Request Time Out. Please refresh your browser window.')));
339
- } else {
340
- $text = $_REQUEST['text'];
341
- $targetLang=$_REQUEST['target'];
342
- $sourceLang=$_REQUEST['source'];
343
- $apikey=$_REQUEST['apikey'];
344
- $apiType=$_REQUEST['apiprovider'];
345
-
346
- if( $apiType=="yandex"){
347
-
348
- $strArr[]=$text;
349
- $requestType="plain";
350
- $response=$this->yandex_api_call(
351
- $strArr,$targetLang,$sourceLang,$requestType,$apikey);
352
- $responseArr['response']=$response;
353
- if(is_array($response) && $response['code']==200)
354
- {
355
- // grab translation count data
356
- $responseArr['code']=200;
357
- $responseArr['translatedString']= $response['text'];
358
- }else if(isset($response['code']) && isset($response['message'])){
359
- $responseArr['code']= $response['code'];
360
- $responseArr['error']= $response['message'];
361
- }else{
362
- $responseArr['code']=500;
363
- $responseArr['error']= $response;
364
- }
365
- }else{
366
- $strArr[]=$text;
367
- $args['from']=$sourceLang;
368
- $args['to']=$targetLang;
369
- $args['text']=$strArr;
370
-
371
- $keys_arr= get_option('atlt_register');
372
- if(isset($keys_arr['atlt_ibm-translate-url'])){
373
- $args['base'] =$keys_arr['atlt_ibm-translate-url'].'/v3/translate?version=2018-05-01';
374
- }
375
- $args['key'] = $apikey;
376
- $ibm_obj= new ibmTranslator();
377
- $response=$ibm_obj->translate($args);
378
- if(is_array($response) && $response['code']==200)
379
- {
380
- // grab translation count data
381
- $responseArr['code']=200;
382
- $responseArr['translatedString']= $response['translation'];
383
- }else if(isset($response['code']) && isset($response['error'])){
384
- $responseArr['code']= $response['code'];
385
- $responseArr['error']= $response['error'];
386
- }else{
387
- $responseArr['code']=500;
388
- $responseArr['error']= $response;
389
- }
390
-
391
- }
392
- die(json_encode($responseArr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
393
- }
394
- }
395
-
396
- /*
397
- |----------------------------------------------------------------------
398
- | error response creator
399
- |----------------------------------------------------------------------
400
- */
401
- public function errorResponse($message){
402
- $error=[];
403
- if($message){
404
- $error['error']['code']=800;
405
- $error['error']['message']=$message;
406
- }
407
- return json_encode($error);
408
- }
409
-
410
- /*
411
- |----------------------------------------------------------------------
412
- | Save string usage
413
- |----------------------------------------------------------------------
414
- */
415
- public function saveStringsCount($request_chars,$totalChars,$apiType)
416
- {
417
-
418
- if($apiType=="yandex"){
419
- $today_translated = Helpers::ytodayTranslated( $request_chars);
420
- $monthly_translated = Helpers::ymonthlyTranslated( $request_chars);
421
- /** Calculate the total time save on translation */
422
- $session_time_saved = Helpers::atlt_time_saved_on_translation( $totalChars);
423
- $total_time_saved = Helpers::atlt_time_saved_on_translation($totalChars);
424
- // create response array
425
- $stats=array(
426
- 'todays_translation'=>$today_translated,
427
- 'total_translation'=>$monthly_translated,
428
- 'time_saved'=> $session_time_saved,
429
- 'total_time_saved'=>$total_time_saved,
430
- 'totalChars'=>$totalChars
431
- );
432
- }else{
433
- $today_translated = Helpers::iTodayTranslated( $request_chars);
434
- $monthly_translated = Helpers::iMonthlyTranslated( $request_chars);
435
- /** Calculate the total time save on translation */
436
- $session_time_saved = Helpers::atlt_time_saved_on_translation( $totalChars);
437
- $total_time_saved = Helpers::atlt_time_saved_on_translation($totalChars);
438
- // create response array
439
- $stats=array(
440
- 'todays_translation'=>$today_translated,
441
- 'total_translation'=>$monthly_translated,
442
- 'time_saved'=> $session_time_saved,
443
- 'total_time_saved'=>$total_time_saved,
444
- 'totalChars'=>$totalChars
445
- );
446
- }
447
- return $stats;
448
- }
449
-
450
- /*
451
- |------------------------------------------------------
452
- | Send Request to yandex API
453
- |------------------------------------------------------
454
- */
455
- public function yandex_api_call($stringArr,$target_language,$source_language,$requestType,$apiKey){
456
- // create query string
457
- $queryString='';
458
- $langParam = $source_language.'-'.$target_language;
459
-
460
- if(is_array($stringArr)){
461
- foreach($stringArr as $str){
462
- $queryString.='&text='.urlencode($str);
463
- }
464
- }
465
- // build query
466
- $buildReqURL='';
467
- $buildReqURL.='https://translate.yandex.net/api/v1.5/tr.json/translate';
468
- $buildReqURL.='?key=' . $apiKey . '&lang=' . $langParam.'&format='.$requestType;
469
- $buildReqURL.=$queryString;
470
- // get API response
471
- $response = wp_remote_get($buildReqURL, array('timeout'=>'180'));
472
-
473
- if (is_wp_error($response)) {
474
- return $response->get_error_message();; // Bail early
475
- }
476
- $body = wp_remote_retrieve_body($response);
477
- // convert string into assoc array
478
- $data = json_decode( $body, true);
479
- return $data;
480
- }
481
-
482
  /*
483
  |------------------------------------------------------------------------
484
  | Enqueue required JS file
485
  |------------------------------------------------------------------------
486
  */
487
  function atlt_enqueue_scripts(){
 
488
  wp_deregister_script('loco-js-editor');
489
- wp_register_script( 'sweet-alert', ATLT_URL.'assets/sweetalert/sweetalert.min.js', array('loco-js-min-admin'),false, true);
490
- //sweet alert for settings panel
491
- wp_register_script( 'settings-sweet-alert', ATLT_URL.'assets/sweetalert/sweetalert.min.js',array('jquery'),false, true);
492
- wp_register_script( 'test-api', ATLT_URL.'assets/js/api-testing.js', array('jquery','settings-sweet-alert'));
493
- wp_register_script( 'atlt-rollback', ATLT_URL.'assets/js/atlt-rollback.js', array('jquery'));
494
- if(Helpers::userType()=="free"){
495
- wp_register_script( 'loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.js', array('loco-js-min-admin'),ATLT_VERSION, true);
496
- }else{
 
 
 
 
 
 
 
 
 
497
  // if PRO version is installed then load assets
498
  if(Helpers::proInstalled() && version_compare(ATLT_PRO_VERSION,'1.1', '>=')){
499
- wp_register_script( 'loco-js-editor', ATLT_PRO_URL.'assets/js/loco-js-editor.js', array('loco-js-min-admin'),ATLT_PRO_VERSION, true);
500
- wp_register_script( 'loco-addon-custom', ATLT_PRO_URL.'assets/js/custom.js', array('loco-js-min-admin'),ATLT_PRO_VERSION, true);
501
- wp_register_style('loco-addon-custom-css', ATLT_PRO_URL.'assets/css/custom.css',null,
502
- ATLT_PRO_VERSION,'all');
 
503
  }else{
504
- wp_register_script( 'loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.js', array('loco-js-min-admin'),ATLT_VERSION, true);
 
 
505
  }
506
  }
507
 
508
-
509
  if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit')
510
  {
511
- $data=array();
512
- wp_enqueue_script('sweet-alert');
 
 
 
 
513
  if(Helpers::userType()=="pro"){
514
- wp_enqueue_script('loco-addon-custom');
515
- wp_enqueue_style('loco-addon-custom-css');
516
  }
517
- wp_enqueue_script('loco-js-editor');
518
-
519
  $status=Helpers::atltVerification();
520
- $data['api_key']['yApiKey']=Helpers::getAPIkey("yandex");
521
- $data['info']['yAvailableChars']=Helpers::getAvailableChars("yandex");
522
-
523
- $data['api_key']['ibmApiKey']=Helpers::getAPIkey("ibm");
524
- $data['info']['iAvailableChars']=Helpers::getAvailableChars("ibm");
525
 
526
- $data['nonce']= wp_create_nonce('atlt_nonce');
527
- $data['endpoint']='free_autotranslate_handler';
528
- // @since version 1.7.1
529
- $settings=get_option('atlt_register');
530
-
531
- if(isset($settings['atlt_ibm-translate-url'])){
532
- $data['info']['ibm_url']=$settings['atlt_ibm-translate-url'];
533
- }else{
534
- $data['info']['ibm_url']=false;
535
- }
536
- $index_per_request=isset($settings['atlt_index-per-request'])?$settings['atlt_index-per-request']:50;
537
- $data['api_key']['atlt_index-per-request']=$index_per_request;
538
-
539
- if($status['type']=="free"){
540
- $info=Helpers::atltVerification();
541
- $data['info']['type']= $info['type'];
542
- $data['info']['total']= $info['total'];
543
- if(isset($info['today'])){
544
- $data['info']['today']= $info['today'];
545
- }
546
- $data['info']['allowed']= $info['allowed'];
547
- }else{
548
- $data['api_key']['gApiKey']=Helpers::getAPIkey("google");
549
- $data['api_key']['mApiKey']=Helpers::getAPIkey("microsoft");
550
- $key=Helpers::getLicenseKey();
551
- if(Helpers::validKey( $key)){
552
- $data['info']['type']="pro";
553
- $data['info']['allowed']="yes";
554
- $data['info']['licenseKey']=$key;
555
- $data['info']['gAvailableChars']=Helpers::getAvailableChars("google");
556
- $data['info']['mAvailableChars']=Helpers::getAvailableChars("microsoft");
557
- if(Helpers::proInstalled()==false){
558
- $data['info']['proInstalled']="no";
559
- }else{
560
- $data['info']['proInstalled']="yes";
561
- $data['endpoint']='pro_autotranslate_handler';
562
- }
563
- }
564
- }
565
  $extraData['preloader_path']=ATLT_URL.'/assets/images/preloader.gif';
566
  $extraData['gt_preview']=ATLT_URL.'/assets/images/powered-by-google.png';
567
- wp_localize_script('loco-js-editor', 'ATLT', $data);
568
- wp_localize_script('loco-js-editor', 'extradata', $extraData);
569
-
570
- if(Helpers::proInstalled() && version_compare(ATLT_PRO_VERSION,'1.1', '>=')){
571
- wp_localize_script('loco-addon-custom', 'ATLT', $data);
572
- wp_localize_script('loco-addon-custom', 'extradata', $extraData);
573
- }
574
- }
575
- if (isset($_REQUEST['page']) && $_REQUEST['page'] == 'loco-atlt')
576
- {
577
- wp_enqueue_script('settings-sweet-alert');
578
- wp_enqueue_script('test-api');
579
- wp_enqueue_script('atlt-rollback');
580
- wp_localize_script( 'atlt-rollback', 'atlt_rollback',array('key'=> wp_create_nonce('atlt_nounce_rollback_loco')) );
581
- }
582
 
 
 
 
583
  }
584
 
585
- /*
586
- |------------------------------------------------------
587
- | Plugin activation
588
- |------------------------------------------------------
589
- */
 
590
  public function atlt_activate(){
591
  $plugin_info = get_plugin_data(__FILE__, true, true);
592
  update_option('atlt_version', $plugin_info['Version'] );
1
  <?php
2
  /*
3
  Plugin Name:Automatic Translate Addon For Loco Translate
4
+ Description:Auto language translator add-on for Loco Translate official plugin version 2.4+ to translate plugins and themes translation files into any language via fully automatic machine translations via Yandex Translate Widget.
5
+ Version:2.0
6
  License:GPL2
7
  Text Domain:loco-translate-addon
8
  Domain Path:languages
9
  Author:Cool Plugins
10
  Author URI:https://coolplugins.net/
11
+ */
12
  namespace LocoAutoTranslateAddon;
13
  use LocoAutoTranslateAddon\Helpers\Helpers;
 
14
  /**
15
  * @package Loco Automatic Translate Addon
16
+ * @version 2.0
17
  */
18
  if (!defined('ABSPATH')) {
19
  die('WordPress Environment Not Found!');
22
  define('ATLT_FILE', __FILE__);
23
  define('ATLT_URL', plugin_dir_url(ATLT_FILE));
24
  define('ATLT_PATH', plugin_dir_path(ATLT_FILE));
25
+ define('ATLT_VERSION', '2.0');
26
 
27
  class LocoAutoTranslate
28
  {
32
  register_deactivation_hook( ATLT_FILE, array( $this, 'atlt_deactivate' ) );
33
  if(is_admin()){
34
 
35
+ // Only loged in user can perform this AJAX request
36
+ add_action('plugins_loaded', array($this, 'atlt_check_required_loco_plugin'));
37
+ /*** Template Setting Page Link inside Plugins List */
38
+ add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this,'atlt_settings_page_link'));
39
+ add_action( 'admin_enqueue_scripts', array( $this,'atlt_enqueue_scripts') );
40
+ add_action('init',array($this,'checkStatus'));
41
+ add_action('init',array($this,'updateSettings'));
42
+ //add notice to use latest loco translate addon
43
+ add_action('init',array($this,'useLatestVersionNotice'));
44
+ add_action('plugins_loaded', array($this,'include_files'));
45
+
46
+ /*
47
+ since version 2.0
48
+ Yandex translate widget integration
49
+ */
50
+ // add no translate attribute in html tag
51
+ if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit')
52
+ {
53
+ add_action('admin_footer', array($this,'load_ytranslate_scripts'),100);
54
+ }
55
+
56
+ /* since version 2.0 */
57
+ add_filter('script_loader_tag',array($this,'custom_remove_scripts'), 11, 2);
58
+ }
59
  }
60
+ /* Remove loco translate editor js file
61
+ since version 2.0
62
+ Created By:-Jyoti
63
+ */
64
+ function custom_remove_scripts($link, $handle) {
65
+ if( !file_exists( WP_PLUGIN_DIR . '/loco-translate/loco.php' ) ){
66
+ return $link;
67
+ }
68
+ $site_url = get_site_url();
69
+ $loco_info = get_plugin_data( WP_PLUGIN_DIR . '/loco-translate/loco.php' , false, false );
70
+ $loco_ver = $loco_info['Version'];
71
+ $urls = array(
72
+ $site_url.'/wp-content/plugins/loco-translate/pub/js/min/editor.js?ver='.$loco_ver.''
73
+ );
74
+ foreach ($urls as $url) {
75
+ if (strstr($link, $url)) {$link = '';}
76
+ }
77
+ return $link;
78
+ }
79
 
80
+ /*
81
+ |----------------------------------------------------------------------
82
+ | Yandex Translate Widget Integartions
83
+ |----------------------------------------------------------------------
84
+ */
85
+ // load google translate widget scripts
86
+ function load_ytranslate_scripts() {
87
+ echo"<script>document.getElementsByTagName('html')[0].setAttribute('translate', 'no');</script>";
 
 
 
 
 
 
88
  }
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  // update settings
91
  public function updateSettings(){
92
  if(get_option( 'atlt-ratingDiv')){
98
  * create 'settings' link in plugins page
99
  */
100
  public function atlt_settings_page_link($links){
 
101
  $links[] = '<a style="font-weight:bold" href="'. esc_url( get_admin_url(null, 'admin.php?page=loco-atlt-register') ) .'">License</a>';
102
  return $links;
103
  }
112
 
113
  if ( is_admin() ) {
114
  include_once ATLT_PATH .'includes/Helpers/Helpers.php';
 
 
 
115
  include_once ATLT_PATH . "includes/ReviewNotice/class.review-notice.php";
116
  new ALTLReviewNotice\ALTLReviewNotice();
117
  include_once ATLT_PATH . 'includes/Feedback/class.feedback-form.php';
118
  new FeedbackForm\FeedbackForm();
119
  include_once ATLT_PATH . 'includes/Register/LocoAutomaticTranslateAddonPro.php';
 
 
120
  }
121
 
122
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  /*
125
  |----------------------------------------------------------------------
127
  |----------------------------------------------------------------------
128
  */
129
  public function checkStatus(){
130
+
131
  $key=Helpers::getLicenseKey();
132
  if(Helpers::validKey( $key) && Helpers::proInstalled()==false){
133
  add_action('admin_notices', array($this, 'atlt_pro_install_notice'));
134
  }
135
  }
136
+
137
+ /*
138
+ |----------------------------------------------------------------------
139
+ | check User Status
140
+ |----------------------------------------------------------------------
141
+ */
142
+ public function useLatestVersionNotice(){
143
+ if(function_exists('loco_plugin_version')){
144
+ $locoV=loco_plugin_version();
145
+ if(version_compare($locoV,'2.4.0', '<'))
146
+ {
147
+ add_action('admin_notices', array($this, 'atlt_use_latest_admin_notice'));
148
+ }
149
+ }
150
+ }
151
+
152
+ /*
153
+ |----------------------------------------------------------------------
154
+ | Notice to use latest version of Loco Translate plugin
155
+ |----------------------------------------------------------------------
156
+ */
157
+ public function atlt_use_latest_admin_notice()
158
+ {
159
+ if (current_user_can('activate_plugins')) {
160
+ $url = 'plugin-install.php?tab=plugin-information&plugin=loco-translate&TB_iframe=true';
161
+ $title = "Loco Translate";
162
+ $plugin_info = get_plugin_data(__FILE__, true, true);
163
+ echo '<div class="error"><p>' .
164
+ sprintf(__('In order to use <strong>%s</strong> (version <strong>%s</strong>), Please update <a href="%s" class="thickbox" title="%s">%s</a> official plugin to a latest version (2.4.0 or upper)',
165
+ 'loco-translate-addon'),
166
+ $plugin_info['Name'], $plugin_info['Version'], esc_url($url),
167
+ esc_attr($title), esc_attr($title)) . '.</p></div>';
168
+
169
+ }
170
+ }
171
  /*
172
  |----------------------------------------------------------------------
173
  | check if required "Loco Translate" plugin is active
179
  if (!function_exists('loco_plugin_self')) {
180
  add_action('admin_notices', array($this, 'atlt_plugin_required_admin_notice'));
181
  }
 
 
 
 
182
  load_plugin_textdomain('loco-translate-addon', false, basename(dirname(__FILE__)) . '/languages/');
183
  }
184
 
189
  */
190
  public function atlt_pro_install_notice()
191
  {
 
192
  if (current_user_can('activate_plugins')) {
193
  $key=Helpers::getLicenseKey();
194
  $url =esc_url( add_query_arg( 'license-key',$key , 'https://locoaddon.com/data/download-plugin.php' ) );
234
  }
235
  }
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  /*
238
  |------------------------------------------------------------------------
239
  | Enqueue required JS file
240
  |------------------------------------------------------------------------
241
  */
242
  function atlt_enqueue_scripts(){
243
+
244
  wp_deregister_script('loco-js-editor');
245
+ // copy object
246
+ wp_add_inline_script( 'loco-translate-js-admin', 'var loco = window.locoScope;
247
+ var target={};
248
+ var returnedTarget = Object.assign(target, window.locoConf);
249
+ window.conf=returnedTarget;' );
250
+
251
+ // load yandex widget
252
+ wp_register_script( 'atlt-yandex-widget', ATLT_URL.'assets/js/widget.js?widgetId=ytWidget&pageLang=en&widgetTheme=light&autoMode=false',array('jquery'),ATLT_VERSION, true);
253
+
254
+ if(Helpers::userType()=="free"){
255
+ // register styles
256
+ wp_register_style('loco-addon-custom-css', ATLT_URL.'assets/css/custom.min.css',null,
257
+ ATLT_VERSION,'all');
258
+ // wp_register_script( 'loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.js', array('loco-js-min-admin'),ATLT_VERSION, true);
259
+ wp_register_script( 'loco-addon-custom', ATLT_URL.'assets/js/custom.min.js', array('loco-translate-js-admin'),ATLT_VERSION, true);
260
+ wp_register_script( 'custom-loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.min.js', array('loco-translate-js-editor'),ATLT_VERSION, true);
261
+ }else{
262
  // if PRO version is installed then load assets
263
  if(Helpers::proInstalled() && version_compare(ATLT_PRO_VERSION,'1.1', '>=')){
264
+ wp_register_style('loco-addon-custom-css', ATLT_PRO_URL.'assets/css/custom.min.css',null,
265
+ ATLT_VERSION,'all');
266
+ wp_register_script( 'loco-addon-custom', ATLT_PRO_URL.'assets/js/custom.min.js', array('loco-translate-js-admin'),ATLT_PRO_VERSION, true);
267
+ wp_register_script( 'custom-loco-js-editor', ATLT_PRO_URL.'assets/js/loco-js-editor.min.js', array('loco-translate-js-editor'),ATLT_PRO_VERSION, true);
268
+ wp_register_script( 'sweet-alert', ATLT_PRO_URL.'assets/sweetalert/sweetalert.min.js', array('jquery'),ATLT_PRO_VERSION, true);
269
  }else{
270
+ // wp_register_script( 'loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.js', array('loco-js-min-admin'),ATLT_VERSION, true);
271
+ wp_register_script( 'loco-addon-custom', ATLT_URL.'assets/js/custom.min.js', array('loco-translate-js-admin'),ATLT_VERSION, true);
272
+ wp_register_script( 'custom-loco-js-editor', ATLT_URL.'assets/js/loco-js-editor.min.js', array('loco-translate-js-editor'),ATLT_VERSION, true);
273
  }
274
  }
275
 
276
+ // load assets only on editor page
277
  if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit')
278
  {
279
+ // load common assets
280
+ wp_enqueue_script('loco-addon-custom');
281
+ wp_enqueue_script('custom-loco-js-editor');
282
+ wp_enqueue_script('atlt-yandex-widget');
283
+ wp_enqueue_style('loco-addon-custom-css');
284
+
285
  if(Helpers::userType()=="pro"){
286
+ wp_enqueue_script('sweet-alert');
 
287
  }
288
+
 
289
  $status=Helpers::atltVerification();
 
 
 
 
 
290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  $extraData['preloader_path']=ATLT_URL.'/assets/images/preloader.gif';
292
  $extraData['gt_preview']=ATLT_URL.'/assets/images/powered-by-google.png';
293
+ $extraData['dpl_preview']=ATLT_URL.'/assets/images/powered-by-deepl.png';
294
+ $extraData['yt_preview']=ATLT_URL.'/assets/images/powered-by-yandex.png';
 
 
 
 
 
 
 
 
 
 
 
 
 
295
 
296
+ wp_localize_script('loco-addon-custom', 'extradata', $extraData);
297
+
298
+ }
299
  }
300
 
301
+
302
+ /*
303
+ |------------------------------------------------------
304
+ | Plugin activation
305
+ |------------------------------------------------------
306
+ */
307
  public function atlt_activate(){
308
  $plugin_info = get_plugin_data(__FILE__, true, true);
309
  update_option('atlt_version', $plugin_info['Version'] );
includes/Core/class.settings-api.php DELETED
@@ -1,711 +0,0 @@
1
- <?php
2
-
3
- namespace LocoAutoTranslateAddon\Core;
4
-
5
- if ( !class_exists( 'Settings_API' ) ):
6
- class Settings_API {
7
- /**
8
- * settings sections array
9
- *
10
- * @var array
11
- */
12
- protected $settings_sections = array();
13
-
14
- /**
15
- * Settings fields array
16
- *
17
- * @var array
18
- */
19
- protected $settings_fields = array();
20
-
21
- public function __construct() {
22
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
23
- }
24
-
25
- /**
26
- * Enqueue scripts and styles
27
- */
28
- function admin_enqueue_scripts() {
29
- wp_enqueue_style( 'wp-color-picker' );
30
-
31
- wp_enqueue_media();
32
- wp_enqueue_script( 'wp-color-picker' );
33
- wp_enqueue_script( 'jquery' );
34
- wp_enqueue_style('atlt-custom-style', ATLT_URL.'/assets/admin/custom-styles.css', null);
35
-
36
- }
37
-
38
- /**
39
- * Set settings sections
40
- *
41
- * @param array $sections setting sections array
42
- */
43
- function set_sections( $sections ) {
44
- $this->settings_sections = $sections;
45
-
46
- return $this;
47
- }
48
-
49
- /**
50
- * Add a single section
51
- *
52
- * @param array $section
53
- */
54
- function add_section( $section ) {
55
- $this->settings_sections[] = $section;
56
-
57
- return $this;
58
- }
59
-
60
- /**
61
- * Set settings fields
62
- *
63
- * @param array $fields settings fields array
64
- */
65
- function set_fields( $fields ) {
66
- $this->settings_fields = $fields;
67
-
68
- return $this;
69
- }
70
-
71
- function add_field( $section, $field ) {
72
- $defaults = array(
73
- 'name' => '',
74
- 'label' => '',
75
- 'desc' => '',
76
- 'type' => 'text'
77
- );
78
-
79
- $arg = wp_parse_args( $field, $defaults );
80
- $this->settings_fields[$section][] = $arg;
81
-
82
- return $this;
83
- }
84
-
85
- /**
86
- * Initialize and registers the settings sections and fileds to WordPress
87
- *
88
- * Usually this should be called at `admin_init` hook.
89
- *
90
- * This function gets the initiated settings sections and fields. Then
91
- * registers them to WordPress and ready for use.
92
- */
93
- function admin_init() {
94
- //register settings sections
95
- foreach ( $this->settings_sections as $section ) {
96
- if ( false == get_option( $section['id'] ) ) {
97
- add_option( $section['id'] );
98
- }
99
-
100
- if ( isset($section['desc']) && !empty($section['desc']) ) {
101
- $section['desc'] = '<div class="inside">' . $section['desc'] . '</div>';
102
- $callback = function() use ( $section ) {
103
- echo str_replace( '"', '\"', $section['desc'] );
104
- };
105
- } else if ( isset( $section['callback'] ) ) {
106
- $callback = $section['callback'];
107
- } else {
108
- $callback = null;
109
- }
110
-
111
- add_settings_section( $section['id'], $section['title'], $callback, $section['id'] );
112
- }
113
-
114
- //register settings fields
115
- foreach ( $this->settings_fields as $section => $field ) {
116
- foreach ( $field as $option ) {
117
-
118
- $name = $option['name'];
119
- $type = isset( $option['type'] ) ? $option['type'] : 'text';
120
- $label = isset( $option['label'] ) ? $option['label'] : '';
121
- $callback = isset( $option['callback'] ) ? $option['callback'] : array( $this, 'callback_' . $type );
122
-
123
- $args = array(
124
- 'id' => $name,
125
- 'class' => isset( $option['class'] ) ? $option['class'] : $name,
126
- 'label_for' => "{$section}[{$name}]",
127
- 'desc' => isset( $option['desc'] ) ? $option['desc'] : '',
128
- 'name' => $label,
129
- 'section' => $section,
130
- 'size' => isset( $option['size'] ) ? $option['size'] : null,
131
- 'options' => isset( $option['options'] ) ? $option['options'] : '',
132
- 'std' => isset( $option['default'] ) ? $option['default'] : '',
133
- 'sanitize_callback' => isset( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : '',
134
- 'type' => $type,
135
- 'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : '',
136
- 'min' => isset( $option['min'] ) ? $option['min'] : '',
137
- 'max' => isset( $option['max'] ) ? $option['max'] : '',
138
- 'step' => isset( $option['step'] ) ? $option['step'] : '',
139
- );
140
-
141
- add_settings_field( "{$section}[{$name}]", $label, $callback, $section, $section, $args );
142
- }
143
- }
144
-
145
- // creates our settings in the options table
146
- foreach ( $this->settings_sections as $section ) {
147
- register_setting( $section['id'], $section['id'], array( $this, 'sanitize_options' ) );
148
- }
149
- }
150
-
151
- /**
152
- * Get field description for display
153
- *
154
- * @param array $args settings field args
155
- */
156
- public function get_field_description( $args ) {
157
- if ( ! empty( $args['desc'] ) ) {
158
- $desc = sprintf( '<p class="description">%s</p>', $args['desc'] );
159
- } else {
160
- $desc = '';
161
- }
162
-
163
- return $desc;
164
- }
165
-
166
- /**
167
- * Displays a text field for a settings field
168
- *
169
- * @param array $args settings field args
170
- */
171
- function callback_text( $args ) {
172
-
173
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
174
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
175
- $type = isset( $args['type'] ) ? $args['type'] : 'text';
176
- $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
177
-
178
- $html = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"%6$s/>', $type, $size, $args['section'], $args['id'], $value, $placeholder );
179
- $html .= $this->get_field_description( $args );
180
-
181
- echo $html;
182
- }
183
-
184
- /**
185
- * Displays a url field for a settings field
186
- *
187
- * @param array $args settings field args
188
- */
189
- function callback_url( $args ) {
190
- $this->callback_text( $args );
191
- }
192
-
193
- /**
194
- * Displays a number field for a settings field
195
- *
196
- * @param array $args settings field args
197
- */
198
- function callback_number( $args ) {
199
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
200
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
201
- $type = isset( $args['type'] ) ? $args['type'] : 'number';
202
- $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
203
- $min = ( $args['min'] == '' ) ? '' : ' min="' . $args['min'] . '"';
204
- $max = ( $args['max'] == '' ) ? '' : ' max="' . $args['max'] . '"';
205
- $step = ( $args['step'] == '' ) ? '' : ' step="' . $args['step'] . '"';
206
-
207
- $html = sprintf( '<input type="%1$s" class="%2$s-number" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"%6$s%7$s%8$s%9$s/>', $type, $size, $args['section'], $args['id'], $value, $placeholder, $min, $max, $step );
208
- $html .= $this->get_field_description( $args );
209
-
210
- echo $html;
211
- }
212
-
213
- /**
214
- * Displays a checkbox for a settings field
215
- *
216
- * @param array $args settings field args
217
- */
218
- function callback_checkbox( $args ) {
219
-
220
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
221
-
222
- $html = '<fieldset>';
223
- $html .= sprintf( '<label for="wpuf-%1$s[%2$s]">', $args['section'], $args['id'] );
224
- $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" />', $args['section'], $args['id'] );
225
- $html .= sprintf( '<input type="checkbox" class="checkbox" id="wpuf-%1$s[%2$s]" name="%1$s[%2$s]" value="on" %3$s />', $args['section'], $args['id'], checked( $value, 'on', false ) );
226
- $html .= sprintf( '%1$s</label>', $args['desc'] );
227
- $html .= '</fieldset>';
228
-
229
- echo $html;
230
- }
231
-
232
- /**
233
- * Displays a multicheckbox for a settings field
234
- *
235
- * @param array $args settings field args
236
- */
237
- function callback_multicheck( $args ) {
238
-
239
- $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
240
- $html = '<fieldset>';
241
- $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="" />', $args['section'], $args['id'] );
242
- foreach ( $args['options'] as $key => $label ) {
243
- $checked = isset( $value[$key] ) ? $value[$key] : '0';
244
- $html .= sprintf( '<label for="wpuf-%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
245
- $html .= sprintf( '<input type="checkbox" class="checkbox" id="wpuf-%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
246
- $html .= sprintf( '%1$s</label><br>', $label );
247
- }
248
-
249
- $html .= $this->get_field_description( $args );
250
- $html .= '</fieldset>';
251
-
252
- echo $html;
253
- }
254
-
255
- /**
256
- * Displays a radio button for a settings field
257
- *
258
- * @param array $args settings field args
259
- */
260
- function callback_radio( $args ) {
261
-
262
- $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
263
- $html = '<fieldset>';
264
-
265
- foreach ( $args['options'] as $key => $label ) {
266
- $html .= sprintf( '<label for="wpuf-%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
267
- $html .= sprintf( '<input type="radio" class="radio" id="wpuf-%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $value, $key, false ) );
268
- $html .= sprintf( '%1$s</label><br>', $label );
269
- }
270
-
271
- $html .= $this->get_field_description( $args );
272
- $html .= '</fieldset>';
273
-
274
- echo $html;
275
- }
276
-
277
- /**
278
- * Displays a selectbox for a settings field
279
- *
280
- * @param array $args settings field args
281
- */
282
- function callback_select( $args ) {
283
-
284
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
285
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
286
- $html = sprintf( '<select class="%1$s" name="%2$s[%3$s]" id="%2$s[%3$s]">', $size, $args['section'], $args['id'] );
287
-
288
- foreach ( $args['options'] as $key => $label ) {
289
- $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $value, $key, false ), $label );
290
- }
291
-
292
- $html .= sprintf( '</select>' );
293
- $html .= $this->get_field_description( $args );
294
-
295
- echo $html;
296
- }
297
-
298
- /**
299
- * Displays a textarea for a settings field
300
- *
301
- * @param array $args settings field args
302
- */
303
- function callback_textarea( $args ) {
304
-
305
- $value = esc_textarea( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
306
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
307
- $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="'.$args['placeholder'].'"';
308
-
309
- $html = sprintf( '<textarea rows="5" cols="55" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]"%4$s>%5$s</textarea>', $size, $args['section'], $args['id'], $placeholder, $value );
310
- $html .= $this->get_field_description( $args );
311
-
312
- echo $html;
313
- }
314
-
315
- /**
316
- * Displays the html for a settings field
317
- *
318
- * @param array $args settings field args
319
- * @return string
320
- */
321
- function callback_html( $args ) {
322
- echo $this->get_field_description( $args );
323
- }
324
-
325
- /**
326
- * Displays a rich text textarea for a settings field
327
- *
328
- * @param array $args settings field args
329
- */
330
- function callback_wysiwyg( $args ) {
331
-
332
- $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
333
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : '500px';
334
-
335
- echo '<div style="max-width: ' . $size . ';">';
336
-
337
- $editor_settings = array(
338
- 'teeny' => true,
339
- 'textarea_name' => $args['section'] . '[' . $args['id'] . ']',
340
- 'textarea_rows' => 10
341
- );
342
-
343
- if ( isset( $args['options'] ) && is_array( $args['options'] ) ) {
344
- $editor_settings = array_merge( $editor_settings, $args['options'] );
345
- }
346
-
347
- wp_editor( $value, $args['section'] . '-' . $args['id'], $editor_settings );
348
-
349
- echo '</div>';
350
-
351
- echo $this->get_field_description( $args );
352
- }
353
-
354
- /**
355
- * Displays a file upload field for a settings field
356
- *
357
- * @param array $args settings field args
358
- */
359
- function callback_file( $args ) {
360
-
361
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
362
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
363
- $id = $args['section'] . '[' . $args['id'] . ']';
364
- $label = isset( $args['options']['button_label'] ) ? $args['options']['button_label'] : __( 'Choose File' );
365
-
366
- $html = sprintf( '<input type="text" class="%1$s-text wpsa-url" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
367
- $html .= '<input type="button" class="button wpsa-browse" value="' . $label . '" />';
368
- $html .= $this->get_field_description( $args );
369
-
370
- echo $html;
371
- }
372
-
373
- /**
374
- * Displays a password field for a settings field
375
- *
376
- * @param array $args settings field args
377
- */
378
- function callback_password( $args ) {
379
-
380
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
381
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
382
-
383
- $html = sprintf( '<input type="password" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
384
- $html .= $this->get_field_description( $args );
385
-
386
- echo $html;
387
- }
388
-
389
- /**
390
- * Displays a color picker field for a settings field
391
- *
392
- * @param array $args settings field args
393
- */
394
- function callback_color( $args ) {
395
-
396
- $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
397
- $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
398
-
399
- $html = sprintf( '<input type="text" class="%1$s-text wp-color-picker-field" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" data-default-color="%5$s" />', $size, $args['section'], $args['id'], $value, $args['std'] );
400
- $html .= $this->get_field_description( $args );
401
-
402
- echo $html;
403
- }
404
-
405
-
406
- /**
407
- * Displays a select box for creating the pages select box
408
- *
409
- * @param array $args settings field args
410
- */
411
- function callback_pages( $args ) {
412
-
413
- $dropdown_args = array(
414
- 'selected' => esc_attr($this->get_option($args['id'], $args['section'], $args['std'] ) ),
415
- 'name' => $args['section'] . '[' . $args['id'] . ']',
416
- 'id' => $args['section'] . '[' . $args['id'] . ']',
417
- 'echo' => 0
418
- );
419
- $html = wp_dropdown_pages( $dropdown_args );
420
- echo $html;
421
- }
422
-
423
- /**
424
- * Sanitize callback for Settings API
425
- *
426
- * @return mixed
427
- */
428
- function sanitize_options( $options ) {
429
-
430
- if ( !$options ) {
431
- return $options;
432
- }
433
-
434
- foreach( $options as $option_slug => $option_value ) {
435
- $sanitize_callback = $this->get_sanitize_callback( $option_slug );
436
-
437
- // If callback is set, call it
438
- if ( $sanitize_callback ) {
439
- $options[ $option_slug ] = call_user_func( $sanitize_callback, $option_value );
440
- continue;
441
- }
442
- }
443
-
444
- return $options;
445
- }
446
-
447
- /**
448
- * Get sanitization callback for given option slug
449
- *
450
- * @param string $slug option slug
451
- *
452
- * @return mixed string or bool false
453
- */
454
- function get_sanitize_callback( $slug = '' ) {
455
- if ( empty( $slug ) ) {
456
- return false;
457
- }
458
-
459
- // Iterate over registered fields and see if we can find proper callback
460
- foreach( $this->settings_fields as $section => $options ) {
461
- foreach ( $options as $option ) {
462
- if ( $option['name'] != $slug ) {
463
- continue;
464
- }
465
-
466
- // Return the callback name
467
- return isset( $option['sanitize_callback'] ) && is_callable( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : false;
468
- }
469
- }
470
-
471
- return false;
472
- }
473
-
474
- /**
475
- * Get the value of a settings field
476
- *
477
- * @param string $option settings field name
478
- * @param string $section the section name this field belongs to
479
- * @param string $default default text if it's not found
480
- * @return string
481
- */
482
- function get_option( $option, $section, $default = '' ) {
483
-
484
- $options = get_option( $section );
485
-
486
- if ( isset( $options[$option] ) ) {
487
- return $options[$option];
488
- }
489
-
490
- return $default;
491
- }
492
-
493
- /**
494
- * Show navigations as tab
495
- *
496
- * Shows all the settings section labels as tab
497
- */
498
- function show_navigation() {
499
- $html = '<h2 class="nav-tab-wrapper">';
500
-
501
- $count = count( $this->settings_sections );
502
-
503
- // don't show the navigation if only one section exists
504
- if ( $count === 1 ) {
505
- return;
506
- }
507
-
508
- foreach ( $this->settings_sections as $tab ) {
509
- $html .= sprintf( '<a href="#%1$s" class="nav-tab" id="%1$s-tab">%2$s</a>', $tab['id'], $tab['title'] );
510
- }
511
-
512
- $html .= '</h2>';
513
-
514
- echo $html;
515
- }
516
-
517
- /**
518
- * Show the section settings forms
519
- *
520
- * This function displays every sections in a different form
521
- */
522
- function show_forms($savebtn='',$showSaveBtn=true) {
523
- ?>
524
- <div class="metabox-holder">
525
- <?php foreach ( $this->settings_sections as $form ) { ?>
526
- <div style="width:80%;float:left;" id="<?php echo $form['id']; ?>" class="group" style="display: none;">
527
- <form method="post" action="options.php">
528
- <?php
529
- do_action( 'wsa_form_top_' . $form['id'], $form );
530
- settings_fields( $form['id'] );
531
- do_settings_sections( $form['id'] );
532
- do_action( 'wsa_form_bottom_' . $form['id'], $form );
533
- if ( isset( $this->settings_fields[ $form['id'] ] ) ):
534
- ?>
535
- <div style="padding-left: 10px">
536
- <?php if($showSaveBtn==true) submit_button($savebtn); ?>
537
- </div>
538
- <?php endif; ?>
539
- </form>
540
- </div>
541
- <?php } ?>
542
- </div>
543
- <div style="max-width:320px;float:right;" class="loco-settings-custom-sidebar">
544
-
545
- <?php
546
- $license_key=get_option("LocoAutomaticTranslateAddonPro_lic_Key","");
547
- $is_pro_active=is_plugin_active('loco-automatic-translate-addon-pro/loco-automatic-translate-addon-pro.php');
548
- $license_type=get_option('atlt-type');
549
- $download_url =esc_url( add_query_arg( 'license-key',$license_key , 'https://locoaddon.com/data/download-plugin.php' ) );
550
-
551
- if($license_type=='pro' && $license_key!= '' && $is_pro_active) {
552
- ?>
553
- <h2>Welcome! Loco Automatic Translate Addon</h2>
554
- <p>Dear Premium User,<br/><br/>We know that machine translation is not perfect as compare to human translation but you can save a lot of your valuable time using automated translations. If you face any issue while using this plugin, you can contact our premium support staff below.</p>
555
- <p><a href="mailto:contact@coolplugins.net" class="button button-secondary">Contact@CoolPlugins.net</a></p>
556
- <p>We hope our plugin helped you a little by automating your plugins and themes strings translation process. If you like it, please share some feedback for our team below.</p>
557
- <p><a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post" class="button button-primary">Submit Review! ★★★★★</a></p>
558
- <h2>Important Notice & Links</h2>
559
- <p>Plugin do not provide any free translation limit, it only provides setting panel to use third party translate APIs. All free characters translation limit provided by third party translate API providers - <strong>Google, Microsoft, IBM etc.</strong> You can grab translate API keys from these providers by following below instructions.</p>
560
- <p><a style="font-size:12px" href="https://locoaddon.com/howto-generate-google-translate-api-key/" target="_blank" class="button button-secondary">Generate Google Translate API Key</a></p>
561
- <p><a style="font-size:12px" href="https://locoaddon.com/how-to-generate-microsoft-translator-api-key/" target="_blank" class="button button-secondary">Generate Microsoft Translate API Key</a></p>
562
- <p><a style="font-size:12px" href="https://www.ibm.com/in-en/cloud/watson-language-translator/pricing" target="_blank" class="button button-secondary">Generate IBM Translate API Key</a></p>
563
- <?php
564
- }
565
- else if($is_pro_active && $license_key== ''){
566
- ?>
567
- <h2>Enter License Key</h2>
568
- <p>Dear User,<br/><br/>You have installed and activated <strong>Loco Automatic Translate Addon Pro</strong> plugin but didn't enter pro license key. Please add pro license key to enjoy all premium features.</p>
569
- <p><a href="?page=loco-atlt-register" class="button button-primary">Enter License Key</a></p>
570
- <?php
571
- }
572
- else if($is_pro_active==false && $license_key!= ''){
573
- ?>
574
- <h2>Install Loco Automatic Translate Addon Pro</h2>
575
- <p>Dear User,<br/><br/>You have activated pro license but didn't install <strong>Loco Automatic Translate Addon Pro</strong> plugin files. Please install and activate Loco Automatic Translate Addon Pro to enjoy all premium features.</p>
576
- <p><a href="<?php echo $download_url ?>" target="_blank" class="button button-primary">Download Pro Plugin</a></p>
577
- <p>or visit<br/><a href="https://locoaddon.com/my-account/downloads/" target="_blank">https://locoaddon.com/my-account/downloads/</a></p>
578
- <?php
579
- }
580
- else {
581
- ?>
582
- <h2>Welcome! Loco Automatic Translate Addon</h2>
583
- <p>Dear User,<br/><br/>You are currently using Loco Automatic Translate Addon free license. If you face any issue, please submit a support ticket below.</p>
584
- <p><a href="https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/" target="_blank" class="button button-secondary">Submit Support Ticket</a><br/>(Response time - 4 to 7 days for free users)</p>
585
- <h2>Upgrade Pro! Use Awesome Features</h2>
586
- <ul>
587
- <li>Google Translate API.</li>
588
- <li>Microsoft Translate API.</li>
589
- <li>Google & Microsoft automated translations are 70% better than IBM.</li>
590
- <li>Google Translate provides 500,000 Char / Month free for automated translations while Microsoft Translate provides free 2,000,000 Char / Month</li>
591
- <li style="background:#fffb7a;">NEW - Use Google page translate button for unlimited translations without any API key.<br/>✅ Available Inside Pro Version 1.1<br/><span style="font-size:11px;font-weight:bold;">(Release date:- 27 June, 2020)</span></li>
592
- <li>Reset translations with one click.</li>
593
- <li>Regular updates with new features</li>
594
- <li>Premium support via email.</li>
595
- </ul>
596
- <p><a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/" target="_blank" class="button button-primary">Buy Pro ($18 - $88)</a></p>
597
- <?php
598
- }
599
- ?>
600
- </div>
601
-
602
- <?php
603
- $this->script();
604
- }
605
-
606
- /**
607
- * Tabbable JavaScript codes & Initiate Color Picker
608
- *
609
- * This code uses localstorage for displaying active tabs
610
- */
611
- function script() {
612
- ?>
613
- <script>
614
- jQuery(document).ready(function($) {
615
- //Initiate Color Picker
616
- $('.wp-color-picker-field').wpColorPicker();
617
-
618
- // Switches option sections
619
- $('.group').hide();
620
- var activetab = '';
621
- if (typeof(localStorage) != 'undefined' ) {
622
- activetab = localStorage.getItem("activetab");
623
- }
624
-
625
- //if url has section id as hash then set it as active or override the current local storage value
626
- if(window.location.hash){
627
- activetab = window.location.hash;
628
- if (typeof(localStorage) != 'undefined' ) {
629
- localStorage.setItem("activetab", activetab);
630
- }
631
- }
632
-
633
- if (activetab != '' && $(activetab).length ) {
634
- $(activetab).fadeIn();
635
- } else {
636
- $('.group:first').fadeIn();
637
- }
638
- $('.group .collapsed').each(function(){
639
- $(this).find('input:checked').parent().parent().parent().nextAll().each(
640
- function(){
641
- if ($(this).hasClass('last')) {
642
- $(this).removeClass('hidden');
643
- return false;
644
- }
645
- $(this).filter('.hidden').removeClass('hidden');
646
- });
647
- });
648
-
649
- if (activetab != '' && $(activetab + '-tab').length ) {
650
- $(activetab + '-tab').addClass('nav-tab-active');
651
- }
652
- else {
653
- $('.nav-tab-wrapper a:first').addClass('nav-tab-active');
654
- }
655
- $('.nav-tab-wrapper a').click(function(evt) {
656
- $('.nav-tab-wrapper a').removeClass('nav-tab-active');
657
- $(this).addClass('nav-tab-active').blur();
658
- var clicked_group = $(this).attr('href');
659
- if (typeof(localStorage) != 'undefined' ) {
660
- localStorage.setItem("activetab", $(this).attr('href'));
661
- }
662
- $('.group').hide();
663
- $(clicked_group).fadeIn();
664
- evt.preventDefault();
665
- });
666
-
667
- $('.wpsa-browse').on('click', function (event) {
668
- event.preventDefault();
669
-
670
- var self = $(this);
671
-
672
- // Create the media frame.
673
- var file_frame = wp.media.frames.file_frame = wp.media({
674
- title: self.data('uploader_title'),
675
- button: {
676
- text: self.data('uploader_button_text'),
677
- },
678
- multiple: false
679
- });
680
-
681
- file_frame.on('select', function () {
682
- attachment = file_frame.state().get('selection').first().toJSON();
683
- self.prev('.wpsa-url').val(attachment.url).change();
684
- });
685
-
686
- // Finally, open the modal
687
- file_frame.open();
688
- });
689
- });
690
- </script>
691
- <?php
692
- $this->_style_fix();
693
- }
694
-
695
- function _style_fix() {
696
- global $wp_version;
697
-
698
- if (version_compare($wp_version, '3.8', '<=')):
699
- ?>
700
- <style type="text/css">
701
- /** WordPress 3.8 Fix **/
702
- .form-table th { padding: 20px 10px; }
703
- #wpbody-content .metabox-holder { padding-top: 5px; }
704
- </style>
705
- <?php
706
- endif;
707
- }
708
-
709
- }
710
-
711
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Core/class.settings-panel.php DELETED
@@ -1,598 +0,0 @@
1
- <?php
2
- /*
3
- |------------------------------------------------------------------------
4
- | Settings panel
5
- |------------------------------------------------------------------------
6
- */
7
- namespace LocoAutoTranslateAddon\Core;
8
- use LocoAutoTranslateAddon\Helpers\Helpers;
9
-
10
- if( !class_exists( 'Settings_Panel' ) ){
11
- class Settings_Panel {
12
-
13
- public $settings_api;
14
- public $PREFIX;
15
- public function __construct(){
16
- $this->settings_api = new Settings_API;
17
- $this->PREFIX = 'atlt_';
18
- add_action('admin_init', array($this, 'admin_init' ) );
19
- add_action('admin_menu', array( $this, 'admin_menu' ),100 );
20
- add_action('admin_notices', array( $this, 'missing_api_key') );
21
- }
22
-
23
-
24
- /*
25
- |------------------------------------------
26
- | Initialize settings section
27
- |------------------------------------------
28
- */
29
- public function admin_init(){
30
- $this->settings_api->set_sections( $this->get_settings_sections() );
31
- $this->settings_api->set_fields( $this->get_settings_fields() );
32
- $this->settings_api->admin_init();
33
-
34
- }
35
-
36
- /*
37
- |--------------------------------------------------------------------
38
- | Create multiple section in settings page using array in $sections
39
- |--------------------------------------------------------------------
40
- */
41
- public function get_settings_sections()
42
- {
43
- $sections = array(
44
- array(
45
- 'id' => $this->PREFIX.'register',
46
- 'title' => __('Loco Automatic Translate Addon Settings', 'cmb2'),
47
- )
48
- );
49
- return $sections;
50
- }
51
-
52
-
53
- public function create_google_stats_tbl(){
54
- $month = get_option('g_translation_month');
55
- $total_translation = get_option('g_month_translated_chars', 0);
56
- $a_per_mon=0;
57
- $total_aval=0;
58
- $a_per_mon=500000;
59
- $total_aval=$a_per_mon-$total_translation;
60
- $info_tbl='<table>
61
- <tr>
62
- <th>Total Characters</th>
63
- <th>'.number_format($a_per_mon).' / Month</th>
64
- <th>Special Note</th>
65
- </tr>
66
- <tr>
67
- <td><strong>Used Characters</strong></td>
68
- <td>'.number_format($total_translation).'<br/><span>(Used This Month)</span></td>
69
- <td rowspan="2" style="max-width:200px;">Plugin do not provide any free translation limit. All free characters translation limit provided by translate API provider - <strong>Google</strong></td>
70
- </tr>
71
- <tr>
72
- <td><strong>Available Characters</strong></td>
73
- <td>'.number_format($total_aval).'<br/><span>(Available This Month)</span></td>
74
- </tr>
75
- </table>
76
- <br/>
77
- <span style="color:#0e840e;">*Check translation characters usage limit statistics inside API provider dashboard if you are using same API key on multiple sites.</span>';
78
- return $info_tbl;
79
- }
80
-
81
- public function create_ibm_stats_tbl(){
82
- $month = get_option('i_translation_month');
83
- $total_translation = get_option('i_month_translated_chars', 0);
84
- $a_per_mon=0;
85
- $total_aval=0;
86
- $a_per_mon=1000000;
87
- $total_aval=$a_per_mon-$total_translation;
88
- $info_tbl='<table>
89
- <tr>
90
- <th>Total Characters</th>
91
- <th>'.number_format($a_per_mon).' / Month</th>
92
- <th>Special Note</th>
93
- </tr>
94
- <tr>
95
- <td><strong>Used Characters</strong></td>
96
- <td>'.number_format($total_translation).'<br/><span>(Used This Month)</span></td>
97
- <td rowspan="2" style="max-width:200px;">Plugin do not provide any free translation limit.
98
- All free characters translation limit provided by translate API provider - <strong>IBM Watson</strong></td>
99
- </tr>
100
- <tr>
101
- <td><strong>Available Characters</strong></td>
102
- <td>'.number_format($total_aval).'<br/><span>(Available This Month)</span></td>
103
- </tr>
104
- </table>
105
- <br/>
106
- <span style="color:#0e840e;">*Check translation characters usage limit statistics inside API provider dashboard if you are using same API key on multiple sites.</span>';
107
- return $info_tbl;
108
- }
109
-
110
-
111
- public function create_microsoft_stats_tbl(){
112
- $month = get_option('m_translation_month');
113
- $total_translation = get_option('m_month_translated_chars', 0);
114
- $a_per_mon=0;
115
- $total_aval=0;
116
- $a_per_mon=2000000;
117
- $total_aval=$a_per_mon-$total_translation;
118
- $info_tbl='<table>
119
- <tr>
120
- <th>Total Characters</th>
121
- <th>'.number_format($a_per_mon).' / Month</th>
122
- <th>Special Note</th>
123
- </tr>
124
- <tr>
125
- <td><strong>Used Characters</strong></td>
126
- <td>'.number_format($total_translation).'<br/><span>(Used This Month)</span></td>
127
- <td rowspan="2" style="max-width:200px;">Plugin do not provide any free translation limit. All free characters translation limit provided by translate API provider - <strong>Microsoft</strong></td>
128
- </tr>
129
- <tr>
130
- <td><strong>Available Characters</strong></td>
131
- <td>'.number_format($total_aval).'<br/><span>(Available This Month)</span></td>
132
- </tr>
133
- </table>
134
- <br/>
135
- <span style="color:#0e840e;">*Check translation characters usage limit statistics inside API provider dashboard if you are using same API key on multiple sites.</span>';
136
- return $info_tbl;
137
- }
138
-
139
- public function APIIntegrationTesting($name){
140
- $output='';
141
- $desc='';
142
- $sourceLang='en';
143
- $targetLang='fr';
144
- $rawString='Hello';
145
- $apiKey='';
146
- $ajax_url= admin_url( 'admin-ajax.php' );
147
- $nonce= wp_create_nonce('atlt_nonce');
148
- if($name=="microsoft")
149
- {
150
- $apiKey= Helpers::getAPIkey("microsoft");
151
- $lbl='Microsoft Translation';
152
- $desc='<a target="_blank" href="https://locoaddon.com/how-to-generate-microsoft-translator-api-key/">Check Microsoft Translator API key generation guide.</a>';
153
- }else if($name=="ibm")
154
- {
155
- $keys_arr= get_option('atlt_register');
156
- $lbl='IBM Translation';
157
- $desc='<a target="_blank" href="https://locoaddon.com/how-to-generate-ibm-watson-translator-api-key/">How to generate IBM Watson Translator free API key?</a>';
158
-
159
- if(!empty($keys_arr['atlt_ibm-translate-api-key'])&&
160
- !empty($keys_arr['atlt_ibm-translate-url'])){
161
- $apiKey=$keys_arr['atlt_ibm-translate-api-key'];
162
- $lbl='IBM Translate';
163
- }
164
-
165
- } else if($name=="google")
166
- {
167
- $apiKey= Helpers::getAPIkey("google");
168
- $lbl='Google Translation';
169
- $desc= '<a target="_blank" href="https://locoaddon.com/howto-generate-google-translate-api-key/">Check Google Translator API key generation guide.</a>';
170
- }else{
171
- $apiKey= Helpers::getAPIkey("yandex");
172
- $lbl='Yandex Translation';
173
- $desc='<span style="color:#e00b0b;">*Yandex Translate API v1 has been deprecated from June 01, 2020. Yandex has stopped providing free translate API v1 keys.<br/>If you have already generated Yandex Translate v1 API key only then you can use Yandex for automatic translations.</span>';
174
- }
175
- if($apiKey){
176
- $output .='<div><a class="atlt_test_api button button-primary button-small"
177
- data-source="'.$sourceLang.'"
178
- data-nonce="'.$nonce.'"
179
- data-target="'.$targetLang.'"
180
- data-text="'.$rawString.'"
181
- data-apikey="'.$apiKey.'"
182
- data-api-provider="'.$name.'"
183
- data-ajaxurl="'.$ajax_url.'"
184
- href="#"><span class="dashicons dashicons-translation"></span> Test '.$lbl.' API </a> <img style="display:none;width:24px;height:24px;" class="atlt-preloader" src="'.ATLT_URL.'/assets/images/preloader.gif"></div>';
185
- }else{
186
- $output.=$desc;
187
- }
188
-
189
- return $output;
190
-
191
- }
192
- /*
193
- |--------------------------------------------------------------------
194
- | return all settings fields to be initialized in settings page
195
- |--------------------------------------------------------------------
196
- */
197
- public function get_settings_fields()
198
- {
199
- $month = get_option('atlt_translation_month');
200
- $today = ('atlt_translation_day');
201
- $total_translation = get_option('atlt_month_translated_chars', 0);
202
- $todays_total_translation = get_option('atlt_perday_translated_chars', 0);
203
- $a_per_day=0;
204
- $a_per_mon=0;
205
- $today_aval=0;
206
- $total_aval=0;
207
-
208
- $key=Helpers::getLicenseKey();
209
-
210
- $LS_html='';
211
- if(Helpers::userType()=="free"){
212
- $LS_html='<table>
213
- <tr>
214
- <th><strong>FREE User</strong></th>
215
- <th><a href="?page=loco-atlt-register">Enter License Key<br/><span>(Click Here!)</span></a></th>
216
- <th><a target="_blank" href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing">Buy Pro License Key<br/><span>(Increase Translation Limit!)</span></a></th>
217
- </tr>
218
- </table>';
219
- $a_per_day=300000;
220
- $a_per_mon=1000000;
221
- $today_aval= $a_per_day-$todays_total_translation;
222
- $total_aval=$a_per_mon-$total_translation;
223
-
224
- }else{
225
- $key=Helpers::getLicenseKey();
226
- if(Helpers::validKey( $key)){
227
- $LS_html='<table>
228
- <tr>
229
- <th><strong>PREMIUM User</strong></th>
230
- <th><a href="?page=loco-atlt-register">Check License Validity Status<br/><span>(Click Here!)</span></a></th>
231
- </tr>
232
- </table>';
233
- $a_per_day=1000000;
234
- $a_per_mon=10000000;
235
- $today_aval= $a_per_day-$todays_total_translation;
236
- $total_aval=$a_per_mon-$total_translation;
237
- }
238
- }
239
- $info_tbl='<table>
240
- <tr>
241
- <th>Total Characters</th>
242
- <th>'.number_format($a_per_day).' / Day</th>
243
- <th>'.number_format($a_per_mon).' / Month</th>
244
- </tr>
245
- <tr>
246
- <td><strong>Used Characters</strong></td>
247
- <td>'.number_format($todays_total_translation).'<br/><span>(Used Today)</span></td>
248
- <td>'.number_format($total_translation).'<br/><span>(Used This Month)</span></td>
249
- </tr>
250
- <tr>
251
- <td><strong>Available Characters</strong></td>
252
- <td>'.number_format($today_aval).'<br/><span>(Available Today)</span></td>
253
- <td>'.number_format($total_aval).'<br/><span>(Available This Month)</span></td>
254
- </tr>
255
- </table>
256
- <br/>
257
- <span style="color:#e00b0b;">*Yandex Translate API v1 has been deprecated from June 01, 2020. Yandex has stopped providing free translate API v1 keys.<br>If you have already generated Yandex Translate v1 API key only then you can use Yandex for automtatic translations.</span>';
258
-
259
- if( function_exists( 'loco_plugin_version' ) && version_compare( loco_plugin_version() , '2.3.3' , '>') ):
260
- $settingArr[]= array(
261
- 'name' => $this->PREFIX.'rollback-request',
262
- 'id' => $this->PREFIX.'rollback-request',
263
- 'class' => $this->PREFIX.'rollbakBtn',
264
- 'label' => 'Rollback Loco Translate To Version 2.3.3:',
265
- 'desc' => '<div id="Btloco_rollback" class="button primary">Rollback Here</div>
266
- <p class="notices" style="color:#d61919;"><strong>Automatic Translate Addon For Loco Translate</strong> is only compatible with Loco Translate official plugin version <strong>2.3.3</strong> or lower.<br/>Currently you are using Loco Translate official plugin version 2.4.0 or higher.<br/>Please rollback to use all features of this addon.<br/><br/>You can also rollback via <a href="https://wordpress.org/plugins/wp-rollback/">WP Rollback plugin</a> easily if you face any issue in above rollback process.</p>
267
- ',
268
- 'type' => 'html',
269
- );
270
- endif;
271
-
272
- $pro_per_day=1000000;
273
- $pro_per_mon=10000000;
274
- $pro_info='<table>
275
- <tr>
276
- <th style="vertical-align:middle;">Google Translate API</th>
277
- <td style="min-width:200px;">'.number_format(500000).' / Month<br/>(Free Char Limit)</td>
278
- <td rowspan="2" style="max-width:200px;"><p>Free characters translation limit only provided by Translate API providers, e.g. - Google, Microsoft, IBM etc.<br/>Plugin doesn\'t provide any free characters limit for automatic translations.</p></td>
279
- </tr>
280
- <tr>
281
- <th style="vertical-align:middle;">Microsoft Translator API</th>
282
- <td style="min-width:200px;">'.number_format(2000000).' / Month<br/>(Free Char Limit)</td>
283
- </tr>
284
- </table>';
285
-
286
- $settingArr[]=array(
287
- 'name' => $this->PREFIX.'api-key',
288
- 'id' => $this->PREFIX.'api-key',
289
- 'class' => $this->PREFIX.'settings-field',
290
- 'label' => 'Enter Yandex Translate<br/>API v1 Key:',
291
- 'desc' =>$this->APIIntegrationTesting("yandex"),
292
- 'type' => 'text',
293
- 'placeholder'=>__('Yandex API Key','cmb2'),
294
- 'default' => ''
295
- );
296
-
297
- $settingArr[]=array(
298
- 'name' => $this->PREFIX.'ibm-translate-api-key',
299
- 'id' => $this->PREFIX.'ibm-translate-api-key',
300
- 'class' => $this->PREFIX.'settings-field',
301
- 'label' => 'Enter IBM Translate<br/>API Key:',
302
- 'type' => 'text',
303
- 'placeholder'=>__('IBM Translate API Key','cmb2'),
304
- 'default' => ''
305
- );
306
- $settingArr[]=array(
307
- 'name' => $this->PREFIX.'ibm-translate-url',
308
- 'id' => $this->PREFIX.'ibm-translate-url',
309
- 'class' => $this->PREFIX.'settings-field',
310
- 'label' => 'Enter IBM Translate URL:',
311
- 'desc' =>$this->APIIntegrationTesting("ibm"),
312
- 'type' => 'text',
313
- 'placeholder'=>__('IBM Watson Translate URL','cmb2'),
314
- 'default' => ''
315
- );
316
- if(Helpers::userType()=="pro" && Helpers::proInstalled()==false) {
317
- $key=Helpers::getLicenseKey();
318
- $url =esc_url( add_query_arg( 'license-key',$key , 'https://locoaddon.com/data/download-plugin.php' ) );
319
-
320
- $settingArr[]=array(
321
- 'name' => $this->PREFIX.'install-pro',
322
- 'id' => $this->PREFIX.'install-pro',
323
- 'class' => $this->PREFIX.'settings-field',
324
- 'label' => 'Please Activate Or Download and Install PRO version',
325
- 'desc' =>'<a href="'.$url.'" target="_blank">Loco Automatic Translate Addon Pro</a>',
326
- 'type' => 'html',
327
-
328
- 'default' => ''
329
- );
330
- }else if(Helpers::proInstalled()==true && Helpers::getLicenseKey()==false) {
331
- $settings_page_link=esc_url( get_admin_url(null, 'admin.php?page=loco-atlt-register') );
332
- $notice=__('Please add <strong>Loco Automatic Translate Addon Pro license key</strong> in the settings panel.', 'loco-translate-addon');
333
- $settingArr[]=
334
- array(
335
- 'name' => $this->PREFIX.'google-api-key-demo-2',
336
- 'id' => $this->PREFIX.'google-api-key-demo-2',
337
- 'class' => $this->PREFIX.'settings-field',
338
- 'label' => 'Enter Google Translate<br>API Key:',
339
- 'desc' =>'<div class=""><p>'.$notice.'</p>
340
- <p><a class="button button-secondary" href="'.$settings_page_link.'">'.__('Add License Key & Activate Premium Features').'</a>
341
- </p></div>',
342
- 'type' => 'html'
343
- );
344
- $settingArr[]=
345
- array(
346
- 'name' => $this->PREFIX.'microsoft-api-key-demo-2',
347
- 'id' => $this->PREFIX.'microsoft-api-key-demo-2',
348
- 'class' => $this->PREFIX.'settings-field',
349
- 'label' => 'Enter Microsoft Translator<br>API Key:',
350
- 'desc' =>'<div class=""><p>'.$notice.'</p>
351
- <p><a class="button button-secondary" href="'.$settings_page_link.'">'.__('Add License Key & Activate Premium Features').'</a>
352
- </p></div>',
353
- 'type' => 'html'
354
- );
355
-
356
- }else if(Helpers::userType()=="pro") {
357
- $key=Helpers::getLicenseKey();
358
- if(Helpers::validKey( $key)){
359
- $settingArr[]=array(
360
- 'name' => $this->PREFIX.'google-api-key',
361
- 'id' => $this->PREFIX.'google-api-key',
362
- 'class' => $this->PREFIX.'settings-field',
363
- 'label' => 'Enter Google Translate<br>API Key:',
364
- 'desc' =>$this->APIIntegrationTesting("google"),
365
- 'type' => 'text',
366
- 'placeholder'=>__('Google Translate API Key','cmb2'),
367
- 'default' => ''
368
- );
369
- $settingArr[]=array(
370
- 'name' => $this->PREFIX.'microsoft-api-key',
371
- 'id' => $this->PREFIX.'microsoft-api-key',
372
- 'class' => $this->PREFIX.'settings-field',
373
- 'label' => 'Enter Microsoft Translator<br>Subscription Key:',
374
- 'desc' => $this->APIIntegrationTesting("microsoft"),
375
- 'type' => 'text',
376
- 'placeholder'=>__('Microsoft Translator Subscription Key','cmb2'),
377
- 'default' => ''
378
- );
379
- }
380
- }else{
381
- $settingArr[]=
382
- array(
383
- 'name' => $this->PREFIX.'google-api-key-demo',
384
- 'id' => $this->PREFIX.'google-api-key-demo',
385
- 'class' => $this->PREFIX.'settings-field',
386
- 'label' => 'Enter Google Translate<br>API Key:',
387
- 'desc' =>'<a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank"><img style="width:auto" src="'.ATLT_URL.'/assets/images/google-api.png" alt="Add Google Translate API Key"></a>',
388
- 'type' => 'html'
389
- );
390
- $settingArr[]=
391
- array(
392
- 'name' => $this->PREFIX.'microsoft-api-key-demo',
393
- 'id' => $this->PREFIX.'microsoft-api-key-demo',
394
- 'class' => $this->PREFIX.'settings-field',
395
- 'label' => 'Enter Microsoft Translator<br>API Key:',
396
- 'desc' =>'<a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank"><img style="width:auto" src="'.ATLT_URL.'/assets/images/microsoft-api.png" alt="Add Microsoft Translator API Key"></a>',
397
- 'type' => 'html'
398
- );
399
- $settingArr[]=
400
- array(
401
- 'name' => $this->PREFIX.'google-page-translate-button-demo',
402
- 'id' => $this->PREFIX.'google-page-translate-button-demo',
403
- 'class' => $this->PREFIX.'settings-field',
404
- 'label' => 'Google Translate Button<br>No API Key Required:<br/><img src='.ATLT_URL.'/assets/images/powered-by-google.png>',
405
- 'desc' =>'<a href="https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing" target="_blank"><img style="width:auto" src="'.ATLT_URL.'/assets/images/google-translate-button.png" alt="Add Microsoft Translator API Key"><br/>✅ Available Inside Pro Version 1.1<br/><span style="font-size:11px;font-weight:bold;">(Release date:- 27 June, 2020)</span></a>',
406
- 'type' => 'html'
407
- );
408
- }
409
- $settingArr[]= array(
410
- 'name' => $this->PREFIX.'index-per-request',
411
- 'id' => $this->PREFIX.'index-per-request',
412
- 'class' => $this->PREFIX.'settings-field',
413
- 'label' => 'Index Per Request:',
414
- 'desc' => 'Number of strings index to send to Translate API in every request.<br/>Decrease it if you have long strings inside your loco translate table fields.'.$this->welcome_tab(),
415
- 'type' => 'number',
416
- 'placeholder'=>__('50','cmb2'),
417
- 'default' => '50'
418
- );
419
-
420
- // if(Helpers::userType()=="pro") {
421
-
422
- // }
423
-
424
- $settingArr[]=
425
- array(
426
- 'name' => $this->PREFIX.'supported-lang-list',
427
- 'id' => $this->PREFIX.'supported-lang-list',
428
- 'class' => $this->PREFIX.'settings-field',
429
- 'label' => 'Supported Languages List',
430
- 'desc' =>'<a target="_blank" href="https://locoaddon.com/supported-languages/">Click here to view All Supported Languages</a>',
431
- 'type' => 'html'
432
- );
433
- $settingArr[]=
434
- array(
435
- 'name' => $this->PREFIX.'traslation-limit',
436
- 'id' => $this->PREFIX.'traslation-limit',
437
- 'class' => $this->PREFIX.'settings-field',
438
- 'label' => 'Yandex Translate<br>Free Translation Limit:',
439
- 'desc' => $info_tbl,
440
- 'type' => 'html'
441
- );
442
-
443
- $settingArr[]= array(
444
- 'name' => $this->PREFIX.'ibm-traslation-limit',
445
- 'id' => $this->PREFIX.'ibm-traslation-limit',
446
- 'class' => $this->PREFIX.'settings-field',
447
- 'label' => 'IBM Translate<br>Free Translation Limit:',
448
- 'desc' =>$this->create_ibm_stats_tbl(),
449
- 'type' => 'html'
450
- );
451
- if(Helpers::userType()=="free") {
452
- $settingArr[]= array(
453
- 'name' => $this->PREFIX.'upgrade-to-pro',
454
- 'id' => $this->PREFIX.'upgrade-to-pro',
455
- 'class' => $this->PREFIX.'settings-field',
456
- 'label' => 'Extra Translate APIs Support<br/>Using Pro License:',
457
- 'desc' => $pro_info,
458
- 'type' => 'html'
459
- );
460
- }else{
461
-
462
- if(Helpers::proInstalled()==true) {
463
-
464
- $settingArr[]= array(
465
- 'name' => $this->PREFIX.'google-traslation-limit',
466
- 'id' => $this->PREFIX.'google-traslation-limit',
467
- 'class' => $this->PREFIX.'settings-field',
468
- 'label' => 'Google Translate<br>Free Translation Limit:',
469
- 'desc' =>$this->create_google_stats_tbl(),
470
- 'type' => 'html'
471
- );
472
- $settingArr[]= array(
473
- 'name' => $this->PREFIX.'microsoft-traslation-limit',
474
- 'id' => $this->PREFIX.'microsoft-traslation-limit',
475
- 'class' => $this->PREFIX.'settings-field',
476
- 'label' => 'Microsoft Translator<br>Free Translation Limit:',
477
- 'desc' =>$this->create_microsoft_stats_tbl(),
478
- 'type' => 'html'
479
- );
480
- }
481
- }
482
- $settingArr[]= array(
483
- 'name' => $this->PREFIX.'license-status',
484
- 'id' => $this->PREFIX.'license-status',
485
- 'class' => $this->PREFIX.'settings-field',
486
- 'label' => 'Current License Status:',
487
- 'desc' => $LS_html,
488
- 'type' => 'html'
489
- );
490
-
491
- $settingArr[]= array(
492
- 'name' => $this->PREFIX.'screenshort',
493
- 'id' => $this->PREFIX.'screenshort',
494
- 'label' => 'Usage Instructions:',
495
- 'desc' => $this->screenshort(),
496
- 'type' => 'html'
497
- );
498
- $settings_fields = array(
499
- $this->PREFIX.'register' => $settingArr
500
- );
501
- return $settings_fields;
502
- }
503
-
504
- public function welcome_tab(){
505
- //$this->ce_get_option($this->PREFIX.'-api-key');
506
- return get_submit_button('Save Settings');
507
-
508
- }
509
-
510
- public function rate_now(){
511
- $like_it_text='Rate Now! ★★★★★';
512
- $p_link=esc_url('https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post');
513
- $ajax_url=admin_url( 'admin-ajax.php' );
514
- $html ='<p>Thanks for using Loco Automatic Translate Addon - WordPress plugin. We hope it has saved your valuable time and efforts! <br/>Please give us a quick rating, it works as a boost for us to keep working on more <a href="https://coolplugins.net/">Cool Plugins!</a></p>
515
- <a href="'.$p_link.'" class="like_it_btn button button-primary" target="_new" title="'.$like_it_text.'">'.$like_it_text.'</a>
516
- ';
517
- return $html;
518
- }
519
-
520
- public function screenshort(){
521
-
522
- $src = ATLT_URL .'assets/images/screenshot-1.gif';
523
- $html = '<img src="'.$src.'" style="width:auto;max-width:100%;">';
524
-
525
- return $html;
526
- }
527
- /*
528
- |---------------------------------------------------
529
- | Add settings page to wordpress menu
530
- |---------------------------------------------------
531
- */
532
- public function admin_menu()
533
- {
534
- add_submenu_page( 'loco','Loco Auto Translator', 'Auto Translator Addon - Settings', 'manage_options', 'loco-atlt', array($this, 'atlt_settings_page'));
535
- }
536
-
537
- public function atlt_settings_page(){
538
-
539
- $this->settings_api->show_navigation();
540
- $this->settings_api->show_forms('Save',false);
541
-
542
- }
543
-
544
- /*
545
- |---------------------------------------------------------
546
- | Gather settings field-values like get_options()
547
- |---------------------------------------------------------
548
- */
549
- public function ce_get_option($option, $default = '')
550
- {
551
-
552
- $section = $this->PREFIX.'register';
553
- $options = get_option($section);
554
-
555
- if (isset($options[$option])) {
556
- return $options[$option];
557
- }
558
-
559
- return $default;
560
- }
561
-
562
- /*
563
- |-----------------------------------------------------------
564
- | Show message in case of no api-key is saved
565
- |-----------------------------------------------------------
566
- */
567
- public function missing_api_key(){
568
-
569
- $api_key = $this->ce_get_option( $this->PREFIX.'api-key');
570
-
571
- $ibm_api_key = $this->ce_get_option( $this->PREFIX.'ibm-translate-api-key');
572
- if( isset( $api_key ) && !empty( $api_key ) ){
573
- return;
574
- }
575
- if( isset( $ibm_api_key ) && !empty( $ibm_api_key ) ){
576
- return;
577
- }
578
- if(Helpers::userType()=="pro"){
579
- return;
580
- }
581
- // Show API message only in translation editor page
582
- if( isset($_REQUEST['action']) && $_REQUEST['action'] == 'file-edit' ){
583
- $plugin_info = get_plugin_data( ATLT_FILE , true, true );
584
- $message = sprintf('You must provide an %s to use the functionality of <strong>%s</strong>','<a href="'.admin_url('admin.php?page=loco-atlt').'">API key</a>',$plugin_info['Name']);
585
- $translation = __($message,'loco-translate-addon');
586
- $HTML = '<div class="notice notice-warning inline is-dismissible"><p>'.$translation.'</p></div>';
587
- echo $HTML;
588
- }else if( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'loco-atlt' ){
589
- $message = sprintf('Get a free API KEY from %s and save it below to enable the Auto Translation feature.','<a href="https://cloud.ibm.com/registration" target="_blank">IBM Watson Language Translator</a>');
590
- $translation = __($message,'loco-translate-addon');
591
- $HTML = '<div class="notice notice-warning inline is-dismissible"><p>'.$translation.'</p></div>';
592
- echo $HTML;
593
- }
594
- }
595
-
596
- }
597
-
598
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Helpers/{Atlt_rollback.php → Atlt_downloader.php} RENAMED
@@ -1,7 +1,7 @@
1
  <?php
2
  namespace LocoAutoTranslateAddon\Helpers;
3
  /**
4
- * This class is used to rollback a plugin. It extends wordpress core class Plugin_Upgrader
5
  * Due to the use of package & namaspace, class can not be extend requiring file
6
  *
7
  */
@@ -14,9 +14,9 @@ namespace LocoAutoTranslateAddon\Helpers;
14
  require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
15
  }
16
 
17
- class Atlt_rollback extends \Plugin_Upgrader{
18
 
19
- public function rollback(){
20
 
21
  $key = ( isset( $_POST['key'] ) && !empty( $_POST['key'] ) ) ? $_POST['key'] : null;
22
 
@@ -27,8 +27,6 @@ namespace LocoAutoTranslateAddon\Helpers;
27
  $this->init();
28
  $this->upgrade_strings();
29
 
30
- $url = 'https://downloads.wordpress.org/plugin/loco-translate.2.3.3.zip';
31
-
32
  add_filter( 'upgrader_pre_install', array( $this, 'deactivate_plugin_before_upgrade' ), 10, 2 );
33
  add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ), 10, 4 );
34
 
1
  <?php
2
  namespace LocoAutoTranslateAddon\Helpers;
3
  /**
4
+ * This class is used to update/install/rollback a plugin. It extends wordpress core class Plugin_Upgrader
5
  * Due to the use of package & namaspace, class can not be extend requiring file
6
  *
7
  */
14
  require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
15
  }
16
 
17
+ class Atlt_downloader extends \Plugin_Upgrader{
18
 
19
+ public function rollback($url = null){
20
 
21
  $key = ( isset( $_POST['key'] ) && !empty( $_POST['key'] ) ) ? $_POST['key'] : null;
22
 
27
  $this->init();
28
  $this->upgrade_strings();
29
 
 
 
30
  add_filter( 'upgrader_pre_install', array( $this, 'deactivate_plugin_before_upgrade' ), 10, 2 );
31
  add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ), 10, 4 );
32
 
includes/Helpers/Helpers.php CHANGED
@@ -4,29 +4,6 @@ namespace LocoAutoTranslateAddon\Helpers;
4
  * @package Loco Automatic Translate Addon
5
  */
6
  class Helpers{
7
- /*
8
- |----------------------------------------------------------------------------|
9
- | Delete or update per day translated charachter stats |
10
- | @param $value int current translated character to update in database |
11
- |----------------------------------------------------------------------------|
12
- */
13
- // count today translated strings
14
- public static function ytodayTranslated($value = 0)
15
- {
16
- $now_translated = $value;
17
- if (false===($today= get_transient('atlt_translation_day'))) {
18
- delete_option('atlt_perday_translated_chars');
19
- update_option('atlt_perday_translated_chars', $now_translated);
20
- set_transient('atlt_translation_day', 'true', DAY_IN_SECONDS);
21
- $today_total_translated=$now_translated;
22
- } else {
23
- $already_translated = intval(get_option('atlt_perday_translated_chars'));
24
- $today_total_translated = $already_translated+$now_translated;
25
- update_option('atlt_perday_translated_chars', $today_total_translated);
26
- }
27
- return $today_total_translated;
28
- }
29
-
30
  public static function proInstalled(){
31
  if (defined('ATLT_PRO_FILE')) {
32
  return true;
@@ -34,67 +11,6 @@ class Helpers{
34
  return false;
35
  }
36
  }
37
- // count monthly translated strings
38
- public static function ymonthlyTranslated($value = 0){
39
- $now_translated=$value;
40
- if (false===($month= get_transient('atlt_translation_month'))) {
41
- delete_option('atlt_month_translated_chars');
42
- update_option('atlt_month_translated_chars',$now_translated);
43
- set_transient('atlt_translation_month', 'true', MONTH_IN_SECONDS);
44
- $month_total_translated=$now_translated;
45
- } else {
46
- $already_translated = intval(get_option('atlt_month_translated_chars'));
47
- $month_total_translated= $already_translated+$now_translated;
48
- update_option('atlt_month_translated_chars', $month_total_translated);
49
- }
50
- return $month_total_translated;
51
- }
52
-
53
-
54
- /* google chars stats*/
55
- public static function iTodayTranslated($value = 0)
56
- {
57
- $now_translated = $value;
58
- if (false===($today= get_transient('i_translation_day'))) {
59
- delete_option('i_perday_translated_chars');
60
- update_option('i_perday_translated_chars', $now_translated);
61
- set_transient('i_translation_day', 'true', DAY_IN_SECONDS);
62
- $today_total_translated=$now_translated;
63
- } else {
64
- $already_translated = intval(get_option('i_perday_translated_chars'));
65
- $today_total_translated = $already_translated+$now_translated;
66
- update_option('i_perday_translated_chars', $today_total_translated);
67
- }
68
- return $today_total_translated;
69
- }
70
-
71
- // count monthly translated strings
72
- public static function iMonthlyTranslated($value = 0){
73
- $now_translated=$value;
74
- if (false===($month= get_transient('i_translation_month'))) {
75
- delete_option('i_month_translated_chars');
76
- update_option('i_month_translated_chars',$now_translated);
77
- set_transient('i_translation_month', 'true', MONTH_IN_SECONDS);
78
- $month_total_translated=$now_translated;
79
- } else {
80
- $already_translated = intval(get_option('i_month_translated_chars'));
81
- $month_total_translated= $already_translated+$now_translated;
82
- update_option('i_month_translated_chars', $month_total_translated);
83
- }
84
- return $month_total_translated;
85
- }
86
-
87
- // check timing
88
- public static function checkPeriod(){
89
- $today=get_transient('atlt_translation_day');
90
- $month=get_transient('atlt_translation_month');
91
- if(false===$today){
92
- delete_option('atlt_perday_translated_chars');
93
- }
94
- if(false===$month){
95
- delete_option('atlt_month_translated_chars');
96
- }
97
- }
98
  // verifiy user limit
99
  public static function atltVerification(){
100
  $allowed='';
@@ -134,54 +50,6 @@ class Helpers{
134
  }
135
  }
136
 
137
- public static function getAvailableChars($source)
138
- {
139
- $availableChars=0;
140
- if($source=="yandex"){
141
- $a_per_day=1000000;
142
- $today_total_translated = get_option('atlt_perday_translated_chars', 0);
143
- $availableChars=$a_per_day-$today_total_translated;
144
- }else if($source=="microsoft"){
145
- $a_per_mon=2000000;
146
- $total_translation = get_option('m_month_translated_chars', 0);
147
- $availableChars=$a_per_mon-$total_translation;
148
- }else if($source=="ibm"){
149
- $a_per_mon=1000000;
150
- $total_translation = get_option('i_month_translated_chars', 0);
151
- $availableChars=$a_per_mon-$total_translation;
152
- }
153
-
154
- else{
155
- $a_per_mon=500000;
156
- $total_translation = get_option('g_month_translated_chars', 0);
157
- $availableChars=$a_per_mon-$total_translation;
158
- }
159
- return $availableChars;
160
- }
161
-
162
- public static function getAPIkey($source){
163
- $key='';
164
- $keys_arr= get_option('atlt_register');
165
- if($source=="google"){
166
- if(isset($keys_arr['atlt_google-api-key'])){
167
- $key=$keys_arr['atlt_google-api-key'];
168
- }
169
- }else if($source=="microsoft"){
170
- if(isset($keys_arr['atlt_microsoft-api-key'])){
171
- $key=$keys_arr['atlt_microsoft-api-key'];
172
- }
173
- }else if($source=="ibm"){
174
- if(isset($keys_arr['atlt_ibm-translate-api-key'])){
175
- $key=$keys_arr['atlt_ibm-translate-api-key'];
176
- }
177
- }else{
178
- if(isset($keys_arr['atlt_api-key'])){
179
- $key=$keys_arr['atlt_api-key'];
180
- }
181
- }
182
- return $key;
183
- }
184
-
185
  // validate key
186
  public static function validKey($key){
187
  if (preg_match("/^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/",$key)){
@@ -200,69 +68,6 @@ class Helpers{
200
  }
201
  }
202
 
203
- // format cumber
204
- public static function formatNum($n) {
205
- // first strip any formatting;
206
- $n = (0+str_replace(",", "", $n));
207
- // is this a number?
208
- if (!is_numeric($n)) return false;
209
- // now filter it;
210
- if ($n > 1000000000000) return round(($n/1000000000000), 2).' trillion';
211
- elseif ($n > 1000000000) return round(($n/1000000000), 2).' billion';
212
- elseif ($n > 1000000) return round(($n/1000000), 2).' million';
213
- elseif ($n > 1000) return round(($n/1000), 2).' thousand';
214
- return number_format($n);
215
- }
216
 
217
- /*
218
- |----------------------------------------------------------------|
219
- | return the total amount of time saved on translation |
220
- | @param $characters int number of translated charachters |
221
- |----------------------------------------------------------------|
222
- */
223
- public static function atlt_time_saved_on_translation( $characters ){
224
- $total_saved = intval( $characters ) / 1800 ;
225
- if($characters='' || $characters<=0){
226
- return;
227
- }
228
- if( $total_saved >=1 && is_float( $total_saved ) ){
229
- $hour = intval( $total_saved );
230
- $minute = $total_saved - $hour;
231
- $minute = intval( $minute * 60 );
232
- return $hour .' hour and '. round($minute,2).' minutes';
233
- }else{
234
- $minute = floatval($total_saved) * 60;
235
- if( $minute <1 ){
236
- return round($minute * 60, 2) . ' seconds';
237
- }
238
- return round($minute,2) . ' minutes';
239
- }
240
- }
241
-
242
- public static function yandexSLangList($langCode,$list=false){
243
- $json_lang_list='{"af":"Afrikaans","am":"Amharic","ar":"Arabic","az":"Azerbaijani","ba":"Bashkir","be":"Belarusian","bg":"Bulgarian","bn":"Bengali","bs":"Bosnian","ca":"Catalan","ceb":"Cebuano","cs":"Czech","cy":"Welsh","da":"Danish","de":"German","el":"Greek","en":"English","eo":"Esperanto","es":"Spanish","et":"Estonian","eu":"Basque","fa":"Persian","fi":"Finnish","fr":"French","ga":"Irish","gd":"Scottish Gaelic","gl":"Galician","gu":"Gujarati","he":"Hebrew","hi":"Hindi","hr":"Croatian","ht":"Haitian","hu":"Hungarian","hy":"Armenian","id":"Indonesian","is":"Icelandic","it":"Italian","ja":"Japanese","jv":"Javanese","ka":"Georgian","kk":"Kazakh","km":"Khmer","kn":"Kannada","ko":"Korean","ky":"Kyrgyz","la":"Latin","lb":"Luxembourgish","lo":"Lao","lt":"Lithuanian","lv":"Latvian","mg":"Malagasy","mhr":"Mari","mi":"Maori","mk":"Macedonian","ml":"Malayalam","mn":"Mongolian","mr":"Marathi","mrj":"Hill Mari","ms":"Malay","mt":"Maltese","my":"Burmese","ne":"Nepali","nl":"Dutch","no":"Norwegian","pa":"Punjabi","pap":"Papiamento","pl":"Polish","pt":"Portuguese","ro":"Romanian","ru":"Russian","si":"Sinhalese","sk":"Slovak","sl":"Slovenian","sq":"Albanian","sr":"Serbian","su":"Sundanese","sv":"Swedish","sw":"Swahili","ta":"Tamil","te":"Telugu","tg":"Tajik","th":"Thai","tl":"Tagalog","tr":"Turkish","tt":"Tatar","udm":"Udmurt","uk":"Ukrainian","ur":"Urdu","uz":"Uzbek","vi":"Vietnamese","xh":"Xhosa","yi":"Yiddish","zh":"Chinese"}';
244
- $langArr=json_decode($json_lang_list,true);
245
- if($list){
246
- return $langArr;
247
- }
248
-
249
- if(isset($langArr[$langCode])){
250
- return true;
251
- }else{
252
- return false;
253
- }
254
- }
255
-
256
- public static function ibmSLangList($langCode,$list=false){
257
- $json_lang_list='{"ar":"Arabic","bg":"Bulgarian","bn":"Bengali","cs":"Czech","da":"Danish","de":"German","el":"Greek","es":"Spanish","et":"Estonian","fi":"Finnish","fr":"French","ga":"Irish","gu":"Gujarati","he":"Hebrew","hi":"Hindi","hr":"Croatian","hu":"Hungarian","it":"Italian","ja":"Japanese","ko":"Korean","lt":"Lithuanian","lv":"Latvian","ml":"Malayalam","ms":"Malay","mt":"Maltese","nb":"Norwegian Bokmal","ne":"Nepali","nl":"Dutch","pl":"Polish","pt":"Portuguese","ro":"Romanian","ru":"Russian","si":"Sinhala","sk":"Slovakian","sl":"Slovenian","sv":"Swedish","ta":"Tamil","te":"Telugu","tr":"Turkish","uk":"Ukrainian","ur":"Urdu","vi":"Vietnamese","zh":"Simplified Chinese"}';
258
- $langArr=json_decode($json_lang_list,true);
259
- if($list){
260
- return $langArr;
261
- }
262
- if(isset($langArr[$langCode])){
263
- return true;
264
- }else{
265
- return false;
266
- }
267
- }
268
  }
4
  * @package Loco Automatic Translate Addon
5
  */
6
  class Helpers{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  public static function proInstalled(){
8
  if (defined('ATLT_PRO_FILE')) {
9
  return true;
11
  return false;
12
  }
13
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  // verifiy user limit
15
  public static function atltVerification(){
16
  $allowed='';
50
  }
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  // validate key
54
  public static function validKey($key){
55
  if (preg_match("/^([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})-([A-Z0-9]{8})$/",$key)){
68
  }
69
  }
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
includes/Register/LocoAutomaticTranslateAddonPro.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  namespace LocoAutoTranslateAddon\Register;
3
- use LocoAutoTranslateAddon\Helpers\Atlt_rollback;
4
 
5
  require_once "LocoAutomaticTranslateAddonProBase.php";
6
  class LocoAutomaticTranslateAddonPro {
@@ -44,9 +44,9 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
44
  die( array('response'=>'500','message'=>'Nonce Verification falied') );
45
  }
46
  $hash = isset($_POST['hash']) ? $_POST['hash'] : null;
47
- if( !empty( $hash ) ){
48
- require_once ATLT_PATH . 'includes/Helpers/Atlt_rollback.php';
49
- $request = new Atlt_rollback();
50
  $response = $request->install( 'https://locoaddon.com/data/download-plugin.php?license-key=' . $hash );
51
  }
52
  if( file_exists( WP_PLUGIN_DIR . '/loco-automatic-translate-addon-pro')==true ){
@@ -59,7 +59,7 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
59
  function ActiveAdminMenu(){
60
  add_submenu_page( 'loco',
61
  'Loco Automatic Translate Addon Pro',
62
- 'Auto Translator Addon - Premium License',
63
  'manage_options',
64
  $this->slug,
65
  array($this, 'Activated'));
@@ -68,8 +68,8 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
68
  // no further execution required
69
  return;
70
  }
71
- if( false == file_exists( WP_PLUGIN_DIR . '/loco-automatic-translate-addon-pro') &&
72
- isset( $_GET['page'] ) && $_GET['page'] == "loco-atlt-register" ){
73
 
74
  add_action('admin_footer', function(){
75
  $hash_key = get_option( 'LocoAutomaticTranslateAddonPro_lic_Key' ,false);
@@ -109,7 +109,7 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
109
  function InactiveMenu() {
110
  add_submenu_page( 'loco',
111
  'Loco Automatic Translate Addon Pro',
112
- 'Auto Translator Addon - Premium License',
113
  'activate_plugins',
114
  $this->slug,
115
  array($this, 'LicenseForm'));
@@ -136,7 +136,7 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
136
  <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
137
  <input type="hidden" name="action" value="LocoAutomaticTranslateAddonPro_el_deactivate_license"/>
138
  <div class="el-license-container">
139
- <h3 class="el-license-title"><i class="dashicons-before dashicons-star-filled"></i> <?php _e("Loco Automatic Translate Addon - Premium License Status",$this->slug);?> </h3>
140
  <hr>
141
  <ul class="el-license-info">
142
  <li>
@@ -192,7 +192,7 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
192
  <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
193
  <input type="hidden" name="action" value="LocoAutomaticTranslateAddonPro_el_activate_license"/>
194
  <div class="el-license-container">
195
- <h3 class="el-license-title"><i class="dashicons-before dashicons-star-filled"></i> <?php _e("Loco Automatic Translate Addon - Premium License",$this->slug);?></h3>
196
  <hr>
197
  <?php
198
  if(!empty($this->showMessage) && !empty($this->licenseMessage)){
@@ -235,61 +235,62 @@ require_once "LocoAutomaticTranslateAddonProBase.php";
235
  <!--Enter License Key Here END-->
236
  <h3>Compare Free vs Pro (<a href='https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing' target='_blank'>Buy Premium License Key</a>)</h3>
237
  <table class="loco-addon-license">
 
238
  <tr>
239
  <th>Features</th>
240
  <th>Free License</th>
241
  <th>Premium License</th>
242
  </tr>
243
- <tr style="background:#fffb7a;font-weight: bold;">
244
- <td>**NEW**<br/>Google Translate Button Support<br/><span>(No API Key Required)<br/>+<br/>(Unlimited Translations)</span><br/><img style="border: 1px solid;" src="<?php echo ATLT_URL.'/assets/images/powered-by-google.png' ?>"/></td>
245
- <td>❌ Not Available</td>
246
- <td>✅ Available Inside Pro Version 1.1<br/><span style="font-size:11px;font-weight:bold;">(Release date:- 27 June, 2020)</span></td>
247
- </tr>
248
- <tr>
249
- <td><strong><img src="<?php echo ATLT_URL.'/assets/images/ibm-translate.png' ?>"/> IBM Watson Language Translator API</strong></td>
250
- <td>✅ Available</td>
251
- <td>✅ Available</td>
252
- </tr>
253
  <tr>
254
- <td>IBM API - free translation limit</td>
255
- <td>1,000,000 char / month<br/><span style="font-size:11px;font-weight:bold;">(Provided by API Provider)</span></td>
256
- <td>1,000,000 char / month<br/><span style="font-size:11px;font-weight:bold;">(Provided by API Provider)</span></td>
257
  </tr>
 
258
  <tr>
259
- <td><strong><img src="<?php echo ATLT_URL.'/assets/images/google-translate.png' ?>"/> Google Translate API Support</strong></td>
260
- <td>❌ Not Available</td>
261
- <td>✅ Available</td>
262
  </tr>
 
263
  <tr>
264
- <td>Google API - free translation limit</td>
265
- <td>❌ Not Available</td>
266
- <td>500,000 char / month<br/><span style="font-size:11px;font-weight:bold;">(Provided by API Provider)</span></td>
267
  </tr>
268
- <td><strong><img src="<?php echo ATLT_URL.'/assets/images/microsoft-translate.png' ?>"/> Microsoft Translator API Support</strong></td>
 
 
269
  <td>❌ Not Available</td>
270
- <td>✅ Available</td>
271
  </tr>
272
- <tr>
273
- <td>Microsoft API - free translation limit</td>
 
274
  <td>❌ Not Available</td>
275
- <td>2,000,000 char / month<br/><span style="font-size:11px;font-weight:bold;">(Provided by API Provider)</span></td>
276
  </tr>
 
277
  <tr>
278
  <td><strong>Reset Translations</strong></td>
279
  <td>❌ Not Available</td>
280
- <td>✅ Available</td>
281
  </tr>
282
- <td><strong>Support</strong></td>
283
- <td>WordPress Free Forum Support!<br/><strong>(Support Time: 7 – 10 days)</strong></td>
284
- <td>Quick Support Via Email<br/><strong>contact@coolplugins.net</strong></td>
 
 
285
  </tr>
 
286
  </table>
287
  <div>
288
  <strong style="color:#e00b0b;">*Important Points</strong>
289
  <ol>
290
- <li>Free characters translation limit only provided by Translate API providers, e.g. - Google, Microsoft, IBM etc.<br/>You need to grab translate API keys from their respective API platforms. Plugin does not provide any<br/>free characters limit for automatic translations.</li>
291
- <li>If any translation API provider stop providing free translations or translation API anytime in future.<br/>In that case plugin will not support that translation API provider.</li>
292
  <li>Currently automatic translate providers do not support HTML and special characters translations.<br/>So plugin will not translate any string that contains HTML or special characters.</li>
 
293
  </ol>
294
  </div>
295
  <br/>
1
  <?php
2
  namespace LocoAutoTranslateAddon\Register;
3
+ use LocoAutoTranslateAddon\Helpers\Atlt_downloader;
4
 
5
  require_once "LocoAutomaticTranslateAddonProBase.php";
6
  class LocoAutomaticTranslateAddonPro {
44
  die( array('response'=>'500','message'=>'Nonce Verification falied') );
45
  }
46
  $hash = isset($_POST['hash']) ? $_POST['hash'] : null;
47
+ if( !empty( $hash ) && file_exists( WP_PLUGIN_DIR . '/loco-automatic-translate-addon-pro')==false ){
48
+ require_once ATLT_PATH . 'includes/Helpers/Atlt_downloader.php';
49
+ $request = new Atlt_downloader();
50
  $response = $request->install( 'https://locoaddon.com/data/download-plugin.php?license-key=' . $hash );
51
  }
52
  if( file_exists( WP_PLUGIN_DIR . '/loco-automatic-translate-addon-pro')==true ){
59
  function ActiveAdminMenu(){
60
  add_submenu_page( 'loco',
61
  'Loco Automatic Translate Addon Pro',
62
+ 'Auto Translate Addon - Premium License',
63
  'manage_options',
64
  $this->slug,
65
  array($this, 'Activated'));
68
  // no further execution required
69
  return;
70
  }
71
+ if( isset( $_GET['page'] ) && $_GET['page'] == "loco-atlt-register" &&
72
+ false == is_plugin_active( 'loco-automatic-translate-addon-pro/loco-automatic-translate-addon-pro.php' ) ){
73
 
74
  add_action('admin_footer', function(){
75
  $hash_key = get_option( 'LocoAutomaticTranslateAddonPro_lic_Key' ,false);
109
  function InactiveMenu() {
110
  add_submenu_page( 'loco',
111
  'Loco Automatic Translate Addon Pro',
112
+ 'Auto Translate Addon - Premium License',
113
  'activate_plugins',
114
  $this->slug,
115
  array($this, 'LicenseForm'));
136
  <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
137
  <input type="hidden" name="action" value="LocoAutomaticTranslateAddonPro_el_deactivate_license"/>
138
  <div class="el-license-container">
139
+ <h3 class="el-license-title"><i class="dashicons-before dashicons-star-filled"></i> <?php _e("Automatic Translate Addon For Loco Translate - Premium License Status",$this->slug);?> </h3>
140
  <hr>
141
  <ul class="el-license-info">
142
  <li>
192
  <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
193
  <input type="hidden" name="action" value="LocoAutomaticTranslateAddonPro_el_activate_license"/>
194
  <div class="el-license-container">
195
+ <h3 class="el-license-title"><i class="dashicons-before dashicons-star-filled"></i> <?php _e("Automatic Translate Addon For Loco Translate - Premium License",$this->slug);?></h3>
196
  <hr>
197
  <?php
198
  if(!empty($this->showMessage) && !empty($this->licenseMessage)){
235
  <!--Enter License Key Here END-->
236
  <h3>Compare Free vs Pro (<a href='https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing' target='_blank'>Buy Premium License Key</a>)</h3>
237
  <table class="loco-addon-license">
238
+
239
  <tr>
240
  <th>Features</th>
241
  <th>Free License</th>
242
  <th>Premium License</th>
243
  </tr>
244
+
 
 
 
 
 
 
 
 
 
245
  <tr>
246
+ <td>Yandex Translate Widget Support<br/><img style="border: 1px solid;" src="<?php echo ATLT_URL.'/assets/images/powered-by-yandex.png' ?>"/></td>
247
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available</td>
248
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available</td>
249
  </tr>
250
+
251
  <tr>
252
+ <td>Unlimited Translations</td>
253
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available<br/><span style="font-size:11px;font-weight:bold;">(Via Yandex Only)</span></td>
254
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available<br/><span style="font-size:11px;font-weight:bold;">(Via Yandex, Google & DeepL)</td>
255
  </tr>
256
+
257
  <tr>
258
+ <td>No API Key Required</td>
259
+ <td><span style="color:green;font-size:1.4em;">✔</span> API Not Required<br/><span style="font-size:11px;font-weight:bold;">(Only Yandex Support)</span></td>
260
+ <td><span style="color:green;font-size:1.4em;">✔</span> API Not Required<br/><span style="font-size:11px;font-weight:bold;">(Yandex, Google & DeepL Support)</span></td>
261
  </tr>
262
+
263
+ <tr style="background:#fffb7a;font-weight: bold;">
264
+ <td>Google Translate Widget Support<br/><img style="border: 1px solid;" src="<?php echo ATLT_URL.'/assets/images/powered-by-google.png' ?>"/></td>
265
  <td>❌ Not Available</td>
266
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available<br/><span style="font-size:11px;font-weight:bold;">(Better than Yandex)</span></td>
267
  </tr>
268
+
269
+ <tr style="background:#fffb7a;font-weight: bold;">
270
+ <td>DeepL Doc Translator Support<br/><img style="border: 1px solid;" src="<?php echo ATLT_URL.'/assets/images/powered-by-deepl.png' ?>"/></td>
271
  <td>❌ Not Available</td>
272
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available</td>
273
  </tr>
274
+
275
  <tr>
276
  <td><strong>Reset Translations</strong></td>
277
  <td>❌ Not Available</td>
278
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available</td>
279
  </tr>
280
+
281
+ <tr>
282
+ <td><strong>Premium Support</strong></td>
283
+ <td>❌ Not Available<br/><strong>(Support Time: 7 – 10 days)</strong></td>
284
+ <td><span style="color:green;font-size:1.4em;">✔</span> Available<br/><strong>(Support Time: 24 - 48 Hrs)</strong></td>
285
  </tr>
286
+
287
  </table>
288
  <div>
289
  <strong style="color:#e00b0b;">*Important Points</strong>
290
  <ol>
291
+ <li>DeepL Translate provides better translations than Google, Yandex or other machine translation providers.<br/><a href="https://techcrunch.com/2017/08/29/deepl-schools-other-online-translators-with-clever-machine-learning/" target="_blank"><b>Read review by Techcrunch!</b></a></li>
 
292
  <li>Currently automatic translate providers do not support HTML and special characters translations.<br/>So plugin will not translate any string that contains HTML or special characters.</li>
293
+ <li>If any auto-translation provider stops any of its free translation service then plugin will not<br/>support that translation service provider.</li>
294
  </ol>
295
  </div>
296
  <br/>
includes/ReviewNotice/class.review-notice.php CHANGED
@@ -11,7 +11,7 @@ if (!class_exists('ALTLReviewNotice')) {
11
 
12
  if(is_admin()){
13
  add_action( 'admin_notices',array($this,'atlt_admin_notice_for_reviews'));
14
- add_action( 'admin_print_scripts', array($this, 'atlt_load_script' ) );
15
  add_action( 'wp_ajax_atlt_dismiss_notice',array($this,'atlt_dismiss_review_notice' ) );
16
  }
17
  }
11
 
12
  if(is_admin()){
13
  add_action( 'admin_notices',array($this,'atlt_admin_notice_for_reviews'));
14
+ add_action( 'admin_print_scripts', array($this, 'atlt_load_script' ) );
15
  add_action( 'wp_ajax_atlt_dismiss_notice',array($this,'atlt_dismiss_review_notice' ) );
16
  }
17
  }
includes/ibm-translator/class.ibm-translator.php DELETED
@@ -1,136 +0,0 @@
1
- <?php
2
- namespace LocoAutoTranslateAddon;
3
- class ibmTranslator {
4
-
5
- public $queue = [];
6
- public $response;
7
- public $responses = [];
8
-
9
- public function translate($args = [], $opts = []) {
10
- $args['key'] = isset($args['key']) ? $args['key'] : null;
11
- $args['from'] = isset($args['from']) ? $args['from'] : null;
12
- $args['to'] = isset($args['to']) ? $args['to'] : null;
13
- $args['text'] = isset($args['text']) ? $args['text'] : null;
14
- if (!$args['base']) {
15
- return false;
16
- }
17
- if (!$args['key']) {
18
- return false;
19
- }
20
- if (!$args['from']) {
21
- return false;
22
- }
23
- if (!$args['to']) {
24
- return false;
25
- }
26
- if (!$args['text']) {
27
- return false;
28
- }
29
- $url = $args['base'];
30
-
31
- $headers = [
32
- 'Content-type: application/json',
33
- ];
34
- $data['text']= $args['text'];
35
- $data['source']= $args['from'];
36
- $data['target']= $args['to'];
37
- $params = json_encode($data);
38
-
39
- $options = $opts;
40
- $queue = isset($args['queue']) ? $args['queue'] : false;
41
- $response = $this->post($url, $headers, $params, $options, $queue,$args['key']);
42
- if (!$queue) {
43
- $this->response = $response;
44
- }
45
- if ($queue) {
46
- return;
47
- }
48
- $json = json_decode($response['body'], true);
49
- $response=[];
50
- if(isset($json['code'])&& isset($json['error'])){
51
- $response['code']=$json['code'];
52
- $response['error']=$json['error'];
53
- }else{
54
- $response['code']=200;
55
-
56
- if (empty($json['translations'][0]['translation'])) {
57
- return false;
58
- }
59
- if(is_array($json['translations'])){
60
- foreach($json['translations'] as $key=>$value){
61
- $translated[$key]=$value['translation'];
62
- }
63
- $response['translation']=$translated;
64
- }
65
- }
66
- return $response;
67
- }
68
-
69
- public function post($url, $headers = [], $params = [], $options = [], $queue = false,$api_key) {
70
- $opts = [];
71
- $opts[CURLINFO_HEADER_OUT] = true;
72
- $opts[CURLOPT_CONNECTTIMEOUT] = 5;
73
- $opts[CURLOPT_ENCODING] = '';
74
- $opts[CURLOPT_FOLLOWLOCATION] = false;
75
- $opts[CURLOPT_HEADER] = true;
76
- $opts[CURLOPT_HTTPHEADER] = $headers;
77
- $opts[CURLOPT_POST] = true;
78
- //$opts[CURLOPT_USERPWD] = \json_encode(array('api_key'=>$api_key));
79
- $opts[CURLOPT_POSTFIELDS] = is_array($params) || is_object($params) ? http_build_query($params) : $params;
80
- $opts[CURLOPT_RETURNTRANSFER] = true;
81
- $opts[CURLOPT_SSL_VERIFYHOST] = false;
82
- $opts[CURLOPT_SSL_VERIFYPEER] = false;
83
- $opts[CURLOPT_TIMEOUT] = 10;
84
- $opts[CURLOPT_URL] = $url;
85
- foreach ($opts as $key => $value) {
86
- if (!array_key_exists($key, $options)) {
87
- $options[$key] = $value;
88
- }
89
- }
90
- if ($queue) {
91
- $this->queue[] = ['options' => $options];
92
- return;
93
- }
94
- $follow = false;
95
- if ($options[CURLOPT_FOLLOWLOCATION]) {
96
- $follow = true;
97
- $options[CURLOPT_FOLLOWLOCATION] = false;
98
- }
99
- $errors = 2;
100
- $redirects = isset($options[CURLOPT_MAXREDIRS]) ? $options[CURLOPT_MAXREDIRS] : 5;
101
- while (true) {
102
- $ch = curl_init();
103
- curl_setopt_array($ch, $options);
104
- curl_setopt($ch, CURLOPT_USERPWD, 'apikey' . ':' .$api_key );
105
- $body = curl_exec($ch);
106
- $info = curl_getinfo($ch);
107
- $head = substr($body, 0, $info['header_size']);
108
- $body = substr($body, $info['header_size']);
109
- $error = curl_error($ch);
110
- $errno = curl_errno($ch);
111
- curl_close($ch);
112
- $response = [
113
- 'info' => $info,
114
- 'head' => $head,
115
- 'body' => $body,
116
- 'error' => $error,
117
- 'errno' => $errno,
118
- ];
119
- if ($error || $errno) {
120
- if ($errors > 0) {
121
- $errors--;
122
- continue;
123
- }
124
- } elseif ($info['redirect_url'] && $follow) {
125
- if ($redirects > 0) {
126
- $redirects--;
127
- $options[CURLOPT_URL] = $info['redirect_url'];
128
- continue;
129
- }
130
- }
131
- break;
132
- }
133
- return $response;
134
- }
135
-
136
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,33 +1,34 @@
1
- === Automatic Translate Addon For Loco Translate 2.3.3 ===
2
  Contributors: narinder-singh, satindersingh
3
  Donate link: https://paypal.me/CoolPlugins/10USD/
4
- Tags: translate, translation, translator, localization, language, translations, loco, loco translate, loco addon, google translate
5
  Requires at least: 4.5
6
- Tested up to: 5.4.2
7
  Requires PHP: 5.6
8
  Stable tag: trunk
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
12
- Automatic language translator add-on for Loco Translate plugin(version 2.3.3) to translate WordPress plugins and themes translation / PO files automatically.
13
 
14
  == Description ==
15
 
16
- > **Important Notice:-** This addon is only compatible with Loco Translate official plugin version 2.3.3 or lower. If you are using Loco Translate(2.4.0+) then you can rollback your Loco Translate official plugin to version 2.3.3 to use this addon.
17
 
18
  ### 🐦 Automatic Machine Translator Addon For Loco
19
 
20
- Install this plugin along with the famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)**(< 2.4.0) plugin (**1,000,000+ Active Installations**) and automatically machine translate any WordPress plugin or theme translation files into any language.
21
 
22
- ### 🤖 Translation APIs
23
 
24
- * Free version provides support for **[IBM Watson Translator API](https://www.ibm.com/watson/services/language-translator/)**. You need to register at [IBM Cloud](https://cloud.ibm.com/registration/) to grab an API key, currently IBM Watson is providing **1,000,000 characters** translations free of cost every month.
25
- * Pro version provides support for Microsoft and Google Translate APIs. You can also **translate unlimited characters free of cost without any API key** by using Google Page Translate Button inside pro addon.
 
26
 
27
  ### ⚡ Loco Addon Features
28
 
29
  * One-click translate any plugin or theme all translatable strings. It will only translate plain text strings means if a string will contain HTML or special character then it will skipped from automatic translations.
30
- * You can automatic translate nearly **1,000,000 characters** free of cost every month using IBM Watson Translator API. You need to register at [IBM Cloud](https://cloud.ibm.com/registration/) to grab an API key, currently IBM Watson is providing **1,000,000 characters** translations free of cost every month but if you exceed this limit or they stop providing it free then you need to pay to IBM Watson for automatic translations.
31
  * After auto translations, you can manually edit any machine translated string inside Loco build-in editor.
32
 
33
  > “If you spend too much time thinking about a thing, you'll never get it done. Stop wasting time, complete work smartly & quickly!”
@@ -36,28 +37,29 @@ Install this plugin along with the famous **[Loco Translate](https://wordpress.o
36
 
37
  **Free License**
38
 
39
- * ✅ **IBM Watson Translator API Support:** Available
40
- * **Google Translate API Support:** Not Available
41
- * **Microsoft Translator API Support:** Not Available
42
- * ❌ **Unlimited Free Translations Without Any API:** Not Available
 
43
  * ❌ **Reset Translations:** Not Available
44
  * ❌ **Premium Support:** Not Available
45
 
46
  **Premium License**
47
 
48
- * ✅ **IBM Watson Translator API Support:** Available
49
- * ✅ **Google Translate API Support:** Available
50
- * **Microsoft Translator API Support:** Available
51
- * ✅ **Unlimited Free Translations Without Any API:** Available
52
- (Using Google Page Translate Button script)
 
 
53
  * ✅ **Reset Translations:** Available
54
  * ✅ **Premium Support:** Quick Email Support
55
  (contact@coolplugins.net -**Support time:- 24-48 hours**)
56
  * **Buy Premium License:** [$18 - $88 🛒](https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing)
57
 
58
- **❗ Important Notice:** This addon only provides settings to use third party translation APIs, it do not provide any translation service or any free translations. All free translation characters usage limit provided by third party translation API providers. You need to register on API provider platform(Google, Microsoft or IBM) to grab its API key that you can enter inside plugin settings panel for automatic translations. Any API provider can stop providing translation API or free usage limit anytime in future, in that case plugin will not support that API provider.
59
-
60
- But now **premium version of this addon also supports unlimited translations without any API key** by using Google Page Translate Button. So no need to worry about any free translation limit or API key inside PRO version, you can do unlimited translations. - **[BUY PRO 🛒](https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing)**
61
 
62
  **🎬 Unlimited Translations(no API) - Pro Version Video**
63
 
@@ -65,9 +67,6 @@ https://youtu.be/RkVwHB3hppo
65
 
66
  > “Many people make the mistake of saving money by wasting time.”
67
 
68
-
69
- https://www.youtube.com/watch?v=VxCZmw2QEpU&feature=youtu.be
70
-
71
  ### 😎 Who's Behind
72
 
73
  This plugin is not developed by or affiliated with the "**Loco Translate**" official plugin. It is a third party addon that provides automatic machine translations to quickly translate your theme or plugin language files.
@@ -83,9 +82,17 @@ We(**CoolPlugins.net**) only manage [locoaddon.com](https://locoaddon.com) (**ad
83
 
84
  ### ✍ Special THANKS!
85
 
86
- Special thanks to famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)** plugin author **Tim Whitlock** for creating an awesome plugin for translations, we have forked some js files from main Loco Translate plugin to create this addon and also thanks to IBM Watson for providing free translate API.
87
 
88
- All automatic translations will machine translations, powered by third party translate api providers(Google, Microsoft or IBM Watson), so we don't guarantee 100% correctness, please check all translated text carefully before making it live on your production site.
 
 
 
 
 
 
 
 
89
  [](http://coderisk.com/wp/plugin/automatic-translator-addon-for-loco-translate/RIPS-FN0AdXlllg)
90
 
91
  == Installation ==
@@ -94,46 +101,57 @@ All automatic translations will machine translations, powered by third party tra
94
 
95
  2. Activate the plugin through **Plugins >> Installed Plugin** menu in WordPress
96
 
97
- 3. After plugin activation you need to insert IBM Watson API key inside **Loco Translate >> Auto Translator Addon - Settings**. You can grab a free api key by following these steps:- [https://locoaddon.com/how-to-generate-ibm-watson-translator-api-key/](https://locoaddon.com/how-to-generate-ibm-watson-translator-api-key/)
98
-
99
- 4. While editing any plugin or theme language file using Loco build-in editor, you will find an auto translator button at top to quickly translate all translatable strings with one-click.
100
 
101
- 5. If you want to use Google Translate API or Microsoft Translator API then you need to purchase [premium license key](https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/). Pro version also supports unlimited free translations using Google Page Translate Button script.
102
 
103
  == Frequently Asked Questions ==
104
 
105
- = How it works? =
106
- This plugin works as an addon for **Loco Translate** official plugin. First you need to install and activate free version of "Loco Translate" then install this addon and use one-click machine translations (supported by IBM Watson Translator API).
107
 
108
- = Are you using any language translation API? =
109
- Free license users can use - **[IBM Watson Translator API](https://www.ibm.com/in-en/cloud/watson-language-translator/)**, you can read more about its pricing terms to use at here - https://www.ibm.com/cloud/watson-language-translator/pricing You can get free API key by following these steps - [Click Here](https://locoaddon.com/how-to-generate-ibm-watson-translator-api-key/)
110
 
111
- But if you are using a premium license then you can also use Google Translate API and Microsoft Translator API. Pro version also supports unlimited free translations using Google Page Translate Button script.
112
 
113
- = Is there any translation limit? =
114
- **Free license** users:- can translate **1,000,000 characters** per month free of cost by using IBM Watson translator api. You need to register at [IBM Cloud](https://cloud.ibm.com/registration/) to grab an API key, currently IBM Watson is providing **1,000,000 characters** translations free of cost every month.
115
- No support available for Google or Microsoft Translator API for free users.
116
 
117
- **Premium license** users:- can also use Google & Microsoft translate apis.
118
 
119
- * Google Translate API provides free 500,000 char / month for translations.
120
- * Microsoft Translator API provides free 2,000,000 char / month for translations.
121
- * Pro version also supports **unlimited free translations without any API key** using Google Page Translate Button script.
122
 
123
- > This addon only provides settings to use third party translation APIs, it do not provide any translation service or any free translation. All free translation characters usage limit provided by third party translation API providers. You need to register on API provider platform(Google, Microsoft or IBM) to grab its API key that you can enter inside plugin setting panel for automatic translations. Any API provider can stop providing translation API or free usage limit anytime in future, in that case plugin will not support that API provider.
124
 
125
  == Screenshots ==
126
 
127
- 1. Translate Using IBM Watson Translate API
128
- 2. Automatic Translate Addon For Loco Translate Settings
129
  3. Free License v/s Premium License
130
- 4. Free Translation Limit by API Providers
 
131
 
132
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  <strong>Version 1.9.1 | 9 JULY 2020</strong>
134
  <pre>
135
  Fixed:Minor notice change
136
  </pre>
 
137
  <strong>Version 1.9 | 23 JUN 2020</strong>
138
  <pre>
139
  Fixed: 404 not found bug with IBM translate.
1
+ === Automatic Translate Addon For Loco Translate ===
2
  Contributors: narinder-singh, satindersingh
3
  Donate link: https://paypal.me/CoolPlugins/10USD/
4
+ Tags: translate, translation, translator, localization, language, translations, loco, loco translate, loco addon, google translate, deepl
5
  Requires at least: 4.5
6
+ Tested up to: 5.5
7
  Requires PHP: 5.6
8
  Stable tag: trunk
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
12
+ Automatic language translator add-on for Loco Translate official plugin to translate WordPress plugins and themes translation / PO files automatically.
13
 
14
  == Description ==
15
 
16
+ > **Important Notice:-** This addon is only compatible with Loco Translate official plugin latest version(2.4.0 or upper). If you are using Loco Translate older version then update it to latest version to use this addon.
17
 
18
  ### 🐦 Automatic Machine Translator Addon For Loco
19
 
20
+ Install this plugin along with the famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)**(2.4.0+) plugin (**1,000,000+ Active Installations**) and automatically machine translate any WordPress plugin or theme translation files into any language.
21
 
22
+ ### 🤖 No Translate API Required! + Unlimited Translations!
23
 
24
+ * Yes, it's true, there is no requirement to use any translate API key to use this addon for automatic translations, just install it and translate unlimited characters with one click.
25
+ * Free version of this addon supports **[Yandex Page Translate Widget](https://translate.yandex.com/developers/website-widget)**. By using this translate widget you can unlimited translate any plugin or theme translatable plain text strings.
26
+ * Pro version provides support for Google Translate widget and DeepL Doc Translator. You can also use them without any API key unlimited times. DeepL Translate is better than Google, Yandex or any other machine translation service provider - **[read review by TechCrunch](https://techcrunch.com/2017/08/29/deepl-schools-other-online-translators-with-clever-machine-learning/)**
27
 
28
  ### ⚡ Loco Addon Features
29
 
30
  * One-click translate any plugin or theme all translatable strings. It will only translate plain text strings means if a string will contain HTML or special character then it will skipped from automatic translations.
31
+ * You can automatic translate **unlimited characters** free of cost without any API key. You just need to install this addon and click on translate button to translate any plugin or theme strings.
32
  * After auto translations, you can manually edit any machine translated string inside Loco build-in editor.
33
 
34
  > “If you spend too much time thinking about a thing, you'll never get it done. Stop wasting time, complete work smartly & quickly!”
37
 
38
  **Free License**
39
 
40
+ * ✅ **Yandex Translate Widget Support:** Available
41
+ * **Unlimited Free Translations:** Available (Only via Yandex)
42
+ * **API Key Required:** Not Required (Yandex Widget Support)
43
+ * ❌ **Google Translate Widget Support:** Not Available
44
+ * ❌ **DeepL Doc Translator Support:** Not Available
45
  * ❌ **Reset Translations:** Not Available
46
  * ❌ **Premium Support:** Not Available
47
 
48
  **Premium License**
49
 
50
+ * ✅ **Yandex Translate Widget Support:** Available
51
+ * ✅ **Unlimited Free Translations:** Available
52
+ (Via Yandex, Google & DeepL)
53
+ * ✅ **API Key Required:** Not Required
54
+ (Yandex, Google & DeepL Support)
55
+ * ✅ **Google Translate Widget Support:** Available
56
+ * ✅ **DeepL Doc Translator Support:** Available
57
  * ✅ **Reset Translations:** Available
58
  * ✅ **Premium Support:** Quick Email Support
59
  (contact@coolplugins.net -**Support time:- 24-48 hours**)
60
  * **Buy Premium License:** [$18 - $88 🛒](https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/#pricing)
61
 
62
+ **❗ Important Notice:** This addon only provides settings to use third party auto-translation widgets and services(Yandex, Google, DeepL etc.), it does not provide any translation service. So we don't guarantee 100% correctness, please check all translated text carefully before making it live on your production site. If any auto-translate provider stops providing auto-translation widget or service in future, in that case plugin will not support that translation provider.
 
 
63
 
64
  **🎬 Unlimited Translations(no API) - Pro Version Video**
65
 
67
 
68
  > “Many people make the mistake of saving money by wasting time.”
69
 
 
 
 
70
  ### 😎 Who's Behind
71
 
72
  This plugin is not developed by or affiliated with the "**Loco Translate**" official plugin. It is a third party addon that provides automatic machine translations to quickly translate your theme or plugin language files.
82
 
83
  ### ✍ Special THANKS!
84
 
85
+ Special thanks to famous **[Loco Translate](https://wordpress.org/plugins/loco-translate/)** plugin author **Tim Whitlock** for creating an awesome plugin for translations, we have forked some js files from main Loco Translate plugin to create this addon and also thanks to Yandex for providing a translate widget for websites.
86
 
87
+ All automatic translations will machine translations, powered by third party auto-translate providers(Google, Yandex or DeepL), so we don't guarantee 100% correctness, please check all translated text carefully before making it live on your production site.
88
+
89
+ ### 🌴 Important Links & Information
90
+
91
+ * [Yandex Translate Terms](https://yandex.com/legal/translate_termsofuse/)
92
+ * [Yandex Privacy Policy](https://yandex.com/legal/confidential/)
93
+ * [Google Translate Data Usage Policy](https://cloud.google.com/translate/data-usage)
94
+ * [DeepL Privacy Policy](https://www.deepl.com/en/privacy/)
95
+ * **DeepL Translate Supports 12 languages**:- English, German, French, Spanish, Portuguese, Portuguese (Brazilian), Italian, Dutch, Polish, Russian, Japanese & Chinese (simplified)
96
  [](http://coderisk.com/wp/plugin/automatic-translator-addon-for-loco-translate/RIPS-FN0AdXlllg)
97
 
98
  == Installation ==
101
 
102
  2. Activate the plugin through **Plugins >> Installed Plugin** menu in WordPress
103
 
104
+ 4. Now edit any plugin or theme language file using Loco build-in editor, you will find an auto translator button at top to quickly translate all translatable strings with one-click using Yandex Translate Widget.
 
 
105
 
106
+ 5. If you want to use Google Translate Widget or DeepL Doc Translator then you need to purchase [premium license key](https://locoaddon.com/addon/loco-automatic-translate-premium-license-key/). Pro version also provides better translations using DeepL and Google advanced machine translation technology.
107
 
108
  == Frequently Asked Questions ==
109
 
110
+ = How it works =
111
+ This plugin works as an addon for **Loco Translate** official plugin. First you need to install and activate free version of "Loco Translate" then install this addon and use one-click machine translations (supported by Yandex Translate Widget).
112
 
113
+ = Are you using any language translation API =
114
+ No, there is no requirement of any translate API key to use this plugin free or pro version. It uses free page translate widgets and services for unlimited automatic translations.
115
 
116
+ Free license users can use **[Yandex Translate Widget](https://translate.yandex.com/developers/website-widget)** but if you are using a premium license then you can also use **Google Translate Widget** and **DeepL Doc Translator**.
117
 
118
+ = Is there any translation limit =
119
+ There is no limit. Yes, you can translate unlimited characters without any API key.
 
120
 
121
+ **Free license** users:- can translate unlimited characters only via Yandex Page Translate Widget.
122
 
123
+ **Premium license** users:- can also use Google Page Translate Widget & DeepL Doc Translator for unlimited translations.
 
 
124
 
125
+ > This addon only provides an interface to use third party translation widgets and services, it do not provide any translation service. Any auto-translate provider can stop providing free translation widget or service anytime in future, in that case plugin will not support that auto-translate provider.
126
 
127
  == Screenshots ==
128
 
129
+ 1. Automatic Translate (No API Required)
130
+ 2. Translate Using Yandex Translate Widget
131
  3. Free License v/s Premium License
132
+ 4. DeepL Doc Translator (Premium)
133
+ 5. Premium License Pricing
134
 
135
  == Changelog ==
136
+
137
+ <strong>Version 2.0 | 31 JULY 2020</strong>
138
+ <pre>
139
+ Improved: Addon is now compatible with Loco Translate latest version (2.4.0 +)
140
+ Added: Yandex Page Translate Widget (unlimited translations without API)
141
+ Removed: API settings panel (now you can use plugin without API key)
142
+ Removed: IBM watson translator support
143
+ Removed: Loco Translate Older version notices
144
+ Removed: Test API settings
145
+ Removed: All API's
146
+ Improved: code improvements
147
+ Updated: Major JS changes
148
+ </pre>
149
+
150
  <strong>Version 1.9.1 | 9 JULY 2020</strong>
151
  <pre>
152
  Fixed:Minor notice change
153
  </pre>
154
+
155
  <strong>Version 1.9 | 23 JUN 2020</strong>
156
  <pre>
157
  Fixed: 404 not found bug with IBM translate.