From 882959ba6905f50d82cbbeb2ec1fc77085c4f809 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Wed, 18 Mar 2020 14:07:12 +0800 Subject: [PATCH 001/231] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E7=89=88=E4=B8=8B=E8=BD=BD=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 24b63ab..786b2d0 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ ## 使用方法 -Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定版:[点击下载](https://github.com/sunxiyuan/wp-china-yes/releases/download/v2.0.1/wp-china-yes.zip) +Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定版:[点击下载](https://github.com/sunxiyuan/wp-china-yes/releases/download/v2.0.2/wp-china-yes.zip) 下载并安装插件后直接启用即可,该插件会自动接管所有WP访问境外服务器的流量。 From c740a64bb1fec4d4c513604368140a637e85bf8b Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 20 Mar 2020 08:02:20 +0800 Subject: [PATCH 002/231] =?UTF-8?q?=E4=BD=BF=E6=8B=89=E5=8F=96=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=E4=BB=93=E5=BA=93=E6=BA=90=E5=88=97=E8=A1=A8=E7=9A=84?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E5=9C=A8=E8=8E=B7=E5=8F=96=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=88=90=E5=8A=9F=E5=90=8E=E8=BF=9B=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.html | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/settings.html b/settings.html index 6783e7c..4ec0332 100644 --- a/settings.html +++ b/settings.html @@ -153,6 +153,17 @@ axios.post(root_url + 'wp-admin/admin-ajax.php', data) .then(function (response) { vm.mirrors_form = response.data.data; + axios.get('https://wp-china-yes.ibadboy.net') + .then(function (response) { + vm.external_api = response.data; + vm.changeServer(); + }) + .catch(function (error) { + vm.$message({ + message: error, + type: 'error' + }); + }); }) .catch(function (error) { vm.$message({ @@ -160,18 +171,6 @@ type: 'error' }); }); - - axios.get('https://wp-china-yes.ibadboy.net') - .then(function (response) { - vm.external_api = response.data; - vm.changeServer(); - }) - .catch(function (error) { - vm.$message({ - message: error, - type: 'error' - }); - }); }, submitMirrorsForm() { let vm = this; From c9bb6daa3f3d013770822b1fa0bee664d5970ea5 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 20 Mar 2020 08:05:43 +0800 Subject: [PATCH 003/231] =?UTF-8?q?=E6=B7=BB=E5=8A=A02.0.3=E5=AD=90?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 786b2d0..015577e 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ ## 使用方法 -Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定版:[点击下载](https://github.com/sunxiyuan/wp-china-yes/releases/download/v2.0.2/wp-china-yes.zip) +Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定版:[点击下载](https://github.com/sunxiyuan/wp-china-yes/releases/download/v2.0.3/wp-china-yes.zip) 下载并安装插件后直接启用即可,该插件会自动接管所有WP访问境外服务器的流量。 @@ -37,6 +37,9 @@ Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定 - [ ] 定时提醒排序、启动时提醒排序 - [ ] 社区源宕机切换提示 +### v2.0.3 + - [x] 修复修改仓库源后刷新页面无法正确展示源信息的问题 + ### v2.0.2 - [x] 修复API接口编写不规范的问题 From 620d87b794ff927cb1c295842059a7d7113484d5 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 23 Mar 2020 17:42:38 +0800 Subject: [PATCH 004/231] =?UTF-8?q?=E6=9B=B4=E6=96=B02.2.0=E7=89=88?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E8=AE=A1=E5=88=92=EF=BC=8C=E5=B9=B6=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E4=B8=80=E4=B8=AA=E5=B7=B2=E7=9F=A5=E4=BD=86=E6=9C=AA?= =?UTF-8?q?=E6=9C=89=E8=A7=A3=E5=86=B3=E6=96=B9=E6=A1=88=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 015577e..7339af2 100644 --- a/readme.md +++ b/readme.md @@ -25,10 +25,14 @@ Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定 ## 开发计划 -### v2.2.0 +### v2.3.0 - [ ] 贡献者列表 - [ ] 捐助者列表 +### v2.2.0 + - [ ] 谷歌字体代理 + - [ ] Gravatar头像代理 + ### v2.1.0 这个版本主要想将用户平均分布在各个优质源上,同时帮助社区源赞助企业获得更多的品牌曝光机会 @@ -51,4 +55,7 @@ Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定 - [x] 自定义源支持 ### v1.0.0 - - [x] 基本功能 \ No newline at end of file + - [x] 基本功能 + +已知但未有解决方案的BUG + - 部分插件作者直接在Trunk目录发布新版插件,这样新版本就没有Tag标记,导致更新的时候下载下来的还是CDN缓存的旧版本。 \ No newline at end of file From c231f262db7e5cab6ed9cd992c1ebd6bcb94ecde Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Wed, 25 Mar 2020 09:48:42 +0800 Subject: [PATCH 005/231] =?UTF-8?q?=E7=BB=8F=E6=88=91=E7=88=B1=E6=B0=B4?= =?UTF-8?q?=E7=85=AE=E9=B1=BC(http://blog.wpjam.com)=E6=8F=90=E9=86=92?= =?UTF-8?q?=EF=BC=8C=E6=8F=92=E4=BB=B6=E6=A0=B8=E5=BF=83=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E7=B2=BE=E7=AE=80=E6=8E=89100=E4=BD=99?= =?UTF-8?q?=E8=A1=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 129 +++--------------------------------------------------- 1 file changed, 5 insertions(+), 124 deletions(-) diff --git a/index.php b/index.php index 2eda3f5..35441e2 100644 --- a/index.php +++ b/index.php @@ -85,130 +85,11 @@ class WP_CHINA_YES { $url = str_replace('api.wordpress.org', $api_server, $url); $url = str_replace('downloads.wordpress.org', $download_server, $url); - if (function_exists('wp_kses_bad_protocol')) { - if ($r['reject_unsafe_urls']) { - $url = wp_http_validate_url($url); - } - if ($url) { - $url = wp_kses_bad_protocol($url, array( - 'http', - 'https', - 'ssl' - )); - } - } - - $arrURL = @parse_url($url); - - if (empty($url) || empty($arrURL['scheme'])) { - return new WP_Error('http_request_failed', __('A valid URL was not provided.')); - } - - if ($r['stream']) { - if (empty($r['filename'])) { - $r['filename'] = get_temp_dir() . basename($url); - } - - $r['blocking'] = true; - if ( ! wp_is_writable(dirname($r['filename']))) { - return new WP_Error('http_request_failed', __('Destination directory for file streaming does not exist or is not writable.')); - } - } - - if (is_null($r['headers'])) { - $r['headers'] = array(); - } - - if ( ! is_array($r['headers'])) { - $processedHeaders = WP_Http::processHeaders($r['headers']); - $r['headers'] = $processedHeaders['headers']; - } - - $headers = $r['headers']; - $data = $r['body']; - $type = $r['method']; - $options = array( - 'timeout' => $r['timeout'], - 'useragent' => $r['user-agent'], - 'blocking' => $r['blocking'], - 'hooks' => new WP_HTTP_Requests_Hooks($url, $r), - ); - - if ($r['stream']) { - $options['filename'] = $r['filename']; - } - if (empty($r['redirection'])) { - $options['follow_redirects'] = false; - } else { - $options['redirects'] = $r['redirection']; - } - - if (isset($r['limit_response_size'])) { - $options['max_bytes'] = $r['limit_response_size']; - } - - if ( ! empty($r['cookies'])) { - $options['cookies'] = WP_Http::normalize_cookies($r['cookies']); - } - - if ( ! $r['sslverify']) { - $options['verify'] = false; - $options['verifyname'] = false; - } else { - $options['verify'] = $r['sslcertificates']; - } - - if ('HEAD' !== $type && 'GET' !== $type) { - $options['data_format'] = 'body'; - } - - $options['verify'] = apply_filters('https_ssl_verify', $options['verify'], $url); - - $proxy = new WP_HTTP_Proxy(); - if ($proxy->is_enabled() && $proxy->send_through_proxy($url)) { - $options['proxy'] = new Requests_Proxy_HTTP($proxy->host() . ':' . $proxy->port()); - - if ($proxy->use_authentication()) { - $options['proxy']->use_authentication = true; - $options['proxy']->user = $proxy->username(); - $options['proxy']->pass = $proxy->password(); - } - } - - mbstring_binary_safe_encoding(); - - try { - $requests_response = Requests::request($url, $headers, $data, $type, $options); - - $http_response = new WP_HTTP_Requests_Response($requests_response, $r['filename']); - $response = $http_response->to_array(); - - $response['http_response'] = $http_response; - } catch (Requests_Exception $e) { - $response = new WP_Error('http_request_failed', $e->getMessage()); - } - - reset_mbstring_encoding(); - - do_action('http_api_debug', $response, 'response', 'Requests', $r, $url); - if (is_wp_error($response)) { - return $response; - } - - if ( ! $r['blocking']) { - return array( - 'headers' => array(), - 'body' => '', - 'response' => array( - 'code' => false, - 'message' => false, - ), - 'cookies' => array(), - 'http_response' => null, - ); - } - - return apply_filters('http_response', $response, $r, $url); + /** + * 此处原本是复制了官方对外部请求处理的原始代码 + * 后经我爱水煮鱼(http://blog.wpjam.com/)提醒,可以直接调用wp_remote_request达成相同目的,由此精简掉100余行代码。 + */ + return wp_remote_request($url , $r); } public static function plugin_row_meta($links, $file) { From 291f64a7a31a7dceccd352c0de930b99fb47a379 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 27 Mar 2020 15:12:43 +0800 Subject: [PATCH 006/231] =?UTF-8?q?=E5=B0=86=E9=85=8D=E7=BD=AE=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E6=96=B9=E6=B3=95=E6=8A=BD=E5=8F=96=E5=87=BA=E6=9D=A5?= =?UTF-8?q?=E5=8D=95=E7=8B=AC=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/index.php b/index.php index 35441e2..14a1a20 100644 --- a/index.php +++ b/index.php @@ -61,13 +61,7 @@ class WP_CHINA_YES { } public static function wp_china_yes_activate() { - $options = array(); - $options['community'] = '0'; - $options['custom_api_server'] = ''; - $options['custom_download_server'] = ''; - $options['api_server'] = 'api.w.org.ibadboy.net'; - $options['download_server'] = 'd.w.org.ibadboy.net'; - add_option('wp_china_yes_options', $options); + self::set_wp_option(); } public static function wp_china_yes_deactivate() { @@ -155,14 +149,15 @@ EOT; self::error('参数错误', - 1); } - $options = array(); - $options['community'] = sanitize_text_field(trim($_POST['community'])); - $options['custom_api_server'] = sanitize_text_field(trim($_POST['custom_api_server'])); - $options['custom_download_server'] = sanitize_text_field(trim($_POST['custom_download_server'])); - $options["api_server"] = sanitize_text_field(trim($_POST['api_server'])); - $options["download_server"] = sanitize_text_field(trim($_POST['download_server'])); - update_option("wp_china_yes_options", $options); - self::success('', $options); + self::set_wp_option( + sanitize_text_field(trim($_POST['community'])), + sanitize_text_field(trim($_POST['custom_api_server'])), + sanitize_text_field(trim($_POST['custom_download_server'])), + sanitize_text_field(trim($_POST['api_server'])), + sanitize_text_field(trim($_POST['download_server'])) + ); + + self::success(); } private static function success($message = '', $data = []) { @@ -186,4 +181,20 @@ EOT; ], JSON_UNESCAPED_UNICODE); exit; } + + private static function set_wp_option( + $community = 0, + $custom_api_server = '', + $custom_download_server = '', + $api_server = 'api.w.org.ibadboy.net', + $download_server = 'd.w.org.ibadboy.net' + ) { + $options = array(); + $options['community'] = (int) $community; + $options['custom_api_server'] = $custom_api_server; + $options['custom_download_server'] = $custom_download_server; + $options['api_server'] = $api_server; + $options['download_server'] = $download_server; + update_option("wp_china_yes_options", $options); + } } \ No newline at end of file From 248b2b486eaedb89a364a4496b9fabb6924658e6 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 27 Mar 2020 15:13:07 +0800 Subject: [PATCH 007/231] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 14a1a20..2e2c77d 100644 --- a/index.php +++ b/index.php @@ -83,7 +83,7 @@ class WP_CHINA_YES { * 此处原本是复制了官方对外部请求处理的原始代码 * 后经我爱水煮鱼(http://blog.wpjam.com/)提醒,可以直接调用wp_remote_request达成相同目的,由此精简掉100余行代码。 */ - return wp_remote_request($url , $r); + return wp_remote_request($url, $r); } public static function plugin_row_meta($links, $file) { From 4c62386d3073c0df3ac06a9360598cd83436a748 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 27 Mar 2020 15:33:07 +0800 Subject: [PATCH 008/231] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AF=B9=E5=AD=90?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E9=83=A8=E7=BD=B2=E7=9A=84WP=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9A=84=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/index.php b/index.php index 2e2c77d..e9154d3 100644 --- a/index.php +++ b/index.php @@ -119,15 +119,13 @@ class WP_CHINA_YES { } public static function settings() { - $iframe_str = << - EOT; - $plugin_root_url = plugins_url(); - $iframe_str = str_replace('/wp-content/plugins', $plugin_root_url, $iframe_str); - echo $iframe_str; } public static function set_cookie() { From 3c95035bba9ff40230bc6f17b510103cfaf108f3 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 27 Mar 2020 15:48:10 +0800 Subject: [PATCH 009/231] =?UTF-8?q?=E8=B0=83=E6=95=B4options=E7=9A=84?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.php b/index.php index e9154d3..42d35a2 100644 --- a/index.php +++ b/index.php @@ -149,10 +149,10 @@ EOT; self::set_wp_option( sanitize_text_field(trim($_POST['community'])), - sanitize_text_field(trim($_POST['custom_api_server'])), - sanitize_text_field(trim($_POST['custom_download_server'])), sanitize_text_field(trim($_POST['api_server'])), - sanitize_text_field(trim($_POST['download_server'])) + sanitize_text_field(trim($_POST['download_server'])), + sanitize_text_field(trim($_POST['custom_api_server'])), + sanitize_text_field(trim($_POST['custom_download_server'])) ); self::success(); @@ -182,17 +182,17 @@ EOT; private static function set_wp_option( $community = 0, - $custom_api_server = '', - $custom_download_server = '', $api_server = 'api.w.org.ibadboy.net', - $download_server = 'd.w.org.ibadboy.net' + $download_server = 'd.w.org.ibadboy.net', + $custom_api_server = '', + $custom_download_server = '' ) { $options = array(); $options['community'] = (int) $community; - $options['custom_api_server'] = $custom_api_server; - $options['custom_download_server'] = $custom_download_server; $options['api_server'] = $api_server; $options['download_server'] = $download_server; + $options['custom_api_server'] = $custom_api_server; + $options['custom_download_server'] = $custom_download_server; update_option("wp_china_yes_options", $options); } } \ No newline at end of file From bf6eebb8d5d2c79e45b2c94b9b0fdd7278608828 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Thu, 2 Apr 2020 16:46:24 +0800 Subject: [PATCH 010/231] =?UTF-8?q?=E8=BF=94=E7=92=9E=E5=BD=92=E7=9C=9F=20?= =?UTF-8?q?=E6=9C=AC=E6=AC=A1=E6=8F=90=E4=BA=A4=E5=8E=BB=E9=99=A4=E7=A4=BE?= =?UTF-8?q?=E5=8C=BA=E6=BA=90=E9=80=89=E6=8B=A9=E3=80=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E6=BA=90=E8=AE=BE=E7=BD=AE=E7=9B=B8=E5=85=B3=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E5=B9=B6=E7=A7=BB=E9=99=A4=E4=BA=86=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E8=AE=BE=E7=BD=AE=E9=A1=B5=E3=80=82=E5=8F=AA=E6=8F=90?= =?UTF-8?q?=E4=BE=9B=E4=B8=80=E4=B8=AA=E5=94=AF=E4=B8=80=E7=9A=84=E4=BF=9D?= =?UTF-8?q?=E8=AF=81=E9=AB=98=E5=8F=AF=E9=9D=A0=E9=AB=98=E9=80=9F=E5=BA=A6?= =?UTF-8?q?=E7=A4=BE=E5=8C=BA=E6=BA=90=E3=80=82=20=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=87=AA=E5=AE=9A=E4=B9=89=E6=BA=90=E7=9A=84?= =?UTF-8?q?=E5=B0=8F=E4=BC=99=E4=BC=B4=E5=8F=AF=E4=BB=A5=E7=9C=8B=E4=B8=80?= =?UTF-8?q?=E4=B8=8Bcustom=E5=88=86=E6=94=AF=EF=BC=8C=E8=BF=99=E9=87=8C?= =?UTF-8?q?=E6=9C=89=E6=8F=90=E4=BE=9B=E4=B8=80=E4=B8=AA=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E7=89=88=E6=9C=AC=EF=BC=8C=E5=8F=AF=E4=BB=A5=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E6=A4=8D=E5=85=A5=E4=B8=BB=E9=A2=98=E7=9A=84functions.php?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=AD=E3=80=82=20https://github.com/sunxi?= =?UTF-8?q?yuan/wp-china-yes/tree/custom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 152 +------------------------------ settings.html | 246 -------------------------------------------------- 2 files changed, 3 insertions(+), 395 deletions(-) delete mode 100644 settings.html diff --git a/index.php b/index.php index 42d35a2..da2033d 100644 --- a/index.php +++ b/index.php @@ -9,22 +9,11 @@ * License URI: http://www.gnu.org/licenses/gpl-3.0.html */ -define('WP_CHINA_YES_PATH', __DIR__); -define('WP_CHINA_YES_BASE_FILE', __FILE__); - WP_CHINA_YES::init(); class WP_CHINA_YES { public static function init() { if (is_admin()) { - register_activation_hook(WP_CHINA_YES_BASE_FILE, array( - __CLASS__, - 'wp_china_yes_activate' - )); - register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array( - __CLASS__, - 'wp_china_yes_deactivate' - )); add_filter('pre_http_request', array( __CLASS__, 'pre_http_request' @@ -33,51 +22,16 @@ class WP_CHINA_YES { __CLASS__, 'plugin_row_meta' ), 10, 2); - add_filter('plugin_action_links', array( - __CLASS__, - 'action_links' - ), 10, 2); - add_action('admin_menu', array( - __CLASS__, - 'admin_menu' - )); - add_action('init', array( - __CLASS__, - 'set_cookie' - )); - add_action('wp_ajax_wpcy_get_config', array( - __CLASS__, - 'get_config' - )); - add_action('wp_ajax_wpcy_set_config', array( - __CLASS__, - 'set_config' - )); - - if (empty(get_option('wp_china_yes_options'))) { - self::wp_china_yes_activate(); - } } } - public static function wp_china_yes_activate() { - self::set_wp_option(); - } - - public static function wp_china_yes_deactivate() { - delete_option('wp_china_yes_options'); - } - public static function pre_http_request($preempt, $r, $url) { if ( ! stristr($url, 'api.wordpress.org') && ! stristr($url, 'downloads.wordpress.org')) { return false; } - $options = get_option('wp_china_yes_options'); - $api_server = $options["custom_api_server"] ?: $options["api_server"]; - $download_server = $options["custom_download_server"] ?: $options["download_server"]; - $url = str_replace('api.wordpress.org', $api_server, $url); - $url = str_replace('downloads.wordpress.org', $download_server, $url); + $url = str_replace('api.wordpress.org', 'api.w.org.ibadboy.net', $url); + $url = str_replace('downloads.wordpress.org', 'd.w.org.ibadboy.net', $url); /** * 此处原本是复制了官方对外部请求处理的原始代码 @@ -87,7 +41,7 @@ class WP_CHINA_YES { } public static function plugin_row_meta($links, $file) { - $base = plugin_basename(WP_CHINA_YES_BASE_FILE); + $base = plugin_basename(__FILE__); if ($file == $base) { $links[] = '发布地址'; $links[] = 'GitHub'; @@ -95,104 +49,4 @@ class WP_CHINA_YES { return $links; } - - public static function action_links($links, $file) { - if ($file != plugin_basename(WP_CHINA_YES_BASE_FILE)) { - return $links; - } - - $settings_link = '设置'; - - array_unshift($links, $settings_link); - - return $links; - } - - public static function admin_menu() { - add_options_page( - 'WP-China-Yes', - 'WP-China-Yes', - 'manage_options', - 'wp_china_yes', - array(__CLASS__, 'settings') - ); - } - - public static function settings() { - $setting_page_url = plugins_url('settings.html', __FILE__); - echo << - -EOT; - } - - public static function set_cookie() { - if ( ! isset($_COOKIE['wp-china-yes']) && current_user_can('manage_options')) { - setcookie('wp-china-yes', json_encode([ - 'get_config' => wp_create_nonce('wpcy_get_config'), - 'set_config' => wp_create_nonce('wpcy_set_config') - ], JSON_UNESCAPED_UNICODE), time() + 1209600, COOKIEPATH, COOKIE_DOMAIN, false); - } - } - - public static function get_config() { - self::success('', get_option('wp_china_yes_options')); - } - - public static function set_config() { - if (( ! array_key_exists('api_server', $_POST) && ! array_key_exists('download_server', $_POST)) || - ( ! array_key_exists('community', $_POST) && ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) { - self::error('参数错误', - 1); - } - - self::set_wp_option( - sanitize_text_field(trim($_POST['community'])), - sanitize_text_field(trim($_POST['api_server'])), - sanitize_text_field(trim($_POST['download_server'])), - sanitize_text_field(trim($_POST['custom_api_server'])), - sanitize_text_field(trim($_POST['custom_download_server'])) - ); - - self::success(); - } - - private static function success($message = '', $data = []) { - header('Content-Type:application/json; charset=utf-8'); - - echo json_encode([ - 'code' => 0, - 'message' => $message, - 'data' => $data - ], JSON_UNESCAPED_UNICODE); - exit; - } - - private static function error($message = '', $code = - 1) { - header('Content-Type:application/json; charset=utf-8'); - header('Status:500'); - - echo json_encode([ - 'code' => $code, - 'message' => $message - ], JSON_UNESCAPED_UNICODE); - exit; - } - - private static function set_wp_option( - $community = 0, - $api_server = 'api.w.org.ibadboy.net', - $download_server = 'd.w.org.ibadboy.net', - $custom_api_server = '', - $custom_download_server = '' - ) { - $options = array(); - $options['community'] = (int) $community; - $options['api_server'] = $api_server; - $options['download_server'] = $download_server; - $options['custom_api_server'] = $custom_api_server; - $options['custom_download_server'] = $custom_download_server; - update_option("wp_china_yes_options", $options); - } } \ No newline at end of file diff --git a/settings.html b/settings.html deleted file mode 100644 index 4ec0332..0000000 --- a/settings.html +++ /dev/null @@ -1,246 +0,0 @@ - - - - - WP-China-Yes设置页 - - - -
- - -

WP-China-Yes

- 这是一个颠覆性的插件,她将全面改善中国大陆站点在访问WP官方服务时的用户体验
- 原理是将位于国外的官方仓库源替换为由社区志愿者维护的国内源,以此达到加速访问的目的 -
- - - - - - - - -
- 使用社区源 -
- - - - - - - -
- -
- 自定义源 - 若配置自定义源则会覆盖社区源 - 搭建方法 - -
- - - - - - - - - - -
- - 保存配置 - - -
-
-
-
- - - - -
-
- - - 这是一个开源项目,她需要每个人的支持和贡献才能健康长久的发展。
- 项目地址:GitHub -
-
-
- - - - - - - From 50112df6c049a2dd388eb06a8cc50e72d0e302ba Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 3 Apr 2020 16:11:33 +0800 Subject: [PATCH 011/231] update redame.md --- readme.md | 44 +------------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/readme.md b/readme.md index 7339af2..c3c73d0 100644 --- a/readme.md +++ b/readme.md @@ -16,46 +16,4 @@ ## 使用方法 -Master上的是开发中的版本,可能存在BUG。推荐安装最新稳定版:[点击下载](https://github.com/sunxiyuan/wp-china-yes/releases/download/v2.0.3/wp-china-yes.zip) - -下载并安装插件后直接启用即可,该插件会自动接管所有WP访问境外服务器的流量。 - -### 特别说明! -无论你使用何种方法安装插件,请一定保证插件的目录名是`wp-china-yes`,否则插件将无法正常工作。 - -## 开发计划 - -### v2.3.0 - - [ ] 贡献者列表 - - [ ] 捐助者列表 - -### v2.2.0 - - [ ] 谷歌字体代理 - - [ ] Gravatar头像代理 - -### v2.1.0 - 这个版本主要想将用户平均分布在各个优质源上,同时帮助社区源赞助企业获得更多的品牌曝光机会 - - - [ ] 节点使用数量统计 - - [ ] 社区源测速排序,并根据节点使用人数智能推荐负载较小的节点 - - [ ] 定时提醒排序、启动时提醒排序 - - [ ] 社区源宕机切换提示 - -### v2.0.3 - - [x] 修复修改仓库源后刷新页面无法正确展示源信息的问题 - -### v2.0.2 - - [x] 修复API接口编写不规范的问题 - -### v2.0.1 - - [x] 修复插件无法运行在使用子目录部署的WordPress上的问题 - -### v2.0.0 - - [x] 社区源列表 - - [x] 自定义源支持 - -### v1.0.0 - - [x] 基本功能 - -已知但未有解决方案的BUG - - 部分插件作者直接在Trunk目录发布新版插件,这样新版本就没有Tag标记,导致更新的时候下载下来的还是CDN缓存的旧版本。 \ No newline at end of file +下载并安装插件后直接启用即可,该插件会自动接管所有WP访问境外服务器的流量。 \ No newline at end of file From 3163e2e41c767c6804bb7950efaad93463dfcab0 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Sat, 4 Apr 2020 12:06:06 +0800 Subject: [PATCH 012/231] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index da2033d..3da0533 100644 --- a/index.php +++ b/index.php @@ -30,8 +30,8 @@ class WP_CHINA_YES { return false; } - $url = str_replace('api.wordpress.org', 'api.w.org.ibadboy.net', $url); - $url = str_replace('downloads.wordpress.org', 'd.w.org.ibadboy.net', $url); + $url = str_replace('api.wordpress.org', 'api.w.org.ibadboy.net', $url); + $url = str_replace('downloads.wordpress.org', 'd.w.org.ibadboy.net', $url); /** * 此处原本是复制了官方对外部请求处理的原始代码 From 7dc13d932959054733163204f855594ceb979282 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Sat, 4 Apr 2020 12:06:39 +0800 Subject: [PATCH 013/231] =?UTF-8?q?=E4=BB=AA=E8=A1=A8=E7=9B=98=E7=9A=84?= =?UTF-8?q?=E8=B5=9E=E5=8A=A9=E8=80=85=E5=88=97=E8=A1=A8=E5=B0=8F=E9=83=A8?= =?UTF-8?q?=E4=BB=B6=E6=A1=86=E6=9E=B6=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- donors_widgets.php | 4 ++++ index.php | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 donors_widgets.php diff --git a/donors_widgets.php b/donors_widgets.php new file mode 100644 index 0000000..91d38f0 --- /dev/null +++ b/donors_widgets.php @@ -0,0 +1,4 @@ + Date: Thu, 9 Apr 2020 20:33:35 +0800 Subject: [PATCH 014/231] =?UTF-8?q?=E8=B5=9E=E5=8A=A9=E5=95=86=E5=B0=8F?= =?UTF-8?q?=E9=83=A8=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/global.css | 84 ++++++++++++++++++++++++++++++++++++++++++++ donors_widgets.php | 84 +++++++++++++++++++++++++++++++++++++++++++- image/clsoe.svg | 1 + image/enterprise.svg | 1 + image/personage.svg | 1 + image/school.svg | 1 + 6 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 css/global.css create mode 100644 image/clsoe.svg create mode 100644 image/enterprise.svg create mode 100644 image/personage.svg create mode 100644 image/school.svg diff --git a/css/global.css b/css/global.css new file mode 100644 index 0000000..e318bde --- /dev/null +++ b/css/global.css @@ -0,0 +1,84 @@ +.sponsor-item-logo { + width: 70px; + height: 60px; +} + +.sponsor-item-container { + height: 70px; + display: flex; + min-width: 350px; + line-height: 24px; + margin-bottom: 10px; + border-bottom: 1px solid #eee; +} + +.sponsor-item-synopsis { + margin-left: 10px; +} + +.sponsor-item-title { + color: #000; + cursor: pointer; + text-decoration:none; +} + +.sponsor-item-title:hover{ + opacity: 0.5; +} +.sponsor-item-title-icon{ + width: 16px; + margin-right: 8px; +} + +.sponsor-item-content { + height: 24px; + padding: 0 10px; + line-height: 20px; + font-size: 12px; + margin: 3px 8px 0 0; + color: #409eff; + border-radius: 4px; + white-space: nowrap; + display: inline-block; + box-sizing: border-box; + background-color: #ecf5ff; + border: 1px solid #d9ecff; +} + + +#sponsor-container { + height: 300px; + overflow: auto; + overflow-x: hidden; +} +#sponsor-container::-webkit-scrollbar { + width: 5px; +} +#sponsor-container::-webkit-scrollbar-thumb { + border-radius: 10px; + background: #d0d1d2; + box-shadow: inset 0 0 5px #fff; +} +#sponsor-container::-webkit-scrollbar-track { + background: #fff; + border-radius: 10px; + box-shadow: inset 0 0 5px #fff; +} + +.url-container{ + padding: 10px 0 0; +} + +.url-item{ + margin: 10px; + text-decoration:none; +} + +.close{ + float: right; + cursor: pointer; +} + +.sponsor-tag-container{ + white-space: nowrap; +} \ No newline at end of file diff --git a/donors_widgets.php b/donors_widgets.php index 91d38f0..d0e7916 100644 --- a/donors_widgets.php +++ b/donors_widgets.php @@ -1,4 +1,86 @@ + + + + Document + + + + +
+ +
+ 项目主页 + 入群交流 + 常见问题 +
不再显示
+
+
+ + + + ETO; diff --git a/image/clsoe.svg b/image/clsoe.svg new file mode 100644 index 0000000..de309e8 --- /dev/null +++ b/image/clsoe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/image/enterprise.svg b/image/enterprise.svg new file mode 100644 index 0000000..6f35e39 --- /dev/null +++ b/image/enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/image/personage.svg b/image/personage.svg new file mode 100644 index 0000000..9e44667 --- /dev/null +++ b/image/personage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/image/school.svg b/image/school.svg new file mode 100644 index 0000000..966fc7e --- /dev/null +++ b/image/school.svg @@ -0,0 +1 @@ + \ No newline at end of file From 5184b51224c44f351b5d1bbc937b61f41840a6d7 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 10 Apr 2020 14:05:44 +0800 Subject: [PATCH 015/231] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=B8=8D=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E7=9A=84break?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- donors_widgets.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/donors_widgets.php b/donors_widgets.php index d0e7916..1e9a9fc 100644 --- a/donors_widgets.php +++ b/donors_widgets.php @@ -51,13 +51,10 @@ function getIcon(type) { switch (type) { case 1: return '{$plugin_url}image/enterprise.svg'; - break; case 2: return '{$plugin_url}image/personage.svg'; - break; case 3: return '{$plugin_url}image/school.svg'; - break; default: break; } From bd065d5949e0b8c6dd35a073b1d81ecbebff4427 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 10 Apr 2020 14:16:18 +0800 Subject: [PATCH 016/231] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=A3=8E=E6=A0=BC?= =?UTF-8?q?=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- donors_widgets.php | 41 ++++++++++++++--------------------------- image/clsoe.svg | 1 - 2 files changed, 14 insertions(+), 28 deletions(-) delete mode 100644 image/clsoe.svg diff --git a/donors_widgets.php b/donors_widgets.php index 1e9a9fc..4ad7538 100644 --- a/donors_widgets.php +++ b/donors_widgets.php @@ -7,27 +7,17 @@ */ $plugin_url = plugin_dir_url(__FILE__); echo << - - - - Document - + - - -
- -
- 项目主页 - 入群交流 - 常见问题 -
不再显示
-
-
- + +
+ 项目主页 + 入群交流 + 常见问题 +
不再显示
+
+ - - ETO; diff --git a/image/clsoe.svg b/image/clsoe.svg deleted file mode 100644 index de309e8..0000000 --- a/image/clsoe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 314e12636ba4eea59a443cac4fcdfb9c32b3e9d1 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 10 Apr 2020 14:20:24 +0800 Subject: [PATCH 017/231] =?UTF-8?q?=E5=B0=86css=E5=86=85=E7=BD=AE=E5=88=B0?= =?UTF-8?q?html=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/global.css | 84 ---------------------------------------------- donors_widgets.php | 4 ++- 2 files changed, 3 insertions(+), 85 deletions(-) delete mode 100644 css/global.css diff --git a/css/global.css b/css/global.css deleted file mode 100644 index e318bde..0000000 --- a/css/global.css +++ /dev/null @@ -1,84 +0,0 @@ -.sponsor-item-logo { - width: 70px; - height: 60px; -} - -.sponsor-item-container { - height: 70px; - display: flex; - min-width: 350px; - line-height: 24px; - margin-bottom: 10px; - border-bottom: 1px solid #eee; -} - -.sponsor-item-synopsis { - margin-left: 10px; -} - -.sponsor-item-title { - color: #000; - cursor: pointer; - text-decoration:none; -} - -.sponsor-item-title:hover{ - opacity: 0.5; -} -.sponsor-item-title-icon{ - width: 16px; - margin-right: 8px; -} - -.sponsor-item-content { - height: 24px; - padding: 0 10px; - line-height: 20px; - font-size: 12px; - margin: 3px 8px 0 0; - color: #409eff; - border-radius: 4px; - white-space: nowrap; - display: inline-block; - box-sizing: border-box; - background-color: #ecf5ff; - border: 1px solid #d9ecff; -} - - -#sponsor-container { - height: 300px; - overflow: auto; - overflow-x: hidden; -} -#sponsor-container::-webkit-scrollbar { - width: 5px; -} -#sponsor-container::-webkit-scrollbar-thumb { - border-radius: 10px; - background: #d0d1d2; - box-shadow: inset 0 0 5px #fff; -} -#sponsor-container::-webkit-scrollbar-track { - background: #fff; - border-radius: 10px; - box-shadow: inset 0 0 5px #fff; -} - -.url-container{ - padding: 10px 0 0; -} - -.url-item{ - margin: 10px; - text-decoration:none; -} - -.close{ - float: right; - cursor: pointer; -} - -.sponsor-tag-container{ - white-space: nowrap; -} \ No newline at end of file diff --git a/donors_widgets.php b/donors_widgets.php index 4ad7538..4593e9f 100644 --- a/donors_widgets.php +++ b/donors_widgets.php @@ -7,7 +7,9 @@ */ $plugin_url = plugin_dir_url(__FILE__); echo << +
From 2448693ee3c2a55e045db37037270afabfd540da Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 10 Apr 2020 14:22:37 +0800 Subject: [PATCH 018/231] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=B5=9E=E5=8A=A9?= =?UTF-8?q?=E5=95=86=E5=90=8D=E5=8D=95=E7=9A=84=E8=A1=8C=E9=AB=98=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- donors_widgets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/donors_widgets.php b/donors_widgets.php index 4593e9f..4f5eef6 100644 --- a/donors_widgets.php +++ b/donors_widgets.php @@ -8,7 +8,7 @@ $plugin_url = plugin_dir_url(__FILE__); echo << -.sponsor-item-logo{width:70px;height:60px;}.sponsor-item-container{height:70px;display:flex;min-width:350px;line-height:24px;margin-bottom:10px;border-bottom:1px solid #eee;}.sponsor-item-synopsis{margin-left:10px;}.sponsor-item-title{color:#000;cursor:pointer;text-decoration:none;}.sponsor-item-title:hover{opacity:0.5;}.sponsor-item-title-icon{width:16px;margin-right:8px;}.sponsor-item-content{height:24px;padding:0 10px;line-height:20px;font-size:12px;margin:3px 8px 0 0;color:#409eff;border-radius:4px;white-space:nowrap;display:inline-block;box-sizing:border-box;background-color:#ecf5ff;border:1px solid #d9ecff;}#sponsor-container{height:300px;overflow:auto;overflow-x:hidden;}#sponsor-container::-webkit-scrollbar{width:5px;}#sponsor-container::-webkit-scrollbar-thumb{border-radius:10px;background:#d0d1d2;box-shadow:inset 0 0 5px #fff;}#sponsor-container::-webkit-scrollbar-track{background:#fff;border-radius:10px;box-shadow:inset 0 0 5px #fff;}.url-container{padding:10px 0 0;}.url-item{margin:10px;text-decoration:none;}.close{float:right;cursor:pointer;}.sponsor-tag-container{white-space:nowrap;} +.sponsor-item-logo{width:70px;height:60px;}.sponsor-item-container{height:68px;display:flex;min-width:350px;line-height:24px;margin-bottom:10px;border-bottom:1px solid #eee;}.sponsor-item-synopsis{margin-left:10px;}.sponsor-item-title{color:#000;cursor:pointer;text-decoration:none;}.sponsor-item-title:hover{opacity:0.5;}.sponsor-item-title-icon{width:16px;margin-right:8px;}.sponsor-item-content{height:24px;padding:0 10px;line-height:20px;font-size:12px;margin:3px 8px 0 0;color:#409eff;border-radius:4px;white-space:nowrap;display:inline-block;box-sizing:border-box;background-color:#ecf5ff;border:1px solid #d9ecff;}#sponsor-container{height:300px;overflow:auto;overflow-x:hidden;}#sponsor-container::-webkit-scrollbar{width:5px;}#sponsor-container::-webkit-scrollbar-thumb{border-radius:10px;background:#d0d1d2;box-shadow:inset 0 0 5px #fff;}#sponsor-container::-webkit-scrollbar-track{background:#fff;border-radius:10px;box-shadow:inset 0 0 5px #fff;}.url-container{padding:10px 0 0;}.url-item{margin:10px;text-decoration:none;}.close{float:right;cursor:pointer;}.sponsor-tag-container{white-space:nowrap;} From d25c4d31294f0ce8901abfc515f924d99531f445 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 10 Apr 2020 14:59:34 +0800 Subject: [PATCH 019/231] =?UTF-8?q?=E5=8F=8D=E7=9C=9F=E5=BD=92=E7=92=9E?= =?UTF-8?q?=EF=BC=8C=E5=8F=88=E6=8A=8A=E8=AE=BE=E7=BD=AE=E9=A1=B5=E5=8A=A0?= =?UTF-8?q?=E5=9B=9E=E6=9D=A5=E4=BA=86=E2=80=A6=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 152 ++++++++++++++++++++++++++++++- settings.html | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 393 insertions(+), 3 deletions(-) create mode 100644 settings.html diff --git a/index.php b/index.php index 5d49bd4..ca15fea 100644 --- a/index.php +++ b/index.php @@ -9,11 +9,22 @@ * License URI: http://www.gnu.org/licenses/gpl-3.0.html */ +define('WP_CHINA_YES_PATH', __DIR__); +define('WP_CHINA_YES_BASE_FILE', __FILE__); + WP_CHINA_YES::init(); class WP_CHINA_YES { public static function init() { if (is_admin()) { + register_activation_hook(WP_CHINA_YES_BASE_FILE, array( + __CLASS__, + 'wp_china_yes_activate' + )); + register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array( + __CLASS__, + 'wp_china_yes_deactivate' + )); add_filter('pre_http_request', array( __CLASS__, 'pre_http_request' @@ -22,20 +33,55 @@ class WP_CHINA_YES { __CLASS__, 'plugin_row_meta' ), 10, 2); + add_filter('plugin_action_links', array( + __CLASS__, + 'action_links' + ), 10, 2); + add_action('admin_menu', array( + __CLASS__, + 'admin_menu' + )); + add_action('init', array( + __CLASS__, + 'set_cookie' + )); + add_action('wp_ajax_wpcy_get_config', array( + __CLASS__, + 'get_config' + )); + add_action('wp_ajax_wpcy_set_config', array( + __CLASS__, + 'set_config' + )); add_action('wp_dashboard_setup', array( __CLASS__, 'donors_widgets' )); + + if (empty(get_option('wp_china_yes_options'))) { + self::wp_china_yes_activate(); + } } } + public static function wp_china_yes_activate() { + self::set_wp_option(); + } + + public static function wp_china_yes_deactivate() { + delete_option('wp_china_yes_options'); + } + public static function pre_http_request($preempt, $r, $url) { if ( ! stristr($url, 'api.wordpress.org') && ! stristr($url, 'downloads.wordpress.org')) { return false; } - $url = str_replace('api.wordpress.org', 'api.w.org.ibadboy.net', $url); - $url = str_replace('downloads.wordpress.org', 'd.w.org.ibadboy.net', $url); + $options = get_option('wp_china_yes_options'); + $api_server = $options["custom_api_server"] ?: $options["api_server"]; + $download_server = $options["custom_download_server"] ?: $options["download_server"]; + $url = str_replace('api.wordpress.org', $api_server, $url); + $url = str_replace('downloads.wordpress.org', $download_server, $url); /** * 此处原本是复制了官方对外部请求处理的原始代码 @@ -45,7 +91,7 @@ class WP_CHINA_YES { } public static function plugin_row_meta($links, $file) { - $base = plugin_basename(__FILE__); + $base = plugin_basename(WP_CHINA_YES_BASE_FILE); if ($file == $base) { $links[] = '发布地址'; $links[] = 'GitHub'; @@ -54,9 +100,109 @@ class WP_CHINA_YES { return $links; } + public static function action_links($links, $file) { + if ($file != plugin_basename(WP_CHINA_YES_BASE_FILE)) { + return $links; + } + + $settings_link = '设置'; + + array_unshift($links, $settings_link); + + return $links; + } + + public static function admin_menu() { + add_options_page( + 'WP-China-Yes', + 'WP-China-Yes', + 'manage_options', + 'wp_china_yes', + array(__CLASS__, 'settings') + ); + } + + public static function settings() { + $setting_page_url = plugins_url('settings.html', __FILE__); + echo <<
+ +EOT; + } + + public static function set_cookie() { + if ( ! isset($_COOKIE['wp-china-yes']) && current_user_can('manage_options')) { + setcookie('wp-china-yes', json_encode([ + 'get_config' => wp_create_nonce('wpcy_get_config'), + 'set_config' => wp_create_nonce('wpcy_set_config') + ], JSON_UNESCAPED_UNICODE), time() + 1209600, COOKIEPATH, COOKIE_DOMAIN, false); + } + } + + public static function get_config() { + self::success('', get_option('wp_china_yes_options')); + } + + public static function set_config() { + if (( ! array_key_exists('api_server', $_POST) && ! array_key_exists('download_server', $_POST)) || + ( ! array_key_exists('community', $_POST) && ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) { + self::error('参数错误', - 1); + } + + self::set_wp_option( + sanitize_text_field(trim($_POST['community'])), + sanitize_text_field(trim($_POST['api_server'])), + sanitize_text_field(trim($_POST['download_server'])), + sanitize_text_field(trim($_POST['custom_api_server'])), + sanitize_text_field(trim($_POST['custom_download_server'])) + ); + + self::success(); + } + public static function donors_widgets() { wp_add_dashboard_widget('custom_help_widget', '《WordPress中国区仓库源建设计划》赞助者', function () { require_once plugin_dir_path(__FILE__) . 'donors_widgets.php'; }); } + + private static function success($message = '', $data = []) { + header('Content-Type:application/json; charset=utf-8'); + + echo json_encode([ + 'code' => 0, + 'message' => $message, + 'data' => $data + ], JSON_UNESCAPED_UNICODE); + exit; + } + + private static function error($message = '', $code = - 1) { + header('Content-Type:application/json; charset=utf-8'); + header('Status:500'); + + echo json_encode([ + 'code' => $code, + 'message' => $message + ], JSON_UNESCAPED_UNICODE); + exit; + } + + private static function set_wp_option( + $community = 0, + $api_server = 'api.w.org.ibadboy.net', + $download_server = 'd.w.org.ibadboy.net', + $custom_api_server = '', + $custom_download_server = '' + ) { + $options = array(); + $options['community'] = (int) $community; + $options['api_server'] = $api_server; + $options['download_server'] = $download_server; + $options['custom_api_server'] = $custom_api_server; + $options['custom_download_server'] = $custom_download_server; + update_option("wp_china_yes_options", $options); + } } \ No newline at end of file diff --git a/settings.html b/settings.html new file mode 100644 index 0000000..fd285a2 --- /dev/null +++ b/settings.html @@ -0,0 +1,244 @@ + + + + + WP-China-Yes设置页 + + + +
+ + +

WP-China-Yes

+ 这是一个颠覆性的插件,她将全面改善中国大陆站点在访问WP官方服务时的用户体验
+ 原理是将位于国外的官方仓库源替换为由社区志愿者维护的国内源,以此达到加速访问的目的 +
+ + + + + + + + +
+ 使用社区源 +
+ + + + + + + +
+ +
+ 自定义源 + 若配置自定义源则会覆盖社区源 + 搭建方法 + +
+ + + + + + + + + + +
+ + 保存配置 + + +
+
+
+
+ + + + +
+
+ + + 这是一个开源项目,她需要每个人的支持和贡献才能健康长久的发展。
+ 项目地址:GitHub +
+
+
+ + + + + + + \ No newline at end of file From 24e6a23fd121b1167b1a577c00c4856cfe8148d6 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 10 Apr 2020 15:07:28 +0800 Subject: [PATCH 020/231] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E9=A1=B5tab=EF=BC=8C=E5=B9=B6=E5=B0=86=E7=A4=BE=E5=8C=BA?= =?UTF-8?q?=E6=BA=90=E9=80=89=E6=8B=A9=E7=9A=84select=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E5=8F=AA=E6=9C=89=E4=B8=BB=E6=BA=90=E5=92=8C=E5=A4=87?= =?UTF-8?q?=E6=BA=90=E7=9A=84=E5=8D=95=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 25 +++++---- settings.html | 146 ++++++++++++++++++++------------------------------ 2 files changed, 73 insertions(+), 98 deletions(-) diff --git a/index.php b/index.php index ca15fea..969b737 100644 --- a/index.php +++ b/index.php @@ -77,9 +77,18 @@ class WP_CHINA_YES { return false; } - $options = get_option('wp_china_yes_options'); - $api_server = $options["custom_api_server"] ?: $options["api_server"]; - $download_server = $options["custom_download_server"] ?: $options["download_server"]; + $options = get_option('wp_china_yes_options'); + + if ($options["community"] == 1) { + $api_server = 'api.w.org.ixmu.net'; + $download_server = 'd.w.org.ixmu.net'; + } else { + $api_server = 'api.w.org.ibadboy.net'; + $download_server = 'd.w.org.ibadboy.net'; + } + + $api_server = $options["custom_api_server"] ?: $api_server; + $download_server = $options["custom_download_server"] ?: $download_server; $url = str_replace('api.wordpress.org', $api_server, $url); $url = str_replace('downloads.wordpress.org', $download_server, $url); @@ -146,15 +155,13 @@ EOT; } public static function set_config() { - if (( ! array_key_exists('api_server', $_POST) && ! array_key_exists('download_server', $_POST)) || - ( ! array_key_exists('community', $_POST) && ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) { + if ( ! array_key_exists('community', $_POST) || + ( ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) { self::error('参数错误', - 1); } self::set_wp_option( sanitize_text_field(trim($_POST['community'])), - sanitize_text_field(trim($_POST['api_server'])), - sanitize_text_field(trim($_POST['download_server'])), sanitize_text_field(trim($_POST['custom_api_server'])), sanitize_text_field(trim($_POST['custom_download_server'])) ); @@ -192,15 +199,11 @@ EOT; private static function set_wp_option( $community = 0, - $api_server = 'api.w.org.ibadboy.net', - $download_server = 'd.w.org.ibadboy.net', $custom_api_server = '', $custom_download_server = '' ) { $options = array(); $options['community'] = (int) $community; - $options['api_server'] = $api_server; - $options['download_server'] = $download_server; $options['custom_api_server'] = $custom_api_server; $options['custom_download_server'] = $custom_download_server; update_option("wp_china_yes_options", $options); diff --git a/settings.html b/settings.html index fd285a2..90df378 100644 --- a/settings.html +++ b/settings.html @@ -16,80 +16,65 @@ - - - - - - -
- 使用社区源 -
- - - - - - - -
- -
- 自定义源 - 若配置自定义源则会覆盖社区源 - 搭建方法 - -
- - - - - - - - - - -
- - 保存配置 - - -
-
-
-
- - - - -
+ + + + +
+ 使用社区仓库源 +
+ + + + 主源 + + + 备源 + + + +
+ +
+ 自定义源 + 若配置自定义源则会覆盖社区仓库源 + 搭建方法 + +
+ + + + + + + + + + +
+ + 保存配置 + + +
+
+
@@ -120,7 +105,6 @@ data() { return { external_api: {}, - server_desc: '', token: { get_config: '', set_config: '' @@ -129,19 +113,10 @@ community: '0', custom_api_server: '', custom_download_server: '', - api_server: '', - download_server: '', } } }, methods: { - changeServer() { - let server = this.external_api.server[this.mirrors_form.community]; - - this.server_desc = server.desc; - this.mirrors_form.api_server = server.api_server; - this.mirrors_form.download_server = server.download_server; - }, getConfig() { let vm = this; let data = new FormData(); @@ -154,7 +129,6 @@ axios.get('https://wp-china-yes.ibadboy.net') .then(function (response) { vm.external_api = response.data; - vm.changeServer(); }) .catch(function (error) { vm.$message({ @@ -191,8 +165,6 @@ data.append('community', vm.mirrors_form.community); data.append('custom_api_server', vm.mirrors_form.custom_api_server); data.append('custom_download_server', vm.mirrors_form.custom_download_server); - data.append('api_server', vm.mirrors_form.api_server); - data.append('download_server', vm.mirrors_form.download_server); axios.post(root_url + 'wp-admin/admin-ajax.php', data) .then(function (response) { From e224d5f625c5b83de66b52860f180197d621fc76 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Fri, 10 Apr 2020 15:22:45 +0800 Subject: [PATCH 021/231] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=ACtag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 4 ++-- readme.txt | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/index.php b/index.php index 969b737..f95f80f 100644 --- a/index.php +++ b/index.php @@ -3,7 +3,7 @@ * Plugin Name: WP-China-Yes * Description: 这是一个颠覆性的插件,她将全面改善中国大陆站点在访问WP官方服务时的用户体验,其原理是将位于国外的官方仓库源替换为由社区志愿者维护的国内源,以此达到加速访问的目的。 * Author: 孙锡源 - * Version: 2.0.0 + * Version: 2.1.0 * Author URI:https://www.ibadboy.net/ * License: GPLv3 or later * License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -132,7 +132,7 @@ class WP_CHINA_YES { } public static function settings() { - $setting_page_url = plugins_url('settings.html', __FILE__); + $setting_page_url = plugins_url('settings.html', __FILE__) . '?v=2.1.0'; echo << EOT; } From 9695a8e5cafd60560752f9f7cf3838ac3d3c431c Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 13:30:33 +0800 Subject: [PATCH 035/231] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=97=B6=E5=BC=B9=E5=87=BA=E7=9A=84=E2=80=9C?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=B8=AD=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.html | 7 ------- 1 file changed, 7 deletions(-) diff --git a/settings.html b/settings.html index 90df378..1fdbc15 100644 --- a/settings.html +++ b/settings.html @@ -152,13 +152,6 @@ cancelButtonText: '取消', type: 'warning' }).then(() => { - const loading = this.$loading({ - lock: true, - text: '提交中', - spinner: 'el-icon-loading', - background: 'rgba(0, 0, 0, 0.7)' - }); - let data = new FormData(); data.append('_ajax_nonce', this.token.set_config); data.append('action', 'wpcy_set_config'); From c447c21e4d32ffde77983a8b75b5f5c06d977888 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 13:31:16 +0800 Subject: [PATCH 036/231] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E5=A4=B4=E9=83=A8?= =?UTF-8?q?=E5=92=8C=E5=B0=BE=E9=83=A8=E6=96=87=E5=AD=97=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.html | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/settings.html b/settings.html index 1fdbc15..8b9a69c 100644 --- a/settings.html +++ b/settings.html @@ -9,13 +9,7 @@
- -

WP-China-Yes

- 这是一个颠覆性的插件,她将全面改善中国大陆站点在访问WP官方服务时的用户体验
- 原理是将位于国外的官方仓库源替换为由社区志愿者维护的国内源,以此达到加速访问的目的 -
- - - - 这是一个开源项目,她需要每个人的支持和贡献才能健康长久的发展。
- 项目地址:GitHub -
From c907b982cc4a79d6e9523afc53bf96e823641617 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 13:32:02 +0800 Subject: [PATCH 037/231] =?UTF-8?q?=E8=AE=BE=E7=BD=AEel-card=E7=9A=84?= =?UTF-8?q?=E9=AB=98=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.html b/settings.html index 8b9a69c..dc66866 100644 --- a/settings.html +++ b/settings.html @@ -15,7 +15,7 @@ - +
使用社区仓库源
@@ -34,7 +34,7 @@
- +
自定义源 若配置自定义源则会覆盖社区仓库源 From 15faeb5b2a8036a238c5a07c2d48519170b4df2f Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 13:32:41 +0800 Subject: [PATCH 038/231] =?UTF-8?q?=E4=BF=AE=E6=94=B9card=E6=A0=87?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.html b/settings.html index dc66866..64723a1 100644 --- a/settings.html +++ b/settings.html @@ -36,7 +36,7 @@
- 自定义源 + 自定义仓库源 若配置自定义源则会覆盖社区仓库源 Date: Mon, 27 Apr 2020 13:34:14 +0800 Subject: [PATCH 039/231] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E2=80=9C=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E5=8A=A0=E9=80=9F=E5=86=85=E5=AE=B9=E2=80=9Dcard?= =?UTF-8?q?=EF=BC=8C=E5=85=B6=E4=B8=AD=E5=8A=A0=E5=85=A5Gravatar=E5=A4=B4?= =?UTF-8?q?=E5=83=8F=E7=9A=84=E5=8A=A0=E9=80=9F=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/settings.html b/settings.html index 64723a1..40bf3db 100644 --- a/settings.html +++ b/settings.html @@ -58,6 +58,18 @@ + +
+ 其他加速内容 +
+ + 配置方法 + + +
From 349cd6df3b67a92f23a15ed155d0b6618702d204 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 14:15:24 +0800 Subject: [PATCH 040/231] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=B8=BB=E9=A1=B5=E5=92=8C=E5=8A=A0=E7=BE=A4=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E7=9A=84URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sponsor_widget.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sponsor_widget.php b/sponsor_widget.php index 052249c..644b385 100644 --- a/sponsor_widget.php +++ b/sponsor_widget.php @@ -14,9 +14,9 @@ echo <<
From 67a9e3da8c8ed166f01b04e3640973e5055a48d4 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 14:25:57 +0800 Subject: [PATCH 041/231] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9D=83?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sponsor_widget.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sponsor_widget.php b/sponsor_widget.php index 644b385..f87c494 100644 --- a/sponsor_widget.php +++ b/sponsor_widget.php @@ -2,8 +2,8 @@ /** * 仪表盘赞助商列表小部件 * - * @author Jialong - * @license http://www.gnu.org/licenses/gpl-3.0.html GPLv3 Licence + * @copyright Copyright (c) 2020 - WP-China-Yes(https://wp-china-yes.org) + * @license http://www.gnu.org/licenses/gpl-3.0.html GPLv3 License */ $plugin_url = plugin_dir_url(__FILE__); echo << Date: Mon, 27 Apr 2020 14:27:13 +0800 Subject: [PATCH 042/231] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9D=83?= =?UTF-8?q?=E5=A3=B0=E6=98=8E=E6=96=87=E4=BB=B6=E7=9A=84=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E4=B8=BA=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE => license | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE => license (100%) diff --git a/LICENSE b/license similarity index 100% rename from LICENSE rename to license From 37221f5da531a26f0ed5d2cd46f10455725650c7 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 14:30:35 +0800 Subject: [PATCH 043/231] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 45 +++++++++------------------------------------ 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/index.php b/index.php index 0d87b86..ac2fad9 100644 --- a/index.php +++ b/index.php @@ -16,10 +16,7 @@ WP_CHINA_YES::init(); class WP_CHINA_YES { public static function init() { - add_filter('pre_http_request', array( - __CLASS__, - 'pre_http_request' - ), 10, 3); + add_filter('pre_http_request', array(__CLASS__, 'pre_http_request'), 10, 3); $post_action = isset($_POST['action']) ? sanitize_text_field(trim($_POST['action'])) : ' '; if( defined( 'DOING_AJAX' ) && DOING_AJAX && !in_array($post_action,array('wpcy_set_config','wpcy_get_config'))){ return; @@ -28,38 +25,14 @@ class WP_CHINA_YES { if (empty(get_option('wp_china_yes_options'))) { self::set_wp_option(); } - register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array( - __CLASS__, - 'wp_china_yes_deactivate' - )); - add_filter('plugin_row_meta', array( - __CLASS__, - 'plugin_row_meta' - ), 10, 2); - add_filter('plugin_action_links', array( - __CLASS__, - 'action_links' - ), 10, 2); - add_action('admin_menu', array( - __CLASS__, - 'admin_menu' - )); - add_action('init', array( - __CLASS__, - 'set_cookie' - )); - add_action('wp_ajax_wpcy_get_config', array( - __CLASS__, - 'get_config' - )); - add_action('wp_ajax_wpcy_set_config', array( - __CLASS__, - 'set_config' - )); - add_action('wp_dashboard_setup', array( - __CLASS__, - 'sponsor_widget' - )); + register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array(__CLASS__, 'wp_china_yes_deactivate')); + add_filter('plugin_row_meta', array(__CLASS__, 'plugin_row_meta'), 10, 2); + add_filter('plugin_action_links', array(__CLASS__, 'action_links'), 10, 2); + add_action('admin_menu', array(__CLASS__, 'admin_menu')); + add_action('init', array(__CLASS__, 'set_cookie')); + add_action('wp_ajax_wpcy_get_config', array(__CLASS__, 'get_config')); + add_action('wp_ajax_wpcy_set_config', array(__CLASS__, 'set_config')); + add_action('wp_dashboard_setup', array(__CLASS__, 'sponsor_widget')); } } From 25ed8049c77befa43fdb07379d4c0285182b4771 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 14:44:00 +0800 Subject: [PATCH 044/231] =?UTF-8?q?=E5=B0=86=E6=89=80=E6=9C=89=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E6=94=B9=E4=B8=BA=E5=8A=A8=E6=80=81=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/index.php b/index.php index ac2fad9..f65b861 100644 --- a/index.php +++ b/index.php @@ -12,11 +12,11 @@ define('WP_CHINA_YES_PATH', __DIR__); define('WP_CHINA_YES_BASE_FILE', __FILE__); -WP_CHINA_YES::init(); +(new WP_CHINA_YES)->init(); class WP_CHINA_YES { - public static function init() { - add_filter('pre_http_request', array(__CLASS__, 'pre_http_request'), 10, 3); + public function init() { + add_filter('pre_http_request', array($this, 'pre_http_request'), 10, 3); $post_action = isset($_POST['action']) ? sanitize_text_field(trim($_POST['action'])) : ' '; if( defined( 'DOING_AJAX' ) && DOING_AJAX && !in_array($post_action,array('wpcy_set_config','wpcy_get_config'))){ return; @@ -25,22 +25,22 @@ class WP_CHINA_YES { if (empty(get_option('wp_china_yes_options'))) { self::set_wp_option(); } - register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array(__CLASS__, 'wp_china_yes_deactivate')); - add_filter('plugin_row_meta', array(__CLASS__, 'plugin_row_meta'), 10, 2); - add_filter('plugin_action_links', array(__CLASS__, 'action_links'), 10, 2); - add_action('admin_menu', array(__CLASS__, 'admin_menu')); - add_action('init', array(__CLASS__, 'set_cookie')); - add_action('wp_ajax_wpcy_get_config', array(__CLASS__, 'get_config')); - add_action('wp_ajax_wpcy_set_config', array(__CLASS__, 'set_config')); - add_action('wp_dashboard_setup', array(__CLASS__, 'sponsor_widget')); + register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array($this, 'wp_china_yes_deactivate')); + add_filter('plugin_row_meta', array($this, 'plugin_row_meta'), 10, 2); + add_filter('plugin_action_links', array($this, 'action_links'), 10, 2); + add_action('admin_menu', array($this, 'admin_menu')); + add_action('init', array($this, 'set_cookie')); + add_action('wp_ajax_wpcy_get_config', array($this, 'get_config')); + add_action('wp_ajax_wpcy_set_config', array($this, 'set_config')); + add_action('wp_dashboard_setup', array($this, 'sponsor_widget')); } } - public static function wp_china_yes_deactivate() { + public function wp_china_yes_deactivate() { delete_option('wp_china_yes_options'); } - public static function pre_http_request($preempt, $r, $url) { + public function pre_http_request($preempt, $r, $url) { if ( ! stristr($url, 'api.wordpress.org') && ! stristr($url, 'downloads.wordpress.org')) { return false; } @@ -67,7 +67,7 @@ class WP_CHINA_YES { return wp_remote_request($url, $r); } - public static function plugin_row_meta($links, $file) { + public function plugin_row_meta($links, $file) { $base = plugin_basename(WP_CHINA_YES_BASE_FILE); if ($file == $base) { $links[] = '发布地址'; @@ -77,7 +77,7 @@ class WP_CHINA_YES { return $links; } - public static function action_links($links, $file) { + public function action_links($links, $file) { if ($file != plugin_basename(WP_CHINA_YES_BASE_FILE)) { return $links; } @@ -89,17 +89,17 @@ class WP_CHINA_YES { return $links; } - public static function admin_menu() { + public function admin_menu() { add_options_page( 'WP-China-Yes', 'WP-China-Yes', 'manage_options', 'wp_china_yes', - array(__CLASS__, 'settings') + array($this, 'settings') ); } - public static function settings() { + public function settings() { $setting_page_url = plugins_url('settings.html', __FILE__) . '?v=2.2.0'; echo << wp_create_nonce('wpcy_get_config'), @@ -117,11 +117,11 @@ EOT; } } - public static function get_config() { + public function get_config() { self::success('', get_option('wp_china_yes_options')); } - public static function set_config() { + public function set_config() { if ( ! array_key_exists('community', $_POST) || ( ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) { self::error('参数错误', - 1); @@ -136,13 +136,13 @@ EOT; self::success(); } - public static function sponsor_widget() { + public function sponsor_widget() { wp_add_dashboard_widget('sponsor_widget', '《WordPress中国区仓库源建设计划》赞助商', function () { require_once plugin_dir_path(__FILE__) . 'sponsor_widget.php'; }); } - private static function success($message = '', $data = []) { + private function success($message = '', $data = []) { header('Content-Type:application/json; charset=utf-8'); echo json_encode([ @@ -153,7 +153,7 @@ EOT; exit; } - private static function error($message = '', $code = - 1) { + private function error($message = '', $code = - 1) { header('Content-Type:application/json; charset=utf-8'); header('Status:500'); @@ -164,7 +164,7 @@ EOT; exit; } - private static function set_wp_option( + private function set_wp_option( $community = 0, $custom_api_server = '', $custom_download_server = '' From e770bc631e9961b451bd9d2594395d047eaa40bd Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 14:55:56 +0800 Subject: [PATCH 045/231] update url --- index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index f65b861..3b08234 100644 --- a/index.php +++ b/index.php @@ -70,8 +70,8 @@ class WP_CHINA_YES { public function plugin_row_meta($links, $file) { $base = plugin_basename(WP_CHINA_YES_BASE_FILE); if ($file == $base) { - $links[] = '发布地址'; - $links[] = 'GitHub'; + $links[] = '项目主页'; + $links[] = 'GitHub'; } return $links; From 8db1fb3f6a50a95448c44ca1f2f73ce5ef8f83c5 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 14:56:40 +0800 Subject: [PATCH 046/231] =?UTF-8?q?=E9=83=A8=E5=88=86=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BA=E9=9D=99=E6=80=81=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.php b/index.php index 3b08234..6407821 100644 --- a/index.php +++ b/index.php @@ -142,7 +142,7 @@ EOT; }); } - private function success($message = '', $data = []) { + private static function success($message = '', $data = []) { header('Content-Type:application/json; charset=utf-8'); echo json_encode([ @@ -153,7 +153,7 @@ EOT; exit; } - private function error($message = '', $code = - 1) { + private static function error($message = '', $code = - 1) { header('Content-Type:application/json; charset=utf-8'); header('Status:500'); @@ -164,7 +164,7 @@ EOT; exit; } - private function set_wp_option( + private static function set_wp_option( $community = 0, $custom_api_server = '', $custom_download_server = '' From 9c836f9ea72219521e155ae3fd3db9d67138d76e Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 15:04:45 +0800 Subject: [PATCH 047/231] =?UTF-8?q?=E5=B0=86=E6=8F=92=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=BF=A1=E6=81=AF=E6=8F=90=E5=8F=96=E4=B8=BA=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/index.php b/index.php index 6407821..c58db5d 100644 --- a/index.php +++ b/index.php @@ -15,6 +15,8 @@ define('WP_CHINA_YES_BASE_FILE', __FILE__); (new WP_CHINA_YES)->init(); class WP_CHINA_YES { + private $wp_china_yes_options = array(); + public function init() { add_filter('pre_http_request', array($this, 'pre_http_request'), 10, 3); $post_action = isset($_POST['action']) ? sanitize_text_field(trim($_POST['action'])) : ' '; @@ -22,7 +24,8 @@ class WP_CHINA_YES { return; } if (is_admin()) { - if (empty(get_option('wp_china_yes_options'))) { + $this->wp_china_yes_options = get_option('wp_china_yes_options'); + if (empty($this->wp_china_yes_options)) { self::set_wp_option(); } register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array($this, 'wp_china_yes_deactivate')); @@ -45,9 +48,7 @@ class WP_CHINA_YES { return false; } - $options = get_option('wp_china_yes_options'); - - if ($options["community"] == 1) { + if ($this->wp_china_yes_options["community"] == 1) { $api_server = 'api.w.org.ixmu.net'; $download_server = 'd.w.org.ixmu.net'; } else { @@ -55,8 +56,8 @@ class WP_CHINA_YES { $download_server = 'd.w.org.ibadboy.net'; } - $api_server = $options["custom_api_server"] ?: $api_server; - $download_server = $options["custom_download_server"] ?: $download_server; + $api_server = $this->wp_china_yes_options["custom_api_server"] ?: $api_server; + $download_server = $this->wp_china_yes_options["custom_download_server"] ?: $download_server; $url = str_replace('api.wordpress.org', $api_server, $url); $url = str_replace('downloads.wordpress.org', $download_server, $url); @@ -118,7 +119,7 @@ EOT; } public function get_config() { - self::success('', get_option('wp_china_yes_options')); + self::success('', $this->wp_china_yes_options); } public function set_config() { From 556aa376a4b863c692ee678d3de42d4cf6b4fc6b Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 15:05:52 +0800 Subject: [PATCH 048/231] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/index.php b/index.php index c58db5d..5c5b401 100644 --- a/index.php +++ b/index.php @@ -82,9 +82,7 @@ class WP_CHINA_YES { if ($file != plugin_basename(WP_CHINA_YES_BASE_FILE)) { return $links; } - $settings_link = '设置'; - array_unshift($links, $settings_link); return $links; From b9cd587072082bbdea2084971d7c8b0384303192 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 15:13:53 +0800 Subject: [PATCH 049/231] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/index.php b/index.php index 5c5b401..e16f772 100644 --- a/index.php +++ b/index.php @@ -15,12 +15,12 @@ define('WP_CHINA_YES_BASE_FILE', __FILE__); (new WP_CHINA_YES)->init(); class WP_CHINA_YES { - private $wp_china_yes_options = array(); + private $wp_china_yes_options = []; public function init() { - add_filter('pre_http_request', array($this, 'pre_http_request'), 10, 3); + add_filter('pre_http_request', [$this, 'pre_http_request'], 10, 3); $post_action = isset($_POST['action']) ? sanitize_text_field(trim($_POST['action'])) : ' '; - if( defined( 'DOING_AJAX' ) && DOING_AJAX && !in_array($post_action,array('wpcy_set_config','wpcy_get_config'))){ + if( defined( 'DOING_AJAX' ) && DOING_AJAX && !in_array($post_action,['wpcy_set_config','wpcy_get_config'])){ return; } if (is_admin()) { @@ -28,14 +28,14 @@ class WP_CHINA_YES { if (empty($this->wp_china_yes_options)) { self::set_wp_option(); } - register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array($this, 'wp_china_yes_deactivate')); - add_filter('plugin_row_meta', array($this, 'plugin_row_meta'), 10, 2); - add_filter('plugin_action_links', array($this, 'action_links'), 10, 2); - add_action('admin_menu', array($this, 'admin_menu')); - add_action('init', array($this, 'set_cookie')); - add_action('wp_ajax_wpcy_get_config', array($this, 'get_config')); - add_action('wp_ajax_wpcy_set_config', array($this, 'set_config')); - add_action('wp_dashboard_setup', array($this, 'sponsor_widget')); + register_deactivation_hook(WP_CHINA_YES_BASE_FILE, [$this, 'wp_china_yes_deactivate']); + add_filter('plugin_row_meta', [$this, 'plugin_row_meta'], 10, 2); + add_filter('plugin_action_links', [$this, 'action_links'], 10, 2); + add_action('admin_menu', [$this, 'admin_menu']); + add_action('init', [$this, 'set_cookie']); + add_action('wp_ajax_wpcy_get_config', [$this, 'get_config']); + add_action('wp_ajax_wpcy_set_config', [$this, 'set_config']); + add_action('wp_dashboard_setup', [$this, 'sponsor_widget']); } } @@ -94,7 +94,7 @@ class WP_CHINA_YES { 'WP-China-Yes', 'manage_options', 'wp_china_yes', - array($this, 'settings') + [$this, 'settings'] ); } @@ -168,7 +168,7 @@ EOT; $custom_api_server = '', $custom_download_server = '' ) { - $options = array(); + $options = []; $options['community'] = (int) $community; $options['custom_api_server'] = $custom_api_server; $options['custom_download_server'] = $custom_download_server; From a156d0b162019ea68b094fd1ce02efd8557a8edf Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 15:18:52 +0800 Subject: [PATCH 050/231] =?UTF-8?q?=E4=BC=98=E5=8C=96set=5Fwp=5Foption?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.php b/index.php index e16f772..1db1bbb 100644 --- a/index.php +++ b/index.php @@ -168,10 +168,10 @@ EOT; $custom_api_server = '', $custom_download_server = '' ) { - $options = []; - $options['community'] = (int) $community; - $options['custom_api_server'] = $custom_api_server; - $options['custom_download_server'] = $custom_download_server; - update_option("wp_china_yes_options", $options); + update_option("wp_china_yes_options", [ + 'community' => (int) $community, + 'custom_api_server' => $custom_api_server, + 'custom_download_server' => $custom_download_server + ]); } } From 05d7eda53eb3f3d5059daed31a69959a54442d99 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 15:19:03 +0800 Subject: [PATCH 051/231] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 1db1bbb..ec88752 100644 --- a/index.php +++ b/index.php @@ -20,7 +20,7 @@ class WP_CHINA_YES { public function init() { add_filter('pre_http_request', [$this, 'pre_http_request'], 10, 3); $post_action = isset($_POST['action']) ? sanitize_text_field(trim($_POST['action'])) : ' '; - if( defined( 'DOING_AJAX' ) && DOING_AJAX && !in_array($post_action,['wpcy_set_config','wpcy_get_config'])){ + if (defined('DOING_AJAX') && DOING_AJAX && ! in_array($post_action, ['wpcy_set_config', 'wpcy_get_config'])) { return; } if (is_admin()) { From 3685cc97111a3115f42cb6f13a62cbc53520c650 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 15:39:15 +0800 Subject: [PATCH 052/231] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E5=A4=B4=E9=83=A8?= =?UTF-8?q?=E7=9A=84=E5=AE=8F=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/index.php b/index.php index ec88752..df6a256 100644 --- a/index.php +++ b/index.php @@ -9,9 +9,6 @@ * License URI: http://www.gnu.org/licenses/gpl-3.0.html */ -define('WP_CHINA_YES_PATH', __DIR__); -define('WP_CHINA_YES_BASE_FILE', __FILE__); - (new WP_CHINA_YES)->init(); class WP_CHINA_YES { @@ -28,7 +25,7 @@ class WP_CHINA_YES { if (empty($this->wp_china_yes_options)) { self::set_wp_option(); } - register_deactivation_hook(WP_CHINA_YES_BASE_FILE, [$this, 'wp_china_yes_deactivate']); + register_deactivation_hook(__FILE__, [$this, 'wp_china_yes_deactivate']); add_filter('plugin_row_meta', [$this, 'plugin_row_meta'], 10, 2); add_filter('plugin_action_links', [$this, 'action_links'], 10, 2); add_action('admin_menu', [$this, 'admin_menu']); @@ -69,7 +66,7 @@ class WP_CHINA_YES { } public function plugin_row_meta($links, $file) { - $base = plugin_basename(WP_CHINA_YES_BASE_FILE); + $base = plugin_basename(__FILE__); if ($file == $base) { $links[] = '项目主页'; $links[] = 'GitHub'; @@ -79,7 +76,7 @@ class WP_CHINA_YES { } public function action_links($links, $file) { - if ($file != plugin_basename(WP_CHINA_YES_BASE_FILE)) { + if ($file != plugin_basename(__FILE__)) { return $links; } $settings_link = '设置'; @@ -163,11 +160,7 @@ EOT; exit; } - private static function set_wp_option( - $community = 0, - $custom_api_server = '', - $custom_download_server = '' - ) { + private static function set_wp_option($community = 0, $custom_api_server = '', $custom_download_server = '') { update_option("wp_china_yes_options", [ 'community' => (int) $community, 'custom_api_server' => $custom_api_server, From 9b496ef3354b0eaeb9fc9fdd487a3965bd4d5b20 Mon Sep 17 00:00:00 2001 From: sunxiyuan Date: Mon, 27 Apr 2020 15:58:00 +0800 Subject: [PATCH 053/231] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/index.php b/index.php index df6a256..891da09 100644 --- a/index.php +++ b/index.php @@ -1,8 +1,8 @@ 项目主页'; - $links[] = 'GitHub'; + $links[] = '集成此插件到自己的产品中'; + $links[] = '参与项目发展'; + $links[] = 'GitHub'; } return $links; From 78425f77cc49c47811bd235586c8a30240d4be99 Mon Sep 17 00:00:00 2001 From: 3xs <31252669+my-3xs@users.noreply.github.com> Date: Fri, 1 May 2020 13:08:42 +0800 Subject: [PATCH 054/231] check_incompatible_notice --- index.php | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/index.php b/index.php index 891da09..735f6a1 100644 --- a/index.php +++ b/index.php @@ -8,7 +8,52 @@ * License: GPLv3 or later * License URI: http://www.gnu.org/licenses/gpl-3.0.html */ - +register_activation_hook( __FILE__, function() { + $check_incompatible = check_incompatible(); + if ( $check_incompatible ) { + set_transient( 'wp-china-yes-warning-notice', true, 5 ); + } +}); +add_action( 'admin_notices', function(){ + if( get_transient( 'wp-china-yes-warning-notice' ) ){ + echo check_incompatible()['error']; + delete_transient( 'wp-china-yes-warning-notice' ); + } +} ); +function check_incompatible(){ + $error = false; + $html = '

WP-CHINA-YES 启动提醒

'; + $html .= ''; + $incompatible_plugins = [ + 'wpjam-basic/wpjam-basic.php', + 'cardui-x/cardui-x.php', + 'nicetheme-jimu/nc-plugins.php', + ]; + if ( is_network_admin() ) { + $active_plugins = (array) get_site_option( 'active_sitewide_plugins', array() ); + $active_plugins = array_keys( $active_plugins ); + } else{ + $active_plugins = (array) get_option( 'active_plugins' ); + } + $matches = array_intersect( $active_plugins, $incompatible_plugins ); + if($matches){ + $error = true; + $html .= '

检测到您已启用下列提供类似功能的插件,请注意:您必须关闭这些插件中带有的wp代理更新、429错误解决等相关功能,以免系统更新被多次接管而产生错误。

    '; + foreach ( $matches as $matche ) { + $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $matche ); + $html.= '
  • '.$data["Name"].'
  • '; + } + } + $html .= '
'; + if($error) return ['error' => $html]; +} (new WP_CHINA_YES)->init(); class WP_CHINA_YES { From 445d9fe349d1ac680119220f3ae82deb43c4361c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= <45513686+haoziz@users.noreply.github.com> Date: Mon, 4 May 2020 10:48:01 +0800 Subject: [PATCH 055/231] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=AD=A4=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.html | 209 -------------------------------------------------- 1 file changed, 209 deletions(-) delete mode 100644 settings.html diff --git a/settings.html b/settings.html deleted file mode 100644 index 40bf3db..0000000 --- a/settings.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - WP-China-Yes设置页 - - - -
- - - - - - -
- 使用社区仓库源 -
- - - - 主源 - - - 备源 - - - -
- -
- 自定义仓库源 - 若配置自定义源则会覆盖社区仓库源 - 搭建方法 - -
- - - - - - - - - - -
- -
- 其他加速内容 -
- - 配置方法 - - -
- - 保存配置 - - -
-
-
-
-
-
- - - - - - - \ No newline at end of file From 726d8f87b352b8203dcd47a7aa45005b7fd8e7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= <45513686+haoziz@users.noreply.github.com> Date: Mon, 4 May 2020 11:02:20 +0800 Subject: [PATCH 056/231] =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.WordPress风格的设置页面 2.使用Nonce防止CSRF --- index.php | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 149 insertions(+), 5 deletions(-) diff --git a/index.php b/index.php index 735f6a1..1ff89ce 100644 --- a/index.php +++ b/index.php @@ -142,16 +142,158 @@ class WP_CHINA_YES { } public function settings() { - $setting_page_url = plugins_url('settings.html', __FILE__) . '?v=2.2.0'; echo << - +
+

WP-China-Yes

+ + +

这是一个开源项目,她需要每个人的支持和贡献才能健康长久的发展。
项目地址:GitHub

+
+ EOT; } public function set_cookie() { - if ( ! isset($_COOKIE['wp-china-yes']) && current_user_can('manage_options')) { + if (current_user_can('manage_options')) { setcookie('wp-china-yes', json_encode([ 'get_config' => wp_create_nonce('wpcy_get_config'), 'set_config' => wp_create_nonce('wpcy_set_config') @@ -160,10 +302,12 @@ EOT; } public function get_config() { + check_ajax_referer('wpcy_get_config'); self::success('', $this->wp_china_yes_options); } public function set_config() { + check_ajax_referer('wpcy_set_config'); if ( ! array_key_exists('community', $_POST) || ( ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) { self::error('参数错误', - 1); From 5bb6d09652a7ffa202e01f806f8644a4dfd77a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= <45513686+haoziz@users.noreply.github.com> Date: Mon, 4 May 2020 11:19:25 +0800 Subject: [PATCH 057/231] =?UTF-8?q?=E5=8A=A0=E5=85=A5Gravatar=E5=A4=B4?= =?UTF-8?q?=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index 1ff89ce..f4389e7 100644 --- a/index.php +++ b/index.php @@ -193,6 +193,25 @@ class WP_CHINA_YES { + + + + https://www.ibadboy.net/archives/3349.html + + + + + + + + + + + @@ -200,8 +219,8 @@ class WP_CHINA_YES {

-

这是一个开源项目,她需要每个人的支持和贡献才能健康长久的发展。
项目地址:GitHub

+

这是一个开源项目,她需要每个人的支持和贡献才能健康长久的发展。
+ 项目地址:GitHub

-EOT; - } - - public function set_cookie() { - if (current_user_can('manage_options')) { - setcookie('wp-china-yes', json_encode([ - 'get_config' => wp_create_nonce('wpcy_get_config'), - 'set_config' => wp_create_nonce('wpcy_set_config') - ], JSON_UNESCAPED_UNICODE), time() + 1209600, COOKIEPATH, COOKIE_DOMAIN, false); - } - } - - public function get_config() { - check_ajax_referer('wpcy_get_config'); - self::success('', $this->wp_china_yes_options); - } - - public function set_config() { - check_ajax_referer('wpcy_set_config'); - if ( ! array_key_exists('community', $_POST) || - ( ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) { - self::error('参数错误', - 1); - } - - self::set_wp_option( - sanitize_text_field(trim($_POST['community'])), - sanitize_text_field(trim($_POST['custom_api_server'])), - sanitize_text_field(trim($_POST['custom_download_server'])) - ); - - self::success(); - } - - public function sponsor_widget() { - wp_add_dashboard_widget('sponsor_widget', '《WordPress中国区仓库源建设计划》赞助商', function () { - require_once plugin_dir_path(__FILE__) . 'sponsor_widget.php'; - }); - } - - private static function success($message = '', $data = []) { - header('Content-Type:application/json; charset=utf-8'); - - echo json_encode([ - 'code' => 0, - 'message' => $message, - 'data' => $data - ], JSON_UNESCAPED_UNICODE); - exit; - } - - private static function error($message = '', $code = - 1) { - header('Content-Type:application/json; charset=utf-8'); - header('Status:500'); - - echo json_encode([ - 'code' => $code, - 'message' => $message - ], JSON_UNESCAPED_UNICODE); - exit; - } - - private static function set_wp_option($community = 0, $custom_api_server = '', $custom_download_server = '') { - update_option("wp_china_yes_options", [ - 'community' => (int) $community, - 'custom_api_server' => $custom_api_server, - 'custom_download_server' => $custom_download_server - ]); - } -} diff --git a/readme.md b/readme.md index c3c73d0..856817c 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1 @@ # WP-China-Yes - -## 介绍 - -因为WordPress官方的服务器都在国外,所以中国大陆的用户在访问由WordPress官方提供的服务(插件、主题商城,WP程序版本更新等)时总是很缓慢。 - -近期又因为被攻击的原因,WordPress的CDN提供商屏蔽了中国大陆的流量,导致大陆用户访问插件主题商城等服务时报429错误。 - -为解决上述问题,我在大陆境内架设了基于反向代理的缓存加速节点,用以加快WordPress官方服务在中国大陆的访问速度,并规避429报错问题。 - -此加速节点是直接为你的站点与WordPress总部服务器的一切通信做加速,加速范围包括但不限于:插件、主题商城的资源下载、作品图片、作者头像、主题预览等…… - -为使更多的使用WordPress的同学能够用上大陆加速节点,我开发了WP-China-Yes插件,以求帮助大家方便简洁的替换官方服务链接为大陆节点。 - -这个是一个公益项目,我始终都不会以任何借口对插件、加速节点的使用权等进行收费。 - -## 使用方法 - -下载并安装插件后直接启用即可,该插件会自动接管所有WP访问境外服务器的流量。 \ No newline at end of file diff --git a/sponsor_widget.php b/sponsor_widget.php deleted file mode 100644 index f87c494..0000000 --- a/sponsor_widget.php +++ /dev/null @@ -1,74 +0,0 @@ - -.sponsor-item-logo{width:70px;height:60px;}.sponsor-item-container{height:68px;display:flex;min-width:350px;line-height:24px;margin-bottom:10px;border-bottom:1px solid #eee;}.sponsor-item-synopsis{margin-left:10px;}.sponsor-item-title{color:#000;cursor:pointer;text-decoration:none;}.sponsor-item-title:hover{opacity:0.5;color: #181717;}.sponsor-item-title-icon{width:16px;margin-right:8px;}.sponsor-item-content{height:24px;padding:0 10px;line-height:20px;font-size:12px;margin:3px 8px 0 0;color:#409eff;border-radius:4px;white-space:nowrap;display:inline-block;box-sizing:border-box;background-color:#ecf5ff;border:1px solid #d9ecff;}#sponsor-container-item{width:100%}#sponsor-container{margin-right: -10px;height:300px;overflow:hidden;}.zUIpanelScrollBox,.zUIpanelScrollBar{width:6px;top:4px;right:2px;border-radius:5px;}.zUIpanelScrollBar{background:#DEDFDF;opacity:0.8;filter:alpha(opacity=80)}.url-container{padding:10px 0 0;}.url-item{margin:10px;text-decoration:none;}.close{float:right;cursor:pointer;}.sponsor-tag-container{white-space:nowrap;} - - - - -
- 项目主页 - 入群交流 - 常见问题 -
不再显示
-
- - -ETO; diff --git a/src/Common.php b/src/Common.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/src/Common.php @@ -0,0 +1 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..7a91153 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + $baseDir . '/src/Common.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($baseDir . '/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..7e84286 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,73 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit76cf9f9dfe928b65756ee64b09b9363d::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit76cf9f9dfe928b65756ee64b09b9363d::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire76cf9f9dfe928b65756ee64b09b9363d($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire76cf9f9dfe928b65756ee64b09b9363d($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 0000000..7bcd839 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,35 @@ + __DIR__ . '/../..' . '/src/Common.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'W' => + array ( + 'WPChina\\WPChinaYes\\' => 19, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'WPChina\\WPChinaYes\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit76cf9f9dfe928b65756ee64b09b9363d::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit76cf9f9dfe928b65756ee64b09b9363d::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1 @@ +[] diff --git a/vendor/loco-translate/CONTRIBUTING.md b/vendor/loco-translate/CONTRIBUTING.md new file mode 100644 index 0000000..ca4d5fe --- /dev/null +++ b/vendor/loco-translate/CONTRIBUTING.md @@ -0,0 +1,5 @@ +# This is a mirror + +Please don't submit pull requests. + +If you find any issues with this plugin, we'll greatly appreciate feedback posted in the [support forum](https://wordpress.org/support/plugin/loco-translate). diff --git a/vendor/loco-translate/README.md b/vendor/loco-translate/README.md new file mode 100644 index 0000000..0d49de8 --- /dev/null +++ b/vendor/loco-translate/README.md @@ -0,0 +1,37 @@ +# Loco WordPress Plugin + +### Translate plugins and themes directly in your browser + +Git mirror of the official Loco WordPress plugin: +[http://wordpress.org/plugins/loco-translate/](http://wordpress.org/plugins/loco-translate/) + +**Please don't submit pull requests** this is just a mirror of the SVN repository at: +[https://plugins.svn.wordpress.org/loco-translate/trunk/](https://plugins.svn.wordpress.org/loco-translate/trunk/) + +Please report issues in the WordPress plugin directory support forum: +[http://wordpress.org/support/plugin/loco-translate](http://wordpress.org/support/plugin/loco-translate) + + +## Installation + +Note that the actual name of the plugin is "loco-translate" not "wp-loco". It's renamed on Github to differentiate it as a WordPress plugin. + +Add the plugin to your WordPress project via Git as follows: + + $ git submodule add git@github.com:loco/wp-loco.git wp-content/plugins/loco-translate + +If you want to use a stable release listed in the WordPress plugin directory, you can checkout by tag, e.g: + + $ cd wp-content/plugins/loco-translate + $ git fetch origin --tags + $ git checkout tags/x.y.z + +Be sure to check out the latest version, replacing `x.y.z` in above example with the release number shown below. + +[![Latest Version](https://img.shields.io/github/release/loco/wp-loco.svg?style=flat-square)](https://github.com/loco/wp-loco/releases) + +## Contributing + +There is no issue tracker here. Please submit bugs or feature requests in the [WordPress support forum](http://wordpress.org/support/plugin/loco-translate). + +The Github repository is for people who want the latest development version of the plugin and prefer Git to [SVN](http://plugins.svn.wordpress.org/loco-translate/trunk/). This is not a collaborative project and there are no resources available for examining pull requests. diff --git a/vendor/loco-translate/languages/loco-translate.pot b/vendor/loco-translate/languages/loco-translate.pot new file mode 100644 index 0000000..c7d3388 --- /dev/null +++ b/vendor/loco-translate/languages/loco-translate.pot @@ -0,0 +1,2044 @@ +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Loco Translate 2.4.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-05-25 13:53+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: \n" +"Language: \n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Loco https://localise.biz/\n" +"X-Loco-Version: 2.4.0; wp-5.4.1" + +#: src/fs/FileWriter.php:214 +#, php-format +msgid "\"%s\" is a directory, not a file" +msgstr "" + +#: tpl/admin/bundle/alias.php:11 +msgid "\"Hello Dolly\" is part of the WordPress core" +msgstr "" + +#: src/api/WordPressFileSystem.php:87 +#, php-format +msgid "%s already exists in this folder" +msgstr "" + +#. characters meaning individual unicode characters of source text +#: src/js/Strings.php:47 +#, javascript-format +msgid "%s characters will be sent for translation." +msgstr "" + +#. Where %s is the type of file, e.g. "po" +#: tpl/admin/file/info.php:24 +#, php-format +msgid "%s file is writeable" +msgstr "" + +#. Shows number of fuzzy strings at top of editor +#: src/js/Strings.php:91 src/gettext/Metadata.php:205 +#, javascript-format +msgid "%s fuzzy" +msgstr "" + +#. Where %s is the size of a file +#: tpl/admin/init/init-pot.php:16 +#, php-format +msgid "%s on disk" +msgstr "" + +#. e.g. via Google Translate +#: src/js/Strings.php:58 +#, javascript-format +msgid "%s string translated via %s" +msgid_plural "%s strings translated via %s" +msgstr[0] "" +msgstr[1] "" + +#: src/js/Strings.php:61 +#, javascript-format +msgid "%s string updated" +msgid_plural "%s strings updated" +msgstr[0] "" +msgstr[1] "" + +#: src/js/Strings.php:43 +#, javascript-format +msgid "%s unique source strings." +msgstr "" + +#. Shows number of untranslated strings at top of editor +#: src/js/Strings.php:95 src/gettext/Metadata.php:208 +#, javascript-format +msgid "%s untranslated" +msgstr "" + +#. Shows percentage translated at top of editor +#: src/js/Strings.php:87 src/gettext/Metadata.php:203 +#, javascript-format +msgid "%s%% translated" +msgstr "" + +#. Summary of new strings after running in-editor Sync +#: src/js/Strings.php:25 +#, javascript-format +msgid "1 new string added" +msgid_plural "%s new strings added" +msgstr[0] "" +msgstr[1] "" + +#. Summary of existing strings that no longer exist after running in-editor Sync +#: src/js/Strings.php:29 +#, javascript-format +msgid "1 obsolete string removed" +msgid_plural "%s obsolete strings removed" +msgstr[0] "" +msgstr[1] "" + +#: src/admin/init/InitPoController.php:221 +#, php-format +msgid "1 source file will be scanned for translatable strings" +msgid_plural "%s source files will be scanned for translatable strings" +msgstr[0] "" +msgstr[1] "" + +#. Shows total string count at top of editor +#: src/js/Strings.php:83 src/gettext/Metadata.php:193 +#, javascript-format +msgid "1 string" +msgid_plural "%s strings" +msgstr[0] "" +msgstr[1] "" + +#. Summary of existing translations where the source text has changed slightly +#: src/js/Strings.php:33 +#, javascript-format +msgid "1 string marked Fuzzy" +msgid_plural "%s strings marked Fuzzy" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/file/info-pot.php:24 +#, php-format +msgid "1 word" +msgid_plural "%s words" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/config/settings.php:148 +msgid "About file system access" +msgstr "" + +#: tpl/admin/init/init-prompt.php:27 tpl/admin/init/init-pot.php:42 +msgid "About templates" +msgstr "" + +#: tpl/admin/errors/no-tokenizer.php:11 +msgid "About the Tokenizer" +msgstr "" + +#: tpl/admin/errors/file-sec.php:14 +msgid "Access to this file is blocked for security reasons" +msgstr "" + +#: tpl/admin/root.php:35 +msgid "Active theme:" +msgstr "" + +#: tpl/admin/file/edit-po.php:58 +msgid "Add automatic translation services in the plugin settings." +msgstr "" + +#: tpl/admin/bundle/conf.php:142 +msgid "Add set" +msgstr "" + +#: tpl/admin/config/settings.php:89 +msgid "Add UTF-8 byte order mark" +msgstr "" + +#: tpl/admin/bundle/view.php:29 +msgid "Additional files found" +msgstr "" + +#: src/hooks/AdminHooks.php:66 +#, php-format +msgid "" +"Administrators and auditors may wish to review Loco's plugin " +"privacy notice." +msgstr "" + +#: src/admin/bundle/BaseController.php:97 tpl/admin/file/move.php:26 +msgid "Advanced" +msgstr "" + +#: src/admin/bundle/ConfController.php:140 +#: tpl/admin/bundle/setup/inc-nav.php:19 tpl/admin/bundle/setup/core.php:17 +msgid "Advanced configuration" +msgstr "" + +#: src/admin/bundle/ConfController.php:55 +msgid "Advanced tab" +msgstr "" + +#: src/mvc/AjaxRouter.php:174 +msgid "Ajax controller returned empty JSON" +msgstr "" + +#: src/mvc/AjaxRouter.php:169 +#, php-format +msgid "Ajax route not found: \"%s\"" +msgstr "" + +#: src/admin/config/SettingsController.php:66 +msgid "Allow" +msgstr "" + +#: src/admin/config/SettingsController.php:67 +msgid "Allow (with warning)" +msgstr "" + +#: tpl/admin/config/settings.php:159 +msgid "Allow full access to these roles" +msgstr "" + +#: src/admin/config/ApisController.php:12 +#: src/admin/config/BaseController.php:20 +#: src/admin/config/BaseController.php:42 tpl/admin/help/tab-config-apis.php:2 +msgid "API keys" +msgstr "" + +#: tpl/admin/file/delete.php:16 +msgid "" +"Are you sure you want to permanently delete the following " +"file?" +msgstr "" + +#: src/admin/init/InitPoController.php:237 +msgid "Assign template" +msgstr "" + +#: tpl/admin/bundle/setup.php:12 +msgid "Author details" +msgstr "" + +#: tpl/admin/file/edit-po.php:16 +msgid "Auto-translate this file" +msgstr "" + +#: tpl/admin/init/init-po.php:67 +msgid "Available languages" +msgstr "" + +#: tpl/admin/errors/no-backups.php:16 +msgid "" +"Backup files will be written when you save translations from Loco Translate " +"editor" +msgstr "" + +#: tpl/admin/file/info-po.php:42 +msgid "Binary file missing" +msgstr "" + +#: tpl/admin/bundle/conf.php:128 +msgid "Blocked paths" +msgstr "" + +#: tpl/admin/bundle/setup/meta.php:11 tpl/admin/bundle/setup/core.php:10 +msgid "Bundle auto-configured" +msgstr "" + +#: tpl/admin/bundle/setup/saved.php:11 +msgid "Bundle configuration saved" +msgstr "" + +#: src/admin/bundle/DebugController.php:24 +msgid "Bundle diagnostics" +msgstr "" + +#: tpl/admin/bundle/locale.php:32 tpl/admin/list/inc-table.php:11 +msgid "Bundle name" +msgstr "" + +#: src/admin/bundle/SetupController.php:35 +msgid "Bundle setup" +msgstr "" + +#: src/ajax/FsConnectController.php:114 +msgid "" +"Changes to this file may be overwritten or deleted when you update WordPress" +msgstr "" + +#: tpl/admin/bundle/setup/conf.php:12 +msgid "Check config repository" +msgstr "" + +#: src/js/Strings.php:101 +msgid "Check console output for debugging information" +msgstr "" + +#: src/admin/bundle/ConfController.php:95 +msgid "Child theme declares the same Text Domain as the parent theme" +msgstr "" + +#: tpl/admin/init/init-po.php:48 +msgid "Choose a language" +msgstr "" + +#: tpl/admin/init/init-po.php:93 +msgid "Choose a location" +msgstr "" + +#: tpl/admin/file/move-po.php:14 +msgid "Choose a new location for these translations" +msgstr "" + +#: tpl/admin/common/inc-fsconn.php:56 +msgid "Click \"Connect\" to authenticate with the server" +msgstr "" + +#. %s is a URL. Keep the tag intact +#: tpl/admin/bundle/view.php:35 tpl/admin/bundle/view.php:57 +#, php-format +msgid "" +"Click the setup tab to complete the bundle configuration" +msgstr "" + +#: tpl/admin/file/info-mo.php:15 +msgid "compiled" +msgstr "" + +#: tpl/admin/file/info-mo.php:27 +msgid "Compiled translations" +msgstr "" + +#: tpl/admin/config/settings.php:18 tpl/admin/config/settings.php:22 +msgid "Compiling MO files" +msgstr "" + +#: src/admin/bundle/BaseController.php:53 +msgid "Configuration reset" +msgstr "" + +#: src/admin/bundle/BaseController.php:38 +msgid "Configuration saved" +msgstr "" + +#. where %s is a plugin or theme +#: src/admin/bundle/ConfController.php:16 +#, php-format +msgid "Configure %s" +msgstr "" + +#: src/package/Debugger.php:204 +#, php-format +msgid "Configured domain has no extractable strings" +msgid_plural "%u configured domains have no extractable strings" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/file/delete.php:12 +msgid "Confirm delete" +msgstr "" + +#: tpl/admin/file/move.php:14 +msgid "Confirm relocation" +msgstr "" + +#: tpl/admin/common/inc-fsconn.php:60 +msgid "Connect" +msgstr "" + +#: src/ajax/FsConnectController.php:101 +msgid "Connected to remote file system" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:57 tpl/admin/bundle/locale.php:72 +msgid "Copy" +msgstr "" + +#: tpl/admin/init/init-po.php:147 +#, php-format +msgid "Copy target translations from \"%s\"" +msgstr "" + +#. Page title for core WordPress translations +#: src/mvc/AdminRouter.php:56 +msgid "Core translations ‹ Loco" +msgstr "" + +#: src/admin/init/InitPoController.php:212 +#: src/admin/bundle/ViewController.php:127 tpl/admin/init/init-pot.php:40 +msgid "Create template" +msgstr "" + +#: tpl/admin/init/init-po.php:13 +msgid "Create template instead" +msgstr "" + +#: src/ajax/FsConnectController.php:124 +msgid "Creating this file requires permission" +msgstr "" + +#: tpl/admin/init/init-po.php:79 +msgid "Custom language" +msgstr "" + +#: src/error/Debug.php:19 src/admin/config/BaseController.php:24 +#: src/admin/config/DebugController.php:12 +#: src/admin/bundle/BaseController.php:100 +msgid "Debug" +msgstr "" + +#: src/admin/file/BaseController.php:110 tpl/admin/file/diff.php:31 +#: tpl/admin/bundle/inc-po-table.php:60 tpl/admin/bundle/locale.php:75 +msgid "Delete" +msgstr "" + +#: src/admin/file/DeleteController.php:76 +#: src/admin/file/DeleteController.php:94 +#, php-format +msgid "Delete %s" +msgstr "" + +#: src/ajax/FsConnectController.php:127 +msgid "Deleting this file requires permission" +msgstr "" + +#. Help tip for "Project name" field in advanced bundle config +#: tpl/admin/bundle/conf.php:35 +msgid "Descriptive name for this set of translatable strings" +msgstr "" + +#: tpl/admin/file/info.php:55 +msgid "Directory doesn't exist" +msgstr "" + +#: tpl/admin/file/info.php:69 +msgid "Directory is writeable" +msgstr "" + +#: src/admin/config/SettingsController.php:68 +msgid "Disallow" +msgstr "" + +#: src/data/Settings.php:186 src/admin/file/EditController.php:175 +#: src/admin/bundle/LocaleController.php:130 tpl/admin/config/settings.php:177 +#: tpl/admin/config/apis.php:100 tpl/admin/config/prefs.php:32 +#: tpl/admin/common/inc-fsconn.php:16 tpl/admin/common/inc-fsconn.php:41 +#: tpl/admin/errors/no-backups.php:22 +msgid "Documentation" +msgstr "" + +#: tpl/admin/bundle/conf.php:81 +msgid "Domain path" +msgstr "" + +#: src/mvc/AjaxRouter.php:197 +msgid "Download action not found" +msgstr "" + +#: src/mvc/AjaxRouter.php:202 +msgid "Download controller returned empty output" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:48 tpl/admin/bundle/locale.php:63 +msgid "Edit" +msgstr "" + +#: tpl/admin/bundle/setup/saved.php:19 +msgid "Edit config" +msgstr "" + +#: src/admin/bundle/ViewController.php:119 +msgid "Edit template" +msgstr "" + +#. %1$s is the file name, %2$s is the bundle name +#: src/admin/file/EditController.php:18 +#, php-format +msgid "Editing %1$s in %2$s" +msgstr "" + +#: tpl/admin/config/settings.php:138 +msgid "Editing of POT (template) files" +msgstr "" + +#: src/admin/file/BaseController.php:105 +msgid "Editor" +msgstr "" + +#. Where %s is the name of the language, e.g. "French translation" +#: src/js/Strings.php:127 +#, javascript-format +msgctxt "Editor" +msgid "%s translation" +msgstr "" + +#. button for adding a new string when manually editing a POT file +#: src/admin/file/EditController.php:199 +msgctxt "Editor" +msgid "Add" +msgstr "" + +#. Button that opens window for auto-translating +#: src/admin/file/EditController.php:210 +msgctxt "Editor" +msgid "Auto" +msgstr "" + +#. Label for the window pane for entering translator comments +#: src/js/Strings.php:133 +msgctxt "Editor" +msgid "Comments" +msgstr "" + +#. Label for the window pane holding message context +#: src/js/Strings.php:130 +msgctxt "Editor" +msgid "Context" +msgstr "" + +#. Label for the context window when no translation selected +#: src/js/Strings.php:157 +msgctxt "Editor" +msgid "Context not loaded" +msgstr "" + +#. Button for downloading a PO, MO or POT file +#: src/admin/file/EditController.php:212 +msgctxt "Editor" +msgid "Download" +msgstr "" + +#. Label for the plural form of the original English text +#: src/js/Strings.php:139 +msgctxt "Editor" +msgid "Plural" +msgstr "" + +#. button for removing a string when manually editing a POT file +#: src/admin/file/EditController.php:201 +msgctxt "Editor" +msgid "Remove" +msgstr "" + +#. Button that reloads current screen +#: src/admin/file/EditController.php:208 +msgctxt "Editor" +msgid "Revert" +msgstr "" + +#. Button that saves translations to disk +#: src/admin/file/EditController.php:204 +msgctxt "Editor" +msgid "Save" +msgstr "" + +#. Label for the singular form of the original English text +#: src/js/Strings.php:136 +msgctxt "Editor" +msgid "Single" +msgstr "" + +#. Label for the window pane holding the original English text +#. List heading showing preview of English text for each item +#: src/js/Strings.php:123 tpl/admin/file/info-pot.php:23 +msgctxt "Editor" +msgid "Source text" +msgstr "" + +#. Label for the source text window when no translation selected +#: src/js/Strings.php:154 +msgctxt "Editor" +msgid "Source text not loaded" +msgstr "" + +#: src/js/Strings.php:151 +msgctxt "Editor" +msgid "Suggest translation" +msgstr "" + +#. Button that runs in-editor sync/operation +#: src/admin/file/EditController.php:206 +msgctxt "Editor" +msgid "Sync" +msgstr "" + +#. Button that toggles between "code" and regular text editing modes +#: src/admin/file/EditController.php:218 +msgctxt "Editor" +msgid "Toggle code view" +msgstr "" + +#: src/js/Strings.php:148 +msgctxt "Editor" +msgid "Toggle Fuzzy" +msgstr "" + +#. Button that toggles invisible characters +#: src/admin/file/EditController.php:216 +msgctxt "Editor" +msgid "Toggle invisibles" +msgstr "" + +#: src/js/Strings.php:145 +msgctxt "Editor" +msgid "Translated" +msgstr "" + +#. List heading showing preview of translated text for each item +#: src/js/Strings.php:163 +msgctxt "Editor" +msgid "Translation" +msgstr "" + +#. Label for the translation editing window when no translation selected +#: src/js/Strings.php:160 +msgctxt "Editor" +msgid "Translation not loaded" +msgstr "" + +#: src/js/Strings.php:142 +msgctxt "Editor" +msgid "Untranslated" +msgstr "" + +#: tpl/admin/errors/file-missing.php:14 +msgid "" +"Either this file is missing or the server doesn't have permission to access " +"it" +msgstr "" + +#: tpl/admin/config/settings.php:95 +msgid "Enable Ajax file uploads" +msgstr "" + +#: tpl/admin/file/move-pot.php:14 +msgid "Enter a new location for this file" +msgstr "" + +#: src/js/Strings.php:110 src/error/Exception.php:149 +msgid "Error" +msgstr "" + +#: tpl/admin/bundle/conf.php:89 tpl/admin/bundle/conf.php:108 +msgid "Exclude" +msgstr "" + +#. Where %2$s is the size of a file +#: tpl/admin/init/init-pot.php:24 +#, php-format +msgid "Excludes one file over %2$s" +msgid_plural "Excludes %s files over %2$s" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/config/settings.php:40 tpl/admin/config/settings.php:44 +msgid "Extracting strings" +msgstr "" + +#: src/fs/FileWriter.php:288 +msgid "Failed to build directory path" +msgstr "" + +#: src/fs/FileWriter.php:132 +#, php-format +msgid "Failed to chmod %s" +msgstr "" + +#: src/fs/FileWriter.php:52 +msgid "Failed to connect to remote server" +msgstr "" + +#: src/fs/FileWriter.php:160 +#, php-format +msgid "Failed to copy %s to %s" +msgstr "" + +#: src/ajax/SaveController.php:72 +#, php-format +msgid "" +"Failed to create backup file in \"%s\". Check file permissions or disable " +"backups" +msgstr "" + +#: src/fs/FileWriter.php:280 +msgid "Failed to create directory" +msgstr "" + +#: src/fs/FileWriter.php:198 +#, php-format +msgid "Failed to delete %s" +msgstr "" + +#: src/fs/FileWriter.php:249 +msgid "Failed to save file" +msgstr "" + +#: tpl/admin/errors/file-sec.php:11 +msgid "File access disallowed" +msgstr "" + +#: tpl/admin/errors/no-backups.php:18 +msgid "File backups are disabled in your plugin settings" +msgstr "" + +#: src/admin/file/DeleteController.php:57 src/admin/file/DiffController.php:61 +#, php-format +msgid "File deleted" +msgid_plural "%u files deleted" +msgstr[0] "" +msgstr[1] "" + +#: src/admin/file/InfoController.php:158 +msgid "File does not have a valid header" +msgstr "" + +#: tpl/admin/file/info.php:14 +msgid "File doesn't exist" +msgstr "" + +#: src/admin/file/BaseController.php:107 tpl/admin/bundle/inc-po-table.php:22 +#: tpl/admin/bundle/locale.php:43 +msgid "File info" +msgstr "" + +#: tpl/admin/errors/file-isdir.php:11 +msgid "File is a directory" +msgstr "" + +#: tpl/admin/file/view-mo.php:11 +msgid "File is in binary MO format" +msgstr "" + +#: tpl/admin/common/inc-fsconn.php:28 +msgid "File is protected by the bundle configuration" +msgstr "" + +#. Refers to bundled plugin or theme translation files - i.e. those supplied by the author +#: src/fs/LocaleDirectory.php:63 +msgctxt "File location" +msgid "Author" +msgstr "" + +#. Refers to translation files in Loco's custom/protected directory +#: src/fs/LocaleDirectory.php:69 +msgctxt "File location" +msgid "Custom" +msgstr "" + +#. Refers to translation files in an alternative location that isn't Author, System or Custom. +#: src/fs/LocaleDirectory.php:72 +msgctxt "File location" +msgid "Other" +msgstr "" + +#. Refers to system-installed translation files - i.e. those under WP_LANG_DIR +#: src/fs/LocaleDirectory.php:66 +msgctxt "File location" +msgid "System" +msgstr "" + +#: src/fs/FileWriter.php:299 +msgid "File modification is disallowed by your WordPress config" +msgstr "" + +#: tpl/admin/file/info-mo.php:21 tpl/admin/file/info-pot.php:17 +#: tpl/admin/file/info-po.php:22 +msgid "File modified" +msgstr "" + +#: src/admin/file/MoveController.php:79 +#, php-format +msgid "File moved" +msgid_plural "%u files moved" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/errors/file-missing.php:11 +msgid "File not found" +msgstr "" + +#: tpl/admin/bundle/conf.php:53 +msgid "File prefix" +msgstr "" + +#: src/admin/file/DiffController.php:50 +msgid "File restored" +msgstr "" + +#: tpl/admin/file/info-mo.php:18 tpl/admin/file/info-pot.php:14 +#: tpl/admin/file/info-po.php:19 +msgid "File size" +msgstr "" + +#: tpl/admin/config/settings.php:115 tpl/admin/config/settings.php:119 +msgid "File system access" +msgstr "" + +#. Help tip for "Source file paths" field in advanced bundle config +#: tpl/admin/bundle/conf.php:113 +msgid "Files and folders within the bundle that contain localized PHP code" +msgstr "" + +#: tpl/admin/list/locales.php:22 +msgid "Files found" +msgstr "" + +#: tpl/admin/file/info.php:110 +msgid "" +"Files in this location can be modified or deleted by WordPress automatic " +"updates" +msgstr "" + +#. Placeholder text for text filter above editor +#: src/admin/file/EditController.php:214 +msgid "Filter translations" +msgstr "" + +#. text field placeholder +#: tpl/admin/common/inc-table-filter.php:6 +msgid "Filter..." +msgstr "" + +#: tpl/admin/bundle/setup/conf.php:27 +msgid "Find config" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:28 tpl/admin/bundle/locale.php:49 +msgid "Folder" +msgstr "" + +#. Help tip for "Domain path" field in advanced bundle config +#: tpl/admin/bundle/conf.php:94 +msgid "Folders within the bundle that contain author-supplied translations" +msgstr "" + +#. Help tip for "Blocked paths" field in advanced bundle config +#: tpl/admin/bundle/conf.php:134 +msgid "Folders within the bundle that will never be searched for files" +msgstr "" + +#: tpl/admin/help/tab-config.php:9 tpl/admin/help/tab-config-apis.php:9 +msgid "Full documentation" +msgstr "" + +#: tpl/admin/config/settings.php:27 +msgid "Generate hash tables" +msgstr "" + +#: tpl/admin/bundle/setup/inc-nav.php:25 +msgid "Get help with this" +msgstr "" + +#: tpl/admin/help/tab-support.php:6 +msgid "Getting help with Loco Translate" +msgstr "" + +#: tpl/admin/bundle/alias.php:17 +msgid "Go to WordPress Core" +msgstr "" + +#: tpl/admin/config/settings.php:155 +msgid "Grant access to roles" +msgstr "" + +#: src/admin/file/EditController.php:202 tpl/admin/file/edit-po.php:45 +#: tpl/admin/file/edit-po.php:65 +msgid "Help" +msgstr "" + +#: src/mvc/AdminController.php:53 +msgid "Help & support" +msgstr "" + +#: tpl/admin/help/side-bar.php:12 +msgid "Help and tutorials" +msgstr "" + +#: src/mvc/AdminRouter.php:42 +msgid "Home" +msgstr "" + +#. Author URI of the plugin +msgid "https://localise.biz/wordpress/plugin" +msgstr "" + +#. URI of the plugin +msgid "https://wordpress.org/plugins/loco-translate/" +msgstr "" + +#: tpl/admin/bundle/setup.php:15 +msgid "" +"If you have trouble translating this bundle, consider asking the author for " +"help" +msgstr "" + +#: tpl/admin/bundle/setup/conf.php:49 +msgid "" +"If you've been given a configuration file by a developer, paste the XML code " +"here" +msgstr "" + +#: tpl/admin/bundle/setup/inc-nav.php:22 +msgid "Import config from XML" +msgstr "" + +#: tpl/admin/config/apis.php:90 +msgid "Important" +msgstr "" + +#: tpl/admin/file/info-po.php:55 +msgid "In sync with template" +msgstr "" + +#: tpl/admin/bundle/conf.php:85 tpl/admin/bundle/conf.php:104 +msgid "Include" +msgstr "" + +#: tpl/admin/config/settings.php:33 +msgid "Include Fuzzy strings" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:54 tpl/admin/bundle/locale.php:69 +msgid "Info" +msgstr "" + +#: src/admin/init/InitPoController.php:104 +#, php-format +msgid "Initializing new translations in \"%s\"" +msgstr "" + +#: src/admin/init/InitPoController.php:108 +msgid "Initializing new translations in unknown set" +msgstr "" + +#: src/admin/bundle/LocaleController.php:116 +#: src/admin/list/LocalesController.php:35 tpl/admin/init/init-po.php:61 +msgid "Installed languages" +msgstr "" + +#: src/Locale.php:304 +msgid "Invalid locale" +msgstr "" + +#: tpl/admin/bundle/setup/none.php:15 +msgid "It needs configuring before you can do any translations" +msgstr "" + +#: tpl/admin/init/init-po.php:153 +msgid "Just copy English source strings" +msgstr "" + +#. relative time when something happened in the last 30 seconds +#: src/mvc/FileParams.php:145 +msgid "Just now" +msgstr "" + +#: src/js/Strings.php:76 +msgid "Keep this translation" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:13 +msgid "Language" +msgstr "" + +#: src/admin/file/InfoController.php:165 +#, php-format +msgid "Language header is \"%s\" but file name contains \"%s\"" +msgstr "" + +#: src/mvc/AdminRouter.php:59 +msgid "Languages" +msgstr "" + +#. Page title for installed languages page +#: src/mvc/AdminRouter.php:61 +msgid "Languages ‹ Loco" +msgstr "" + +#. Where %s is the size of a file +#: tpl/admin/init/init-pot.php:18 +#, php-format +msgid "largest is %s" +msgstr "" + +#: tpl/admin/file/info-pot.php:20 +msgid "Last extracted" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:25 tpl/admin/bundle/locale.php:46 +#: tpl/admin/list/locales.php:19 tpl/admin/list/inc-table.php:17 +msgid "Last modified" +msgstr "" + +#: tpl/admin/file/info-mo.php:24 tpl/admin/file/info-po.php:25 +msgid "Last translation" +msgstr "" + +#: tpl/admin/bundle/setup/conf.php:55 +msgid "Load config" +msgstr "" + +#: src/js/Strings.php:73 +msgid "Loading suggestions" +msgstr "" + +#: tpl/admin/list/locales.php:16 +msgid "Locale code" +msgstr "" + +#: tpl/admin/list/locales.php:13 +msgid "Locale name" +msgstr "" + +#: tpl/admin/bundle/conf.php:71 tpl/admin/common/inc-fsconn.php:12 +msgid "Locked" +msgstr "" + +#: src/output/Buffer.php:129 +#, php-format +msgid "Loco interrupted by output from %s:%u" +msgstr "" + +#: loco.php:129 +#, php-format +msgid "" +"Loco requires the \"%s\" PHP extension. Ask your hosting provider to install " +"it" +msgstr "" + +#. change "en" in the URL to your language if it's available at http://php.net/docs.php +#: tpl/admin/errors/no-tokenizer.php:17 +msgid "" +"Loco requires the Tokenizer extension to scan PHP source code for " +"translatable strings" +msgstr "" + +#. Name of the plugin +#: src/mvc/AdminRouter.php:37 src/hooks/AdminHooks.php:63 +msgid "Loco Translate" +msgstr "" + +#. home screen title where %s is the version number +#: src/admin/RootController.php:23 +#, php-format +msgid "Loco Translate %s" +msgstr "" + +#: src/data/Settings.php:184 +msgid "" +"Loco Translate 2.4 supports third party translation providers. Set up your " +"API keys in the plugin settings!" +msgstr "" + +#: src/mvc/AdminController.php:116 +msgid "Loco Translate is powered by" +msgstr "" + +#. Page title for plugin home screen +#: src/mvc/AdminRouter.php:39 +msgid "Loco, Translation Management" +msgstr "" + +#: tpl/admin/file/edit-po.php:34 +msgid "Mark new translations as Fuzzy" +msgstr "" + +#: tpl/admin/config/settings.php:82 +msgid "Maximum line length (zero disables wrapping)" +msgstr "" + +#. Where %s is the name of the POT template file. Message appears after sync +#: src/js/Strings.php:18 +#, javascript-format +msgid "Merged from %s" +msgstr "" + +#. Message appears after sync operation +#: src/js/Strings.php:21 +msgid "Merged from source code" +msgstr "" + +#: tpl/admin/file/info-po.php:79 +msgid "Missing template" +msgstr "" + +#: src/ajax/MsginitController.php:60 +msgid "MO file exists for this language already. Delete it first" +msgstr "" + +#. @var Loco_mvc_ViewParams $verbose +#: tpl/admin/config/settings.php:130 +msgid "Modification of installed files" +msgstr "" + +#: src/fs/FileWriter.php:304 +msgid "Modification of installed files is disallowed by the plugin settings" +msgstr "" + +#: src/fs/FileWriter.php:309 +msgid "" +"Modification of POT (template) files is disallowed by the plugin settings" +msgstr "" + +#: tpl/admin/file/view-pot.php:11 tpl/admin/file/edit-pot.php:12 +#: tpl/admin/bundle/locale.php:14 tpl/admin/common/inc-po-header.php:8 +msgctxt "Modified time" +msgid "Updated" +msgstr "" + +#: src/admin/file/MoveController.php:100 src/admin/file/MoveController.php:127 +#, php-format +msgid "Move %s" +msgstr "" + +#: tpl/admin/file/move.php:24 +msgid "Move files" +msgstr "" + +#: src/admin/init/InitPoController.php:16 +#: src/admin/init/InitPoController.php:111 +#: src/admin/file/BaseController.php:129 src/admin/bundle/ViewController.php:96 +msgid "New language" +msgstr "" + +#: src/admin/init/InitPotController.php:16 +msgid "New template" +msgstr "" + +#: src/admin/init/InitPotController.php:116 +msgid "New template file" +msgstr "" + +#: src/admin/init/InitPotController.php:117 +#, php-format +msgid "New translations template for \"%s\"" +msgstr "" + +#: src/admin/bundle/LocaleController.php:129 +msgid "No core translation files are installed for this language" +msgstr "" + +#: tpl/admin/errors/no-locale.php:11 +msgid "No files found for this language" +msgstr "" + +#: tpl/admin/init/init-po.php:60 +msgid "No language selected" +msgstr "" + +#: tpl/admin/errors/no-backups.php:12 +msgid "No previous file revisions" +msgstr "" + +#: tpl/admin/file/edit-po.php:56 +msgid "No translation APIs configured" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:105 +#, php-format +msgid "No translations found for \"%s\"" +msgstr "" + +#: tpl/admin/bundle/conf.php:94 tpl/admin/bundle/conf.php:113 +#: tpl/admin/bundle/conf.php:134 +msgid "no wildcards" +msgstr "" + +#: tpl/admin/config/settings.php:89 tpl/admin/config/settings.php:125 +msgid "Not recommended" +msgstr "" + +#: tpl/admin/file/info.php:81 +msgid "" +"Note that the file may not be deletable due to additional ownership " +"permissions" +msgstr "" + +#. When text filtering reduces to an empty view +#: src/js/Strings.php:14 +msgid "Nothing matches the text filter" +msgstr "" + +#: src/js/Strings.php:64 +msgid "Nothing needed updating" +msgstr "" + +#: src/js/Strings.php:116 src/error/Notice.php:20 +#: tpl/admin/common/inc-fsconn.php:37 +msgid "Notice" +msgstr "" + +#: tpl/admin/config/settings.php:76 +msgid "Number of backups to keep of each file:" +msgstr "" + +#: tpl/admin/bundle/setup/author.php:11 +msgid "Official configuration" +msgstr "" + +#: tpl/admin/help/side-bar.php:9 +msgid "Official plugin page" +msgstr "" + +#: src/js/Strings.php:119 src/error/Success.php:19 +msgid "OK" +msgstr "" + +#: tpl/admin/bundle/setup/conf.php:34 +msgid "OK, Load this config" +msgstr "" + +#: src/admin/file/DeleteController.php:99 +#, php-format +msgid "One dependent file will also be deleted" +msgid_plural "%u dependent files will also be deleted" +msgstr[0] "" +msgstr[1] "" + +#: src/admin/bundle/SetupController.php:114 +#, php-format +msgid "One file can't be matched to a known set of strings" +msgid_plural "%s files can't be matched to a known set of strings" +msgstr[0] "" +msgstr[1] "" + +#: src/admin/file/MoveController.php:83 +#, php-format +msgid "One file could not be moved" +msgid_plural "%u files could not be moved" +msgstr[0] "" +msgstr[1] "" + +#. Where %2$s is the maximum size of a file that will be included and %3$s is the largest encountered +#: src/ajax/SyncController.php:62 +#, php-format +msgid "" +"One file has been skipped because it's %3$s. (Max is %2$s). Check all " +"strings are present before saving." +msgid_plural "" +"%s files over %2$s have been skipped. (Largest is %3$s). Check all strings " +"are present before saving." +msgstr[0] "" +msgstr[1] "" + +#: src/package/Debugger.php:186 +#, php-format +msgid "One string extracted from source code for \"%2$s\"" +msgid_plural "%s strings extracted from source code for \"%s\"" +msgstr[0] "" +msgstr[1] "" + +#: src/admin/init/InitPoController.php:193 +#, php-format +msgid "One string found in %2$s" +msgid_plural "%s strings found in %s" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/file/info-po.php:66 +msgid "Out of sync with template" +msgstr "" + +#: src/admin/bundle/BaseController.php:95 +msgid "Overview" +msgstr "" + +#: tpl/admin/file/edit-po.php:28 +msgid "Overwrite existing translations" +msgstr "" + +#: src/mvc/AdminRouter.php:237 +msgid "Page not found" +msgstr "" + +#: src/fs/FileWriter.php:245 +msgid "Parent directory isn't writable" +msgstr "" + +#: tpl/admin/bundle/conf.php:144 +msgid "Parent theme" +msgstr "" + +#: tpl/admin/bundle/setup/partial.php:11 +msgid "Partially configured bundle" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:19 tpl/admin/bundle/locale.php:39 +msgid "Pending" +msgstr "" + +#: src/error/WriteException.php:13 +msgid "Permission denied" +msgstr "" + +#: src/fs/FileWriter.php:239 +msgid "Permission denied to update file" +msgstr "" + +#: src/package/Plugin.php:208 +#, php-format +msgid "Plugin not found: %s" +msgstr "" + +#: src/mvc/AdminRouter.php:66 src/admin/config/ApisController.php:59 +#: src/admin/config/PrefsController.php:42 +#: src/admin/config/VersionController.php:22 +#: src/admin/config/SettingsController.php:79 tpl/admin/help/tab-config.php:2 +msgid "Plugin settings" +msgstr "" + +#. Page title for plugin translations +#: src/mvc/AdminRouter.php:51 +msgid "Plugin translations ‹ Loco" +msgstr "" + +#: src/mvc/AdminRouter.php:49 src/admin/Navigation.php:44 +#: src/admin/bundle/LocaleController.php:146 +msgid "Plugins" +msgstr "" + +#. Plural category for languages that have no plurals +#: src/Locale.php:383 +msgctxt "Plural category" +msgid "All forms" +msgstr "" + +#. Plural category used in some multi-plural languages +#: src/Locale.php:397 +msgctxt "Plural category" +msgid "Few" +msgstr "" + +#. Plural category used in some multi-plural languages +#: src/Locale.php:399 +msgctxt "Plural category" +msgid "Many" +msgstr "" + +#. Plural category for singular quantity +#: src/Locale.php:393 +msgctxt "Plural category" +msgid "One" +msgstr "" + +#. General plural category not covered by other forms +#: src/Locale.php:401 +msgctxt "Plural category" +msgid "Other" +msgstr "" + +#. Plural category used in some multi-plural languages +#: src/Locale.php:395 +msgctxt "Plural category" +msgid "Two" +msgstr "" + +#. Plural category for zero quantity +#: src/Locale.php:391 +msgctxt "Plural category" +msgid "Zero" +msgstr "" + +#. Where %s is the name of a template file +#: tpl/admin/file/info-po.php:70 +#, php-format +msgid "" +"PO file has different source strings to \"%s\". Try running Sync before " +"making any changes." +msgstr "" + +#. Where %s is the name of a template file +#: tpl/admin/file/info-po.php:59 +#, php-format +msgid "PO file has the same source strings as \"%s\"" +msgstr "" + +#: tpl/admin/file/info-mo.php:38 +msgid "PO file missing" +msgstr "" + +#: src/ajax/SaveController.php:106 +msgid "PO file saved and MO file compiled" +msgstr "" + +#: src/ajax/SaveController.php:111 +msgid "PO file saved, but MO file compilation failed" +msgstr "" + +#: src/ajax/SaveController.php:118 +msgid "POT file saved" +msgstr "" + +#: tpl/admin/config/settings.php:102 +msgid "POT template files" +msgstr "" + +#: tpl/admin/bundle/conf.php:29 +msgid "Project name" +msgstr "" + +#: src/js/Strings.php:104 +msgid "Provide the following text when reporting a problem" +msgstr "" + +#: tpl/admin/common/inc-fsconn.php:27 +msgid "Read only" +msgstr "" + +#: tpl/admin/root.php:23 +msgid "Recently updated:" +msgstr "" + +#: tpl/admin/config/settings.php:95 +msgid "Recommended" +msgstr "" + +#: src/fs/FileWriter.php:150 +msgid "Refusing to copy over an existing file" +msgstr "" + +#. Help tip for "Template file" field in advanced bundle config +#: tpl/admin/bundle/conf.php:75 +msgid "Relative path from bundle root to the official POT file" +msgstr "" + +#: src/admin/file/BaseController.php:109 +msgid "Relocate" +msgstr "" + +#: tpl/admin/bundle/conf.php:159 tpl/admin/bundle/setup/saved.php:18 +msgid "Reset config" +msgstr "" + +#: src/admin/file/BaseController.php:108 tpl/admin/file/diff.php:30 +msgid "Restore" +msgstr "" + +#: src/admin/file/DiffController.php:74 src/admin/file/DiffController.php:92 +#, php-format +msgid "Restore %s" +msgstr "" + +#. Where %s is a file name +#: src/ajax/DiffController.php:47 +#, php-format +msgid "Revisions are identical, you can delete %s" +msgstr "" + +#: tpl/admin/root.php:47 +msgid "Running plugins:" +msgstr "" + +#: tpl/admin/bundle/conf.php:141 +msgid "Save config" +msgstr "" + +#: tpl/admin/config/settings.php:124 +msgid "Save credentials in session" +msgstr "" + +#: tpl/admin/config/settings.php:176 tpl/admin/config/apis.php:99 +#: tpl/admin/config/prefs.php:31 +msgid "Save settings" +msgstr "" + +#: tpl/admin/config/settings.php:68 tpl/admin/config/settings.php:72 +msgid "Saving PO/POT files" +msgstr "" + +#: src/ajax/FsConnectController.php:133 +msgid "Saving this file requires permission" +msgstr "" + +#: tpl/admin/config/settings.php:60 +msgid "Scan JavaScript files with extensions:" +msgstr "" + +#: tpl/admin/config/settings.php:54 +msgid "Scan PHP files with extensions:" +msgstr "" + +#: src/admin/bundle/LocaleController.php:137 +msgid "See all core translations" +msgstr "" + +#: tpl/admin/root.php:54 src/admin/bundle/LocaleController.php:147 +msgid "See all plugins" +msgstr "" + +#: tpl/admin/root.php:39 src/admin/bundle/LocaleController.php:142 +msgid "See all themes" +msgstr "" + +#: tpl/admin/init/init-prompt.php:40 +msgid "See FAQ" +msgstr "" + +#: tpl/admin/config/apis.php:93 +msgid "See full disclaimer" +msgstr "" + +#. Generic error when external process broke an Ajax request +#: src/js/Strings.php:98 +msgid "Server returned invalid data" +msgstr "" + +#. where %s is a plugin or theme +#: src/admin/bundle/SetupController.php:15 +#, php-format +msgid "Set up %s" +msgstr "" + +#: tpl/admin/list/inc-table.php:20 +msgid "Sets" +msgstr "" + +#: src/mvc/AdminRouter.php:67 src/mvc/AdminRouter.php:72 +#: src/data/Settings.php:185 src/admin/file/EditController.php:174 +#: tpl/admin/file/edit-po.php:62 tpl/admin/common/inc-fsconn.php:18 +#: tpl/admin/common/inc-fsconn.php:43 tpl/admin/errors/no-backups.php:24 +msgid "Settings" +msgstr "" + +#: src/admin/config/ApisController.php:43 +#: src/admin/config/PrefsController.php:26 +#: src/admin/config/SettingsController.php:31 +msgid "Settings saved" +msgstr "" + +#: src/admin/bundle/BaseController.php:96 +msgid "Setup" +msgstr "" + +#: src/admin/bundle/SetupController.php:25 +msgid "Setup tab" +msgstr "" + +#: tpl/admin/list/locales.php:25 +msgid "Site language" +msgstr "" + +#: src/admin/config/BaseController.php:18 +msgid "Site options" +msgstr "" + +#: tpl/admin/help/tab-config.php:5 +msgid "" +"Site options apply to all users of Loco Translate across the current site" +msgstr "" + +#: tpl/admin/config/settings.php:48 +msgid "Skip PHP files larger than:" +msgstr "" + +#: src/admin/init/InitPoController.php:227 +msgid "Skip template" +msgstr "" + +#: src/admin/file/BaseController.php:106 +msgid "Source" +msgstr "" + +#: tpl/admin/bundle/conf.php:100 +msgid "Source file paths" +msgstr "" + +#: tpl/admin/init/init-pot.php:12 +msgid "Source files to scan:" +msgstr "" + +#: tpl/admin/init/init-po.php:173 +msgid "Start translating" +msgstr "" + +#. Message appears after sync operation, where %s refers to a POT file. +#: src/js/Strings.php:37 +#, javascript-format +msgid "Strings up to date with %s" +msgstr "" + +#. Message appears after sync operation. +#: src/js/Strings.php:40 +msgid "Strings up to date with source code" +msgstr "" + +#: tpl/admin/init/init-pot.php:30 +msgid "Strings will be extracted to:" +msgstr "" + +#: src/js/Strings.php:70 +msgid "Suggested translations" +msgstr "" + +#: tpl/admin/init/init-prompt.php:34 +msgid "Suggestion" +msgstr "" + +#: src/admin/config/DebugController.php:47 +msgid "System diagnostics" +msgstr "" + +#: tpl/admin/file/view-pot.php:9 tpl/admin/file/edit-pot.php:10 +#: tpl/admin/file/info-pot.php:12 tpl/admin/bundle/inc-po-table.php:42 +#: tpl/admin/bundle/conf.php:65 +msgid "Template file" +msgstr "" + +#: src/admin/init/InitPotController.php:68 +msgid "Template file already exists" +msgstr "" + +#: src/ajax/XgettextController.php:62 +msgid "Template file created" +msgstr "" + +#: tpl/admin/init/init-prompt.php:10 +msgid "Template missing" +msgstr "" + +#: tpl/admin/init/init-po.php:136 +msgid "Template options" +msgstr "" + +#: tpl/admin/bundle/conf.php:41 tpl/admin/list/inc-table.php:14 +msgid "Text domain" +msgstr "" + +#: src/config/FormModel.php:146 +msgid "Text Domain cannot be empty" +msgstr "" + +#. "either" meaning that the file itself can't exist without a containing directory +#: tpl/admin/file/info.php:59 +msgid "The containing directory for this file doesn't exist either" +msgstr "" + +#. Where %s is the name (or number) of an operating system user +#: tpl/admin/file/info.php:73 +#, php-format +msgid "" +"The containing directory is writeable by %s, so you can add new files in the " +"same location" +msgstr "" + +#: tpl/admin/file/move.php:17 +msgid "The following file will be moved/renamed to the new location:" +msgid_plural "The following files will be moved/renamed to the new location:" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/root.php:12 +#, php-format +msgid "The language of this site is %s." +msgstr "" + +#. Help tip for "Text domain" field in advanced bundle config +#: tpl/admin/bundle/conf.php:47 +msgid "The namespace into which WordPress will load translated strings" +msgstr "" + +#. used when user name of web server process is unknown +#: src/compat/PosixExtension.php:109 +msgid "the web server" +msgstr "" + +#. Page title for theme translations +#: src/mvc/AdminRouter.php:46 +msgid "Theme translations ‹ Loco" +msgstr "" + +#: src/mvc/AdminRouter.php:44 src/admin/Navigation.php:41 +#: src/admin/bundle/LocaleController.php:141 +msgid "Themes" +msgstr "" + +#: tpl/admin/root.php:50 +msgid "" +"These plugins have recently loaded translation files into the admin area" +msgstr "" + +#: tpl/admin/file/info-po.php:83 +msgid "" +"These translations are not linked to a POT file. Sync operations will " +"extract strings directly from source code." +msgstr "" + +#: tpl/admin/config/apis.php:92 +msgid "" +"Third party services are subject to their own terms of use and may incur " +"costs from the provider" +msgstr "" + +#: tpl/admin/init/init-prompt.php:18 +msgid "This bundle doesn't define a translations template file" +msgstr "" + +#: tpl/admin/bundle/view.php:55 +msgid "" +"This bundle isn't automatically compatible and requires configuring before " +"you can use all the functions of Loco Translate" +msgstr "" + +#: tpl/admin/bundle/view.php:32 +msgid "" +"This bundle isn't fully configured, so we don't know what the following " +"files are for" +msgstr "" + +#: tpl/admin/bundle/setup/none.php:14 +msgid "This bundle isn't set up for translation in a way we understand" +msgstr "" + +#: tpl/admin/bundle/setup/meta.php:14 +msgid "" +"This bundle's configuration has been automatically detected and seems to be " +"fully compatible" +msgstr "" + +#: tpl/admin/bundle/setup/partial.php:14 +msgid "" +"This bundle's configuration has been automatically detected, but isn't fully " +"complete" +msgstr "" + +#: tpl/admin/bundle/setup/core.php:13 +msgid "This bundle's configuration is built into Loco" +msgstr "" + +#: tpl/admin/bundle/setup/author.php:14 +msgid "This bundle's configuration is provided by the author" +msgstr "" + +#: tpl/admin/bundle/setup/saved.php:14 +msgid "This bundle's configuration is saved in the WordPress database" +msgstr "" + +#: tpl/admin/init/init-prompt.php:14 +msgid "" +"This bundle's template file doesn't exist yet. We recommend you create it " +"before adding languages" +msgstr "" + +#: tpl/admin/file/info.php:92 +msgid "This directory can't be written to directly by the web server" +msgstr "" + +#: src/ajax/FsConnectController.php:108 +msgid "This directory is managed by WordPress, be careful what you delete" +msgstr "" + +#: src/ajax/FsConnectController.php:111 +msgid "" +"This directory is managed by WordPress. Removed files may be restored during " +"updates" +msgstr "" + +#: tpl/admin/file/info.php:39 +msgid "This file can't be updated directly by the web server" +msgstr "" + +#: src/ajax/FsConnectController.php:105 +msgid "This file may be overwritten or deleted when you update WordPress" +msgstr "" + +#: tpl/admin/bundle/debug.php:8 +msgid "This information is for developers to find problems in the bundle setup" +msgstr "" + +#. Warning when POT file is opened in the file editor. It can be disabled in settings. +#: src/admin/file/EditController.php:173 +msgid "" +"This is NOT a translation file. Manual editing of source strings is not " +"recommended." +msgstr "" + +#: src/ajax/FsConnectController.php:130 +msgid "This move operation requires permission" +msgstr "" + +#: tpl/admin/errors/file-isdir.php:14 +msgid "This page was expecting a file, but the path is actually a directory" +msgstr "" + +#: src/hooks/AdminHooks.php:64 +msgid "This plugin doesn't collect any data from public website visitors." +msgstr "" + +#: tpl/admin/bundle/alias.php:14 +msgid "" +"This plugin doesn't have its own translation files, but can be translated in " +"the default text domain" +msgstr "" + +#. Author of the plugin +msgid "Tim Whitlock" +msgstr "" + +#. Where %s is the name (or number) of an operating system user +#: tpl/admin/file/info.php:96 +#, php-format +msgid "" +"To create new files here you'll have to connect to the remote file system, " +"or make the directory writeable by %s" +msgstr "" + +#. Where %s is the name (or number) of an operating system user +#: tpl/admin/file/info.php:43 +#, php-format +msgid "" +"To make changes you'll have to connect to the remote file system, or make " +"the file writeable by %s" +msgstr "" + +#: src/hooks/AdminHooks.php:103 tpl/admin/file/edit-po.php:42 +msgid "Translate" +msgstr "" + +#: src/admin/list/PluginsController.php:12 +msgid "Translate plugins" +msgstr "" + +#: src/admin/list/ThemesController.php:14 +msgid "Translate themes" +msgstr "" + +#. Description of the plugin +msgid "Translate themes and plugins directly in WordPress" +msgstr "" + +#: src/js/Strings.php:54 +#, javascript-format +msgid "Translation job aborted with one string remaining" +msgid_plural "Translation job aborted with %s strings remaining" +msgstr[0] "" +msgstr[1] "" + +#: tpl/admin/file/info-po.php:28 tpl/admin/bundle/inc-po-table.php:16 +#: tpl/admin/bundle/locale.php:36 +msgid "Translation progress" +msgstr "" + +#. %s%% is a percentage, e.g. 50% +#: src/js/Strings.php:51 +#, javascript-format +msgid "Translation progress %s%%" +msgstr "" + +#. Where %s is the name of the invalid POT file +#: src/ajax/SyncController.php:47 src/admin/file/EditController.php:135 +#, php-format +msgid "Translation template is invalid (%s)" +msgstr "" + +#: src/admin/file/EditController.php:130 +#, php-format +msgid "Translations don't match template. Run sync to update from %s" +msgstr "" + +#: tpl/admin/root.php:26 +msgid "Translations have been recently modified in the following bundles" +msgstr "" + +#: tpl/admin/config/prefs.php:16 tpl/admin/config/prefs.php:20 +msgid "Translator credit" +msgstr "" + +#: tpl/admin/bundle/view.php:52 +msgid "unconfigured" +msgstr "" + +#: tpl/admin/bundle/setup/none.php:11 +msgid "Unconfigured bundle" +msgstr "" + +#: tpl/admin/file/info-other.php:11 +msgid "Unexpected file type" +msgstr "" + +#: src/package/Header.php:77 src/admin/file/InfoController.php:127 +msgid "Unknown author" +msgstr "" + +#: src/js/Strings.php:107 +msgid "Unknown error" +msgstr "" + +#: tpl/admin/config/version.php:17 +#, php-format +msgid "Upgrade to %s" +msgstr "" + +#: tpl/admin/init/init-po.php:163 +msgid "Use this file as template when running Sync" +msgstr "" + +#: src/js/Strings.php:67 +msgid "Use this translation" +msgstr "" + +#: src/mvc/AdminRouter.php:71 src/admin/config/PrefsController.php:13 +#: src/admin/config/BaseController.php:19 +msgid "User options" +msgstr "" + +#: tpl/admin/help/tab-config.php:6 +msgid "User options apply to your WordPress login, across all sites" +msgstr "" + +#: src/data/Permissions.php:157 +msgctxt "User role" +msgid "Translator" +msgstr "" + +#. Help tip for "File prefix" field in advanced bundle config +#: tpl/admin/bundle/conf.php:59 +msgid "" +"Usually the same as the text domain, but don't leave blank unless you mean to" +msgstr "" + +#: src/admin/config/VersionController.php:13 +#: src/admin/config/BaseController.php:21 +msgid "Version" +msgstr "" + +#: tpl/admin/config/version.php:11 tpl/admin/config/version.php:25 +#: tpl/admin/config/version.php:35 +#, php-format +msgid "Version %s" +msgstr "" + +#: tpl/admin/bundle/inc-po-table.php:51 tpl/admin/bundle/locale.php:66 +msgid "View" +msgstr "" + +#: src/admin/bundle/ViewController.php:108 +msgid "View template" +msgstr "" + +#: src/package/Header.php:83 +msgid "Visit official site" +msgstr "" + +#: src/js/Strings.php:113 src/error/Warning.php:19 +msgid "Warning" +msgstr "" + +#: tpl/admin/file/info-po.php:45 +msgid "We can't find the binary MO file that belongs with these translations" +msgstr "" + +#: tpl/admin/file/info-mo.php:41 +msgid "We can't find the original PO file from which this was compiled" +msgstr "" + +#: tpl/admin/bundle/setup/conf.php:16 +msgid "" +"We have a database of non-standard bundle configurations.\n" +"If we know your bundle, we'll configure it for you automatically" +msgstr "" + +#: src/admin/RootController.php:84 +msgid "Welcome to Loco Translate" +msgstr "" + +#: src/admin/init/InitPoController.php:316 tpl/admin/file/info.php:113 +msgid "What's this?" +msgstr "" + +#: src/mvc/AdminRouter.php:54 +msgid "WordPress" +msgstr "" + +#: src/package/Core.php:79 src/admin/bundle/LocaleController.php:136 +msgid "WordPress Core" +msgstr "" + +#: src/package/Core.php:26 +msgid "WordPress core" +msgstr "" + +#: tpl/admin/init/init-po.php:55 +msgid "WordPress language" +msgstr "" + +#: tpl/admin/file/info.php:107 +msgid "WordPress updates" +msgstr "" + +#. When a file or folder cannot be modified due to filesystem permissions +#: tpl/admin/file/info.php:36 tpl/admin/file/info.php:89 +#: tpl/admin/common/inc-fsconn.php:50 +msgid "Write protected" +msgstr "" + +#: tpl/admin/bundle/conf.php:146 +msgid "XML" +msgstr "" + +#: src/error/XmlParseException.php:8 +msgid "XML parse error" +msgstr "" + +#: tpl/admin/bundle/setup/conf.php:46 +msgid "XML setup" +msgstr "" + +#: src/config/XMLModel.php:42 +msgid "XML supplied is empty" +msgstr "" + +#: tpl/admin/bundle/setup/meta.php:15 tpl/admin/bundle/setup/author.php:15 +#: tpl/admin/bundle/setup/core.php:14 +msgid "" +"You can make changes in the Advanced tab if you need to override the current " +"settings" +msgstr "" + +#. %s is a URL. Keep the tag intact +#: tpl/admin/errors/no-tokenizer.php:25 +#, php-format +msgid "" +"You can still translate any bundle that has a template" +msgstr "" + +#: tpl/admin/file/info.php:27 +msgid "" +"You can update these translations directly from the editor to the file system" +msgstr "" + +#: tpl/admin/init/init-prompt.php:36 +msgid "You can use existing translations as a template using the Copy feature." +msgstr "" + +#: tpl/admin/init/init-po.php:12 +msgid "You're creating translations directly from source code" +msgstr "" + +#: tpl/admin/config/version.php:28 +msgid "You're running a development snapshot of Loco Translate" +msgstr "" + +#: tpl/admin/config/version.php:38 +msgid "You're running the latest version of Loco Translate" +msgstr "" + +#: tpl/admin/root.php:14 +#, php-format +msgid "Your admin language is %s." +msgstr "" + +#. Warning appears when user tries to refresh or navigate away when editor work is unsaved +#: src/js/Strings.php:79 +msgid "Your changes will be lost if you continue without saving" +msgstr "" diff --git a/vendor/loco-translate/lib/compiled/README.md b/vendor/loco-translate/lib/compiled/README.md new file mode 100644 index 0000000..9edc7c3 --- /dev/null +++ b/vendor/loco-translate/lib/compiled/README.md @@ -0,0 +1,5 @@ +# Compiled libraries + +These files are built from the Loco core. Do not edit! + +They've been converted down for PHP 5.2 compatibility in WordPress. diff --git a/vendor/loco-translate/lib/compiled/gettext.php b/vendor/loco-translate/lib/compiled/gettext.php new file mode 100644 index 0000000..ca4b1fd --- /dev/null +++ b/vendor/loco-translate/lib/compiled/gettext.php @@ -0,0 +1,46 @@ +map = array_combine( array_map( 'strtolower', $keys ), $keys ); parent::__construct($raw); } } public function normalize( $key ){ $k = strtolower($key); return isset($this->map[$k]) ? $this->map[$k] : null; } public function add($key, $val ){ $this->offsetSet( $key, $val ); return $this; } public function __toString(){ $pairs = array(); foreach( $this as $key => $val ){ $pairs[] = $key.': '.$val; } return implode("\n", $pairs ); } public function trimmed($prop ){ return trim( $this->__get($prop) ); } public function has($key ){ $k = strtolower($key); return isset($this->map[$k]); } public function __get($key ){ return $this->offsetGet( $key ); } public function __set($key, $val ){ $this->offsetSet( $key, $val ); } public function offsetExists($k ){ return ! is_null( $this->normalize($k) ); } public function offsetGet($k ){ $k = $this->normalize($k); if( is_null($k) ){ return ''; } return parent::offsetGet($k); } public function offsetSet($key, $v ){ $k = strtolower($key); if( isset($this->map[$k]) && $key !== $this->map[$k] ){ parent::offsetUnset( $this->map[$k] ); } $this->map[$k] = $key; parent::offsetSet( $key, $v ); } public function offsetUnset($key ){ $k = strtolower($key); if( isset($this->map[$k]) ){ parent::offsetUnset( $this->map[$k] ); unset( $this->map[$k] ); } } public function jsonSerialize(){ return $this->getArrayCopy(); } public function keys(){ trigger_error('Is this required?', E_USER_NOTICE); return array_values( $this->map ); } } +function loco_normalize_charset( $cs ){ if( preg_match('/^UTF-?8$/i',$cs) ){ return 'UTF-8'; } $aliases = @mb_encoding_aliases($cs); if( false === $aliases ){ throw new InvalidArgumentException('Unsupported character encoding: '.$cs ); } if( $r = preg_grep('/^ISO[-_]\\d+[-_]\\d+$/i',$aliases) ){ $cs = current($aliases); $cs = strtr( strtoupper($cs), '_', '-' ); } else if( in_array('US-ASCII',$aliases,true) ){ $cs = 'US-ASCII'; } return $cs; } +class LocoPoHeaders extends LocoHeaders { private $cs; public function getCharset(){ $cs = $this->cs; if( is_null($cs) ){ $cs = ''; $raw = $this->offsetGet('content-type'); if( $raw && preg_match('!\\bcharset[= ]+([-\\w]+)!',$raw,$r) ){ try { $cs = loco_normalize_charset($r[1]); } catch( InvalidArgumentException $e ){ $cs = null; } catch( Throwable $e ){ trigger_error( $e->getMessage(), E_USER_NOTICE ); $cs = null; } } $this->cs = $cs; } return $cs; } public function setCharset( $to ){ $to = loco_normalize_charset($to); $from = $this->getCharset(); $this->cs = $to; $this['Content-Type'] = 'text/plain; charset='.$to; if( $from && $from !== $to ){ foreach( $this as $key => $val ){ $this[$key] = mb_convert_encoding($val,$to,$from); } } return $to; } public static function fromMsgstr( $str ){ $headers = new LocoPoHeaders; $key = ''; foreach( preg_split('/[\\r\\n]+/',$str) as $line ){ $i = strpos($line,':'); if( is_int($i) ){ $key = trim( substr($line,0,$i), " \t" ); $headers->offsetSet( $key, ltrim( substr($line,++$i)," \t" ) ); } else if( '' !== $key ){ $headers->offsetSet( $key, $headers->offsetGet($key)."\n".$line ); } } $cs = $headers->getCharset(); if( $cs && 'UTF-8' !== $cs && 'UTF-8' !== mb_detect_encoding($str,array('UTF-8',$cs),true) ){ foreach( $headers as $key => $val ){ $headers[$key] = mb_convert_encoding($val,'UTF-8',array($cs)); } } return $headers; } public static function fromSource( $raw ){ $po = new LocoPoParser($raw); $po->parse(0); return $po->getHeader(); } } +function loco_convert_utf8( $str, $enc ){ if( '' === $enc ){ if( false === preg_match('//u',$str) ){ $str = mb_convert_encoding( $str, 'UTF-8', 'cp1252' ); } } else if( 'UTF-8' === $enc || 'US-ASCII' === $enc ){ if( false === preg_match('//u',$str) ){ throw new Loco_error_ParseException('Bad '.$enc.' encoding'); } } else if( 'ISO-8859-1' === $enc ) { $str = mb_convert_encoding( $str, 'UTF-8', 'cp1252' ); } else { $str = mb_convert_encoding( $str, 'UTF-8', $enc ); } return $str; } +abstract class LocoGettextParser { private $head; private $cs; abstract public function parse( $limit = -1 ); protected function setHeader( LocoPoHeaders $head ){ $this->head = $head; if( $cs = $head->getCharset() ){ if( is_null($this->cs) ){ $this->setCharset($cs); } } return $head; } public function getHeader(){ return $this->head; } protected function setCharset( $cs ){ $this->cs = $cs; } protected function getCharset(){ return $this->cs; } protected function str( $str ){ if( '' !== $str ){ $enc = (string) $this->cs; $str = loco_convert_utf8( $str, $enc ); } return $str; } } +function loco_remove_bom( $s, &$c ){ $bom = substr($s,0,2); if( "\xFF\xFE" === $bom ){ $c = 'UTF-16LE'; return substr($s,2); } if( "\xFE\xFF" === $bom ){ $c = 'UTF-16BE'; return substr($s,2); } if( "\xEF\xBB" === $bom && "\xBF" === $s[2] ){ $c = 'UTF-8'; return substr($s,3); } $c = ''; return $s; } +function loco_parse_reference_id( $refs, &$_id ){ if( false === ( $n = strpos($refs,'loco:') ) ){ $_id = ''; return $refs; } $_id = substr($refs, $n+5, 24 ); $refs = substr_replace( $refs, '', $n, 29 ); return trim( $refs ); } +class LocoPoParser extends LocoGettextParser implements Iterator { private $lines = array(); private $i; private $k; private $m; public function __construct( $src ){ if( '' !== $src ){ $src = loco_remove_bom($src,$cs); if( $cs && 'UTF-8' !== $cs ){ $src = mb_convert_encoding( $src, 'UTF-8', array($cs) ); } if( 'UTF-8' === mb_detect_encoding($src,array('UTF-8','ISO-8859-1'),true) ){ $this->setCharset('UTF-8'); } $this->lines = preg_split('/(\\r\\n?|\\n)/', $src ); } } public function rewind(){ $this->i = -1; $this->k = -1; $this->next(); } public function valid(){ return is_int($this->i); } public function key(){ return $this->k; } public function current(){ return $this->m; } public function next(){ $valid = false; $entry = array( '#' => array(), 'id' => array(null), 'str' => array(null) ); $i = $this->i; while( array_key_exists(++$i,$this->lines) ){ $line = $this->lines[$i]; try { if( '' === $line ){ if( $valid ){ break; } continue; } $c = $line[0]; if( '#' === $c ){ if( $valid ){ $i--; break; } if( '#' === $line ){ continue; } $f = $line[1]; $entry['#'][$f][] = trim( substr( $line, 1+strlen($f) ), "/ \n\r\t" ); } else if( preg_match('/^msg(id(?:_plural)?|ctxt|str(?:\\[(\\d+)])?)[ \\t]*/', $line, $r ) ){ if( isset($r[2]) ){ $key = 'str'; $idx = (int) $r[2]; } else { $key = $r[1]; $idx = 0; } if( $valid && 'str' !== $key && null !== $entry['str'][0] ){ $i--; break; } $snip = strlen($r[0]); if( '"' !== substr($line,$snip,1) ){ throw new Exception('Expected " to follow msg'.$key); } $val = ''; $line = substr($line,$snip); while( true ){ if( '"' === $line || '"' !== substr($line,-1) ){ throw new Exception('Unterminated msg'.$key ); } $val .= substr( $line, 1, -1 ); $j = $i + 1; if( array_key_exists($j,$this->lines) && ( $line = $this->lines[$j] ) && '"' === $line[0] ){ $i = $j; } else { break; } } if( ! $valid ){ $valid = true; } if( 'id_plural' === $key ){ $key = 'id'; $idx = 1; } $entry[$key][$idx] = stripcslashes($val); } else if( preg_match('/^[ \\t]+$/',$line) ){ if( $valid ) { break; } } else if( '"' === $c ){ throw new Exception('String encountered without keyword'); } else { throw new Exception('Junk'); } } catch( Exception $e ){ } } if( $valid ){ ++$this->k; $this->i = $i; $this->m = $entry; } else { $this->i = null; $this->k = null; $this->m = null; } } public function parse( $limit = -1 ){ $this->rewind(); if( ! $this->valid() ){ throw new Loco_error_ParseException('Invalid PO file'); } $i = -1; $assets = array(); $entry = $this->current(); if( '' !== $entry['id'][0] || isset($entry['ctxt']) || is_null($entry['str'][0]) ){ $head = $this->setHeader( new LocoPoHeaders ); } else { $head = $this->setHeader( LocoPoHeaders::fromMsgstr($entry['str'][0]) ); } $lk = $head['X-Loco-Lookup']; while( $this->valid() ){ $entry = $this->current(); $this->next(); $msgid = $entry['id'][0]; if( is_null($msgid) ){ continue; } if( ++$i === $limit ){ return $assets; } $asset = array( 'source' => $this->str( $msgid ), 'target' => $this->str( (string) $entry['str'][0] ), 'context' => null, ); $prev_entry = null; if( isset($entry['ctxt']) ){ $asset['context'] = $this->str( $entry['ctxt'][0] ); } $cmt = $entry['#']; if( isset($cmt[' ']) ){ $asset['comment'] = $this->str( implode("\n", $cmt[' '] ) ); } if( isset($cmt['.']) ){ $asset['notes'] = $this->str( implode("\n", $cmt['.'] ) ); } if( isset($cmt[':']) ){ if( $refs = implode( ' ', $cmt[':'] ) ) { $refs = $this->str($refs); if( $refs = loco_parse_reference_id( $refs, $_id ) ){ $asset['refs'] = $refs; } if( $_id ){ $asset['_id'] = $_id; } } } if( isset($cmt[',']) ){ foreach( $cmt[','] as $flags ){ foreach( explode(',',$flags) as $flag ){ if( $flag = trim($flag," \t") ){ if( preg_match('/^((?:no-)?\w+)-format/', $flag, $r ) ){ $asset['format'] = $r[1]; } else if( 'fuzzy' === $flag ){ $asset['flag'] = 4; } } } } } if( isset($cmt['|']) ){ $p = new LocoPoParser(''); $p->lines = $cmt['|']; $p->setCharset( $this->getCharset() ); try { $prev_entry = $p->parse(); } catch( Loco_error_ParseException $e ){ } if( $prev_entry ){ $msgid = $prev_entry[0]['source']; if( $lk && 'text' !== $lk ){ $asset[$lk] = $asset['source']; $asset['source'] = $msgid; } else if( 'loco:' === substr($msgid,0,5) ){ $asset['_id'] = substr($msgid,5); } else { $asset['prev'] = $prev_entry; $prev_entry = null; } } } $assets[] = $asset; if( isset($entry['id'][1]) ){ $idx = 0; $pidx = count($assets) - 1; $num = max( 2, count($entry['str']) ); while( ++$idx < $num ){ $plural = array( 'source' => '', 'target' => isset($entry['str'][$idx]) ? $this->str($entry['str'][$idx]) : '', 'plural' => $idx, 'parent' => $pidx, ); if( 1 === $idx ){ $plural['source'] = $this->str($entry['id'][1]); if( is_array($prev_entry) && isset($prev_entry[1]) ){ if( $lk && 'text' !== $lk ){ $plural[$lk] = $plural['source']; $plural['source'] = $prev_entry[1]['source']; } } } if( isset($asset['flag']) ){ $plural['flag'] = $asset['flag']; } $assets[] = $plural; } } } if( -1 === $i ){ throw new Loco_error_ParseException('Invalid PO file'); } else if( 0 === $i && '' === $assets[0]['source'] && '' === $assets[0]['target'] ){ throw new Loco_error_ParseException('Invalid PO file' ); } return $assets; } } +class LocoMoParser extends LocoGettextParser { private $bin; private $be; private $n; private $o; private $t; private $v; public function __construct( $bin ){ $this->bin = $bin; } public function getAt( $idx ){ $offset = $this->targetOffset(); $offset += ( $idx * 8 ); $len = $this->integerAt( $offset ); $idx = $this->integerAt( $offset + 4 ); $txt = $this->bytes( $idx, $len ); if( false === strpos( $txt, "\0") ){ return $txt; } return explode( "\0", $txt ); } public function parse( $limit = -1 ){ $i = -1; $r = array(); $sourceOffset = $this->sourceOffset(); $targetOffset = $this->targetOffset(); $soffset = $sourceOffset; $toffset = $targetOffset; while( $soffset < $targetOffset ){ $len = $this->integerAt( $soffset ); $idx = $this->integerAt( $soffset + 4 ); $src = $this->bytes( $idx, $len ); $eot = strpos( $src, "\x04" ); if( false === $eot ){ $context = null; } else { $context = $this->str( substr($src, 0, $eot ) ); $src = substr( $src, $eot+1 ); } $sources = explode( "\0", $src, 2 ); $len = $this->integerAt( $toffset ); $idx = $this->integerAt( $toffset + 4 ); $targets = explode( "\0", $this->bytes( $idx, $len ) ); if( -1 === $i && '' === $sources[0] && is_null($context) ){ $this->setHeader( LocoPoHeaders::fromMsgstr($targets[0]) ); } if( ++$i === $limit ){ break; } $r[$i] = array( 'source' => $this->str( $sources[0] ), 'target' => $this->str( $targets[0] ), 'context' => $context, ); if( isset($sources[1]) ){ $p = count($r) - 1; $nforms = max( 2, count($targets) ); for( $i = 1; $i < $nforms; $i++ ){ $r[] = array( 'source' => isset($sources[$i]) ? $this->str( $sources[$i] ) : sprintf('%s (plural %u)',$r[$p]['source'],$i), 'target' => isset($targets[$i]) ? $this->str( $targets[$i] ) : '', 'parent' => $p, 'plural' => $i, ); } } $soffset += 8; $toffset += 8; } return $r; } public function isBigendian(){ if( is_null($this->be) ){ $str = $this->words( 0, 1 ); if( "\xDE\x12\x04\x95" === $str ){ $this->be = false; } else if( "\x95\x04\x12\xDE" === $str ){ $this->be = true; } else { throw new Loco_error_ParseException('Invalid MO format'); } } return $this->be; } public function version(){ if( is_null($this->v) ){ $this->v = $this->integerWord(1); } return $this->v; } public function count(){ if( is_null($this->n) ){ $this->n = $this->integerWord(2); } return $this->n; } public function sourceOffset(){ if( is_null($this->o) ){ $this->o = $this->integerWord(3); } return $this->o; } public function targetOffset(){ if( is_null($this->t) ){ $this->t = $this->integerWord(4); } return $this->t; } public function getHashTable(){ $s = $this->integerWord(5); $h = $this->integerWord(6); return $this->bytes( $h, $s * 4 ); } private function bytes( $offset, $length ){ $s = substr( $this->bin, $offset, $length ); if( strlen($s) !== $length ){ throw new Loco_error_ParseException('Failed to read '.$length.' bytes at ['.$offset.']' ); } return $s; } private function words( $offset, $length ){ return $this->bytes( $offset * 4, $length * 4 ); } private function integerWord( $offset ){ return $this->integerAt( $offset * 4 ); } private function integerAt( $offset ){ $str = $this->bytes( $offset, 4 ); $fmt = $this->isBigendian() ? 'N' : 'V'; $arr = unpack( $fmt, $str ); if( ! isset($arr[1]) || ! is_int($arr[1]) ){ throw new Loco_error_ParseException('Failed to read integer at byte '.$offset); } return $arr[1]; } } +abstract class LocoPo { public static function pair( $key, $text, $width = 79, $eol = "\n", $esc = '\\n' ){ if( '' === $text ){ return $key.' ""'; } $text = addcslashes( $text, "\t\x0B\x0C\x07\x08\\\"" ); if( $esc ) { $text = preg_replace('/(?:\\r\\n?|\\n)/', $esc.$eol, $text, -1, $nbr ); } else { $eol = "\n"; $text = preg_replace_callback('/(?:\\r\\n?|\\n)/',array(__CLASS__,'replace_br'), $text, -1, $nbr ); } if( $nbr ){ } else if( $width && $width < mb_strlen($text,'UTF-8') + strlen($key) + 3 ){ } else { return $key.' "'.$text.'"'; } $lines = array( $key.' "' ); if( $width ){ $width -= 2; $a = '/^.{0,'.($width-1).'}[-– \\.,:;\\?!\\)\\]\\}\\>]/u'; $b = '/^[^-– \\.,:;\\?!\\)\\]\\}\\>]+/u'; foreach( explode($eol,$text) as $unwrapped ){ $length = mb_strlen( $unwrapped, 'UTF-8' ); while( $length > $width ){ if( preg_match( $a, $unwrapped, $r ) ){ $line = $r[0]; } else if( preg_match( $b, $unwrapped, $r ) ){ $line = $r[0]; } else { throw new Exception('Wrapping error'); } $lines[] = $line; $trunc = mb_strlen($line,'UTF-8'); $length -= $trunc; $unwrapped = (string) substr( $unwrapped, strlen($line) ); if( ( '' === $unwrapped && 0 !== $length ) || ( 0 === $length && '' !== $unwrapped ) ){ throw new Exception('Truncation error'); } } if( 0 !== $length ){ $lines[] = $unwrapped; } } } else { foreach( explode($eol,$text) as $unwrapped ){ $lines[] = $unwrapped; } } return implode('"'.$eol.'"',$lines).'"'; } private static function replace_br( array $r ){ return addcslashes($r[0],"\r\n")."\n"; } public static function refs( $text, $width = 76, $eol = "\n" ){ $text = preg_replace('/\\s+/u', ' ', $text ); if( $width ){ $text = wordwrap( $text, $width, $eol.'#: ', false ); } return '#: '.$text; } public static function prefix( $text, $prefix, $eol = "\n" ){ $lines = preg_split('/\\R/u', $text, -1 ); return $prefix.implode( $eol.$prefix, $lines ); } } +class LocoPoIndex extends ArrayIterator { public function compare( LocoPoMessage $a, LocoPoMessage $b ){ $h = $a->getHash(); if( ! isset($this[$h]) ){ return 1; } $j = $b->getHash(); if( ! isset($this[$j]) ){ return -1; } return $this[$h] > $this[$j] ? 1 : -1; } } +class LocoPoMessage extends ArrayObject { public function __construct( array $r ){ $r['key'] = $r['source']; parent::__construct($r); } public function __get( $prop ){ return isset($this[$prop]) ? $this[$prop] : null; } private function _getFlags(){ $flags = array(); $plurals = $this->__get('plurals'); if( 4 === $this->__get('flag') ){ $flags[] = 'fuzzy'; } else if( $plurals ){ foreach( $plurals as $child ){ if( 4 === $child->__get('flag') ){ $flags[] = 'fuzzy'; break; } } } if( $f = $this->__get('format') ){ $flags[] = $f.'-format'; } else if( isset($plurals[0]) && ( $f = $plurals[0]->format ) ){ $flags[] = $f.'-format'; } return $flags; } public function getHash(){ $hash = $this->getKey(); if( isset($this['plurals']) ){ foreach( $this['plurals'] as $p ){ $hash .= "\0".$p->getHash(); break; } } return $hash; } public function getKey(){ $msgid = (string) $this['source']; $msgctxt = (string) $this->__get('context'); if( '' !== $msgctxt ){ if( '' === $msgid ){ $msgid = '('.$msgctxt.')'; } $msgid = $msgctxt."\4".$msgid; } return $msgid; } public function __toString(){ return $this->render( 79, 76 ); } public function render( $width, $ref_width ){ $s = array(); try { if( $text = $this->__get('comment') ) { $s[] = LocoPo::prefix( $text, '# '); } if( $text = $this->__get('notes') ) { $s[] = LocoPo::prefix( $text, '#. '); } if( $text = $this->__get('refs') ){ $s[] = LocoPo::refs( $text, $ref_width ); } if( $texts = $this->_getFlags() ){ $s[] = '#, '.implode(', ',$texts); } $plurals = $this->__get('plurals'); $prev = $this->__get('prev'); if( is_array($prev) && $prev ){ foreach( new LocoPoIterator($prev) as $p ){ $text = $p->render( max(0,$width-3), 0 ); $text = preg_replace('/^msg[_a-z]+(\\[\\d+])? ""\\n/m','',$text); $s[] = LocoPo::prefix( rtrim($text,"\n"),'#| '); break; } } $text = $this->__get('context'); if( is_string($text) && '' !== $text ){ $s[] = LocoPo::pair('msgctxt', $text, $width ); } $s[] = LocoPo::pair( 'msgid', $this['key'], $width ); $target = $this['target']; if( is_array($plurals) ){ if( $plurals ){ foreach( $plurals as $i => $p ){ if( 0 === $i ){ $s[] = LocoPo::pair('msgid_plural', $p['key'], $width ); $s[] = LocoPo::pair('msgstr[0]', $target, $width ); } $s[] = LocoPo::pair('msgstr['.(++$i).']', $p['target'], $width ); } } else if( isset($this['plural_key']) ){ $s[] = LocoPo::pair('msgid_plural', $this['plural_key'], $width ); $s[] = LocoPo::pair('msgstr[0]', $target, $width ); } else { trigger_error('Missing plural_key in zero plural export'); $s[] = LocoPo::pair('msgstr', $target, $width ); } } else { $s[] = LocoPo::pair('msgstr', $target, $width ); } } catch( Exception $e ){ trigger_error( $e->getMessage(), E_USER_WARNING ); } return implode("\n",$s)."\n"; } } +class LocoPoIterator implements Iterator, Countable { private $po; private $headers; private $i; private $t; private $j; private $z; private $w = 79; public function __construct( $po ){ $this->po = $po; $this->t = count( $po ); if( ! isset($po[0]) ){ throw new InvalidArgumentException('Empty PO data'); } $h = $po[0]; if( '' === $h['source'] && empty($h['context']) ){ $this->z = 0; } else { $this->z = -1; } } public function count(){ return $this->t - ( $this->z + 1 ); } public function at( $index ){ return $this->po[ $this->z + $index ]; } public function wrap( $width ){ $width = (int) $width; if( $width > 0 ){ $this->w = max( 15, $width ); } else { $this->w = 0; } return $this; } public function rewind(){ $this->i = $this->z; $this->j = -1; $this->next(); } public function key(){ return $this->j; } public function valid(){ return is_int($this->i); } public function next(){ $i = $this->i; while( ++$i < $this->t ){ $this->j++; $this->i = $i; return; } $this->i = null; $this->j = null; } public function current(){ $i = $this->i; $po = $this->po; $parent = new LocoPoMessage( $po[$i] ); $plurals = array(); while( isset($po[++$i]['parent']) ){ $this->i = $i; $plurals[] = new LocoPoMessage( $po[$i] ); } if( $plurals ){ $parent['plurals'] = $plurals; } return $parent; } public function getArrayCopy(){ $po = $this->po; if( 0 === $this->z ){ $po[0]['target'] = (string) $this->getHeaders(); } return $po; } public function getHeaders(){ if( ! $this->headers ){ $header = $this->po[0]; if( 0 === $this->z ){ $this->headers = LocoPoHeaders::fromMsgstr( $header['target'] ); } else { $this->headers = new LocoPoHeaders; } } return $this->headers; } public function initPo(){ if( 0 === $this->z ){ unset( $this->po[0]['flag'] ); } return $this; } public function initPot(){ if( 0 === $this->z ){ $this->po[0]['flag'] = 4; } return $this; } public function strip(){ $po = $this->po; $i = count($po); $z = $this->z; while( --$i > $z ){ $po[$i]['target'] = ''; } $this->po = $po; return $this; } public function __toString(){ try { return $this->render(); } catch( Exception $e ){ trigger_error( $e->getMessage(), E_USER_WARNING ); return ''; } } public function render( $sorter = null ){ $width = $this->w; $ref_width = max( 0, $width - 3 ); if( 0 === $this->z ){ $h = $this->po[0]; } else { $h = array( 'source' => '' ); } $h['target'] = (string) $this->getHeaders(); $msg = new LocoPoMessage( $h ); $s = $msg->render( $width, $ref_width ); if( $sorter ){ if( ! is_callable($sorter) ){ throw new InvalidArgumentException('Bad callback'); } $msgs = array(); foreach( $this as $msg ){ $msgs[] = $msg; } usort( $msgs, $sorter ); } else { $msgs = $this; } foreach( $msgs as $msg ){ $s .= "\n".$msg->render( $width, $ref_width ); } return $s; } public function exportRefs( $grep = '' ){ $a = array(); if( '' === $grep ) { $grep = '/(\\S+):\\d+/'; } else { $grep = '/(\\S*'.$grep.'):\\d+/'; } foreach( $this as $message ){ if( preg_match_all( $grep, (string) $message->refs, $r ) ){ foreach( $r[1] as $ref ) { $a[$ref][] = $message; } } } return $a; } public function splitRefs( array $map = null ){ $a = array(); foreach( $this as $message ){ $refs = ltrim( (string) $message->refs ); if( '' !== $refs ){ if( preg_match_all('/\\S+\\.([a-z]+):\\d+/', $refs, $r, PREG_SET_ORDER ) ){ $tmp = array(); foreach( $r as $rr ) { list( $ref, $ext ) = $rr; $tmp[$ext][$ref] = true; } foreach( $tmp as $ext => $refs ){ if( is_array($map) ){ if( isset($map[$ext]) ){ $ext = $map[$ext]; } else { continue; } } $message = clone $message; $message['refs'] = implode(' ',array_keys($refs) ); $a[$ext][] = $message; } } } } return $a; } public function getHashes(){ $a = array(); foreach( $this as $msg ){ $a[] = $msg->getHash(); } sort( $a, SORT_STRING ); return $a; } public function equalSource( LocoPoIterator $that ){ $a = $this->getHashes(); $b = $that->getHashes(); if( count($a) !== count($b) ){ return false; } foreach( $a as $i => $hash ){ if( $hash !== $b[$i] ){ return false; } } return true; } public function sort( $func = null ){ $order = array(); foreach( $this as $msg ){ $order[] = $msg; } if( is_null($func) ){ $func = array( __CLASS__, 'compare' ); } else if( ! is_callable($func) ){ throw new InvalidArgumentException('Bad callback'); } usort( $order, $func ); $po = array(); if( 0 === $this->z ){ $po[] = $this->po[0]; } foreach( $order as $msg ){ $po[] = $msg->getArrayCopy(); if( is_array( $plurals = $msg->plurals ) ){ $index = count($po) - 1; unset( $po[$index]['plurals'] ); foreach( $plurals as $p ){ $a = $p->getArrayCopy(); $a['parent'] = $index; $po[] = $a; } } } $this->po = $po; return $this; } public static function compare( LocoPoMessage $a, LocoPoMessage $b ){ $h = $a->getHash(); $j = $b->getHash(); $n = strcasecmp( $h, $j ); if( 0 === $n ){ $n = strcmp( $h, $j ); if( 0 === $n ){ return 0; } } return $n > 0 ? 1 : -1; } public function createSorter(){ $index = array(); foreach( $this as $i => $msg ){ $index[ $msg->getHash() ] = $i; } $obj = new LocoPoIndex( $index ); return array( $obj, 'compare' ); } } +class LocoMoTable { private $size = 0; private $bin = ''; private $map; public function __construct( $data = null ){ if( is_array($data) ){ $this->compile( $data ); } else if( $data ){ $this->parse( $data ); } } public function count(){ if( ! isset($this->size) ){ if( $this->bin ){ $this->size = (int) ( strlen( $this->bin ) / 4 ); } else if( is_array($this->map) ){ $this->size = count($this->map); } else { return 0; } if( ! self::is_prime($this->size) || $this->size < 3 ){ throw new Exception('Size expected to be prime number above 2, got '.$this->size); } } return $this->size; } public function bytes(){ return $this->count() * 4; } public function __toString(){ return $this->bin; } public function export(){ if( ! is_array($this->map) ){ $this->parse( $this->bin ); } return $this->map; } private function reset( $length ){ $this->size = max( 3, self::next_prime ( $length * 4 / 3 ) ); $this->bin = null; $this->map = array(); return $this->size; } public function compile( array $msgids ){ $hash_tab_size = $this->reset( count($msgids) ); $packed = array_fill( 0, $hash_tab_size, "\0\0\0\0" ); $j = 0; foreach( $msgids as $msgid ){ $hash_val = self::hashpjw( $msgid ); $idx = $hash_val % $hash_tab_size; if( array_key_exists($idx, $this->map) ){ $incr = 1 + ( $hash_val % ( $hash_tab_size - 2 ) ); do { $idx += $incr; if( $hash_val === $idx ){ throw new Exception('Unable to find empty slot in hash table'); } $idx %= $hash_tab_size; } while( array_key_exists($idx, $this->map ) ); } $this->map[$idx] = $j; $packed[$idx] = pack('V', ++$j ); } return $this->bin = implode('',$packed); } public function lookup( $msgid, array $msgids ){ $hash_val = self::hashpjw( $msgid ); $idx = $hash_val % $this->size; $incr = 1 + ( $hash_val % ( $this->size - 2 ) ); while( true ){ if( ! array_key_exists($idx, $this->map) ){ break; } $j = $this->map[$idx]; if( isset($msgids[$j]) && $msgid === $msgids[$j] ){ return $j; } $idx += $incr; if( $idx === $hash_val ){ break; } $idx %= $this->size; } return -1; } public function parse( $bin ){ $this->bin = (string) $bin; $this->size = null; $hash_tab_size = $this->count(); $this->map = array(); $idx = -1; $byte = 0; while( ++$idx < $hash_tab_size ){ $word = substr( $this->bin, $byte, 4 ); if( "\0\0\0\0" !== $word ){ list(,$j) = unpack('V', $word ); $this->map[$idx] = $j - 1; } $byte += 4; } return $this->map; } public static function hashpjw( $str ){ $i = -1; $hval = 0; $len = strlen($str); while( ++$i < $len ){ $ord = ord( substr($str,$i,1) ); $hval = ( $hval << 4 ) + $ord; $g = $hval & 0xf0000000; if( $g !== 0 ){ $hval ^= $g >> 24; $hval ^= $g; } } return $hval; } private static function next_prime( $seed ){ $seed |= 1; while ( ! self::is_prime($seed) ){ $seed += 2; } return $seed; } private static function is_prime( $num ) { if ($num === 1 ){ return false; } if( $num === 2 ){ return true; } if( $num % 2 == 0 ) { return false; } for( $i = 3; $i <= ceil(sqrt($num)); $i = $i + 2) { if($num % $i == 0 ){ return false; } } return true; } } +class LocoMo { private $bin; private $msgs; private $head; private $hash; private $use_fuzzy = false; private $cs; public function __construct( Iterator $export, LocoPoHeaders $head = null ){ if( $head ){ $this->head = $head; } else { $this->head = new LocoPoHeaders(array('Project-Id-Version' => 'Loco')); } $this->msgs = $export; $this->bin = ''; } public function setCharset( $cs ){ $cs = $this->head->setCharset($cs); $this->cs = 'UTF-8' === $cs ? null : $cs; } public function enableHash(){ return $this->hash = new LocoMoTable; } public function useFuzzy(){ $this->use_fuzzy = true; } public function setHeader( $key, $val ){ $this->head->add($key, $val); return $this; } private function str( $s ){ $s = (string) $s; if( $cs = $this->cs ){ $s = mb_convert_encoding($s,$cs,array('UTF-8')); } return $s; } public function compile(){ $table = array(''); $sources = array(''); $targets = array( (string) $this->head ); $fuzzy_flag = 4; $skip_fuzzy = ! $this->use_fuzzy; foreach( $this->msgs as $r ){ if( $skip_fuzzy && isset($r['flag']) && $fuzzy_flag === $r['flag'] ){ continue; } $msgid = $this->str( $r['key'] ); if( isset($r['context']) ){ $msgctxt = $this->str( $r['context'] ); if( '' !== $msgctxt ){ if( '' === $msgid ){ $msgid = '('.$msgctxt.')'; } $msgid = $msgctxt."\x04".$msgid; } } if( '' === $msgid ){ continue; } $msgstr = $this->str( $r['target'] ); if( '' === $msgstr ){ continue; } $table[] = $msgid; if( isset($r['plurals']) ){ foreach( $r['plurals'] as $i => $p ){ if( $i === 0 ){ $msgid .= "\0".$p['key']; } $msgstr .= "\0".$p['target']; } } $sources[] = $msgid; $targets[] = $msgstr; } asort( $sources, SORT_STRING ); $this->bin = "\xDE\x12\x04\x95\x00\x00\x00\x00"; $n = count($sources); $this->writeInteger( $n ); $offset = 28; $this->writeInteger( $offset ); $offset += $n * 8; $this->writeInteger( $offset ); if( $this->hash ){ sort( $table, SORT_STRING ); $this->hash->compile( $table ); $s = $this->hash->count(); } else { $s = 0; } $this->writeInteger( $s ); $offset += $n * 8; $this->writeInteger( $offset ); if( $s ){ $offset += $s * 4; } $source = ''; foreach( $sources as $i => $str ){ $source .= $str."\0"; $this->writeInteger( $strlen = strlen($str) ); $this->writeInteger( $offset ); $offset += $strlen + 1; } $target = ''; foreach( array_keys($sources) as $i ){ $str = $targets[$i]; $target .= $str."\0"; $this->writeInteger( $strlen = strlen($str) ); $this->writeInteger( $offset ); $offset += $strlen + 1; } if( $this->hash ){ $this->bin .= $this->hash->__toString(); } $this->bin .= $source; $this->bin .= $target; return $this->bin; } private function writeInteger( $num ){ $this->bin .= pack( 'V', $num ); return $this; } } +interface LocoTokensInterface extends Iterator { public function advance(); public function ignore( array $a ); } +class LocoTokenizer implements LocoTokensInterface { const T_LITERAL = 0; const T_UNKNOWN = -1; private $src; private $pos; private $line; private $col; private $max; private $rules = array(); private $skip = array(); private $tok; private $len; public function __construct( $src = '' ){ $this->init($src); } public function parse( $src ){ $tokens = array(); $this->init($src); while( $tok = $this->advance() ){ $tokens[] = $tok; } return $tokens; } public function init( $src ){ $this->src = $src; $this->rewind(); return $this; } public function define( $grep, $t = 0 ){ if('^' !== $grep[1] ){ throw new InvalidArgumentException('Expression '.$grep.' isn\'t anchored'); } if( ! is_int($t) && ! is_callable($t) ){ throw new InvalidArgumentException('Non-integer token must be valid callback'); } $sniff = $grep[2]; if( $sniff === preg_quote($sniff,$grep[0]) ){ $this->rules[$sniff][] = array( $grep, $t ); } else { $this->rules[''][] = array( $grep, $t ); } return $this; } public function ignore( array $a ){ foreach( $a as $t ){ $this->skip[$t] = true; } return $this; } public function current(){ return $this->tok; } public function advance(){ $tok = $this->current(); $this->next(); return $tok; } public function next(){ $tok = null; $offset = $this->pos; $column = $this->col; $line = $this->line; while( $offset <= $this->max ){ $t = null; $s = ''; $text = substr($this->src,$offset); foreach( array($text[0],'') as $k ){ if( isset($this->rules[$k]) ) { foreach( $this->rules[$k] as $rule) { if( preg_match($rule[0], $text, $match ) ) { $s = $match[0]; $t = $rule[1]; if( ! is_int($t) ) { $t = call_user_func( $t, $s, $match ); } break 2; } } } } if( is_null($t) ){ $n = preg_match('/^./u',$text,$match); if( false === $n ){ $s = $text[0]; $match = array( mb_convert_encoding($s,'UTF-8','cp1252') ); } $s = (string) $match[0]; $t = self::T_UNKNOWN; } $length = strlen($s); if( 0 === $length ){ throw new Loco_error_ParseException('Failed to match anything'); } $offset += $length; $lines = preg_split('/\\r?\\n/',$s); $nlines = count($lines); if( $nlines > 1 ){ $next_line = $line + ( $nlines - 1 ); $next_column = strlen( end($lines) ); } else { $next_line = $line; $next_column = $column + $length; } if( array_key_exists($t,$this->skip) ){ $line = $next_line; $column = $next_column; continue; } $tok = self::T_LITERAL === $t ? $s : array( $t, $s, $line, $column ); $line = $next_line; $column = $next_column; $this->len++; break; } $this->tok = $tok; $this->pos = $offset; $this->col = $column; $this->line = $line; } public function key(){ return $this->len ? $this->len-1 : null; } public function valid(){ return null !== $this->tok; } public function rewind(){ $this->len = 0; $this->pos = 0; $this->col = 0; $this->line = 1; $this->max = strlen($this->src) - 1; $this->next(); } } +function loco_utf8_chr( $u ){ if( $u < 0x80 ){ if( $u < 0 ){ throw new RangeException( sprintf('%d is out of Unicode range', $u ) ); } return chr($u); } if( $u < 0x800 ) { return chr( ($u>>6) & 0x1F | 0xC0 ).chr( $u & 0x3F | 0x80 ); } if( $u < 0x10000 ) { return chr( $u>>12 & 15 | 0xE0 ).chr( $u>>6 & 0x3F | 0x80 ).chr( $u & 0x3F | 0x80 ); } if( $u < 0x110000 ) { return chr( $u>>18 & 7 | 0xF0 ).chr( $u>>12 & 0x3F | 0x80 ).chr( $u>>6 & 0x3F | 0x80 ).chr( $u & 0x3F | 0x80 ); } throw new RangeException( sprintf('\\x%X is out of Unicode range', $u ) ); } +function loco_resolve_surrogates( $s ){ return preg_replace_callback('/\\xED([\\xA0-\\xAF])([\\x80-\\xBF])\\xED([\\xB0-\\xBF])([\\x80-\\xBF])/', '_loco_resolve_surrogates', $s ); } +function _loco_resolve_surrogates( array $r ){ return loco_utf8_chr ( ( ( ( ( 832 | ( ord($r[1]) & 0x3F ) ) << 6 ) | ( ord($r[2]) & 0x3F ) ) - 0xD800 ) * 0x400 + ( ( ( ( 832 | ( ord($r[3]) & 0x3F ) ) << 6 ) | ( ord($r[4]) & 0x3F ) ) - 0xDC00 ) + 0x10000 ); } +class LocoEscapeParser { private $map; private $grep; public function __construct( array $map = array() ){ $this->map = $map; $rules = array('\\\\'); if( $map ){ $rules[] = '['.implode(array_keys($map)).']'; } if( ! isset($map['U']) ) { $rules[] = 'U[0-9A-Fa-f]{5,8}'; } if( ! isset($map['u']) ) { $rules[] = 'u(?:\\{[0-9A-Fa-f]+\\}|[0-9A-Fa-f]{1,4})(?:\\\\u(?:\\{[0-9A-Fa-f]+\\}|[0-9A-Fa-f]{1,4}))*'; } $this->grep = '/\\\\('.implode('|',$rules).')/'; } public function unescape( $s ){ if( '' !== $s ) { return $this->stripSlashes( preg_replace_callback($this->grep, array($this, 'unescapeMatch'), $s) ); } return ''; } public function unescapeMatch( array $r ){ $s = $r[0]; $c = $s[1]; if( isset($this->map[$c]) ){ return $this->map[$c]; } if( 'u' === $c ){ $str = ''; $surrogates = false; foreach( explode('\\u',$s) as $i => $h ){ if( '' !== $h ){ $h = ltrim( trim($h,'{}'),'0'); $u = intval($h,16); $str.= loco_utf8_chr($u); if( ! $surrogates ){ $surrogates = $u >= 0xD800 && $u <= 0xDBFF; } } } if( $surrogates ){ $str = loco_resolve_surrogates($str); } return $str; } if( 'U' === $c ){ return loco_utf8_chr( intval(substr($s,2),16) ); } if( 'x' === $c ){ return chr( intval(substr($s,2),16) ); } if( ctype_digit($c) ){ return chr( intval(substr($s,1),8) ); } return $s; } protected function stripSlashes( $s ){ return stripcslashes($s); } } +class LocoJsTokens extends LocoTokenizer { const T_KWORD = 1; const T_REGEX = 2; private static $lex; protected static $words = array( 'true' => 1, 'false' => 1, 'null' => 1, 'break' => T_BREAK, 'else' => T_ELSE, 'new' => T_NEW, 'var' => 1, 'case' => T_CASE, 'finally' => T_FINALLY, 'return' => T_RETURN, 'void' => 1, 'catch' => T_CATCH, 'for' => T_FOR, 'switch' => T_SWITCH, 'while' => T_WHILE, 'continue' => T_CONTINUE, 'function' => T_FUNCTION, 'this' => T_STRING, 'with' => 1, 'default' => T_DEFAULT, 'if' => T_IF, 'throw' => T_THROW, 'delete' => 1, 'in' => 1, 'try' => T_TRY, 'do' => T_DO, 'instanceof' => 1, 'typeof' => 1, ); public static function decapse( $encapsed ){ $s = substr($encapsed,1,-1); $l = self::$lex; if( is_null($l) ){ $l = new LocoEscapeParser( array( 'U' => 'U', 'a' => 'a', ) ); self::$lex = $l; } return $l->unescape($s); } public function __construct( $src = '' ){ $this->define('/^(?:\\\\u[0-9A-F]{4,4}|[$_\\pL\\p{Nl}])(?:\\\\u[0-9A-F]{4}|[$_\\pL\\pN\\p{Mn}\\p{Mc}\\p{Pc}])*/ui', array($this,'matchWord') ); $this->define('/^\\s+/u', T_WHITESPACE ); $this->define('!^//.*!', T_COMMENT ); $this->define('!^/\\*.*\\*/!Us', array($this,'matchComment') ); $this->define('/^"(?:\\\\.|[^\\r\\n\\p{Zl}\\p{Zp}"\\\\])*"/u', T_CONSTANT_ENCAPSED_STRING ); $this->define('/^\'(?:\\\\.|[^\\r\\n\\p{Zl}\\p{Zp}\'\\\\])*\'/u', T_CONSTANT_ENCAPSED_STRING ); $this->define('/^[-+;,<>.=:|&^!?*%~(){}[\\]]/'); parent::__construct($src); } public function matchWord( $s ){ if( array_key_exists($s,self::$words) ){ return self::$words[$s]; } return T_STRING; } public function matchComment( $s ){ if( '/**' === substr($s,0,3) ){ return T_DOC_COMMENT; } return T_COMMENT; } } +class LocoExtracted implements Countable { private $exp = array(); private $reg = array(); private $dom = array(); private $dflt = ''; public function extractSource( LocoExtractor $ext, $src, $fileref = '' ){ $ext->extract( $this, $ext->tokenize($src), $fileref ); return $this; } public function export(){ return $this->exp; } public function count(){ return count( $this->exp ); } public function getDomainCounts(){ return $this->dom; } public function setDomain( $default ){ $this->dflt = (string) $default; return $this; } public function getDomain(){ return $this->dflt; } public function pushMeta( $source, $notes = '', $domain = null ){ if( ! $domain || '*' === $domain ){ $domain = $this->dflt; } $entry = array( 'id' => '', 'source' => $source, 'target' => '', 'notes' => $notes, ); if( $domain ){ $entry['domain'] = $domain; $key = $source."\1".$domain; } else { $key = $source; } return $this->pushMsgid( $key, $entry, $domain ); } public function pushMsgid( $key, array $entry, $domain ){ if( isset($this->reg[$key]) ){ $index = $this->reg[$key]; $clash = $this->exp[$index]; if( $value = $this->mergeField( $clash, $entry, 'refs', ' ') ){ $this->exp[$index]['refs'] = $value; } if( $value = $this->mergeField( $clash, $entry, 'notes', "\n") ){ $this->exp[$index]['notes'] = $value; } } else { $index = count($this->exp); $this->reg[$key] = $index; $this->exp[$index] = $entry; if( isset($this->dom[$domain]) ){ $this->dom[$domain]++; } else { $this->dom[$domain] = 1; } } return $index; } public function pushMsgidPlural( $key, array $entry ){ $key = $key."\2"; if( ! isset($this->reg[$key]) ){ $index = count($this->exp); $this->reg[$key] = $index; $this->exp[$index] = $entry; if( isset($entry['format']) ){ $index = $entry['parent']; if( ! isset($this->exp[$index]['format']) ) { $this->exp[$index]['format'] = $entry['format']; } } } } public function mergeField( array $old, array $new, $field, $glue ){ $prev = isset($old[$field]) ? $old[$field] : ''; if( isset($new[$field]) ){ $text = $new[$field]; if( '' !== $prev && $prev !== $text ){ if( 'notes' === $field && preg_match( '/^'.preg_quote( rtrim($text,'. '),'/').'[. ]*$/mu', $prev ) ) { $text = $prev; } else { $text = $prev.$glue.$text; } } return $text; } return $prev; } public function filter( $domain ){ $map = array(); $newOffset = 1; $matchAll = '*' === $domain; $raw = array( array( 'id' => '', 'source' => '', 'target' => '', 'domain' => $matchAll ? '' : $domain, ) ); foreach( $this->exp as $oldOffset => $r ){ if( isset($r['parent']) ){ if( isset($map[$r['parent']]) ){ $r['parent'] = $map[ $r['parent'] ]; $raw[ $newOffset++ ] = $r; } } else { if( $matchAll ){ $match = true; } else if( isset($r['domain']) ){ $match = $domain === $r['domain']; } else { $match = $domain === ''; } if( $match ){ $map[ $oldOffset ] = $newOffset; $raw[ $newOffset++ ] = $r; } } } return $raw; } } +abstract class LocoExtractor { private $rules; private $wp = array(); private $domain; abstract public function tokenize( $src ); abstract public function extract( LocoExtracted $strings, LocoTokensInterface $tokens, $fileref = '' ); abstract protected function fsniff( $str ); abstract protected function decapse( $raw ); abstract protected function comment( $comment ); public function __construct( array $rules ){ $this->rules = $rules; } public function setDomain( $default ){ $this->domain = $default; return $this; } public function headerize( array $tags, $domain = '' ){ if( isset($this->wp[$domain]) ){ $this->wp[$domain] += $tags; } else { $this->wp[$domain] = $tags; } return $this; } protected function getHeaders(){ return $this->wp; } final public function extractSource( $src, $fileref ){ $strings = new LocoExtracted; $this->extract( $strings, $this->tokenize($src), $fileref ); return $strings; } public function rule( $s ){ return isset($this->rules[$s]) ? $this->rules[$s] : ''; } protected function push( LocoExtracted $strings, $rule, array $args, $comment = '', $ref = '' ){ $s = strpos( $rule, 's'); $p = strpos( $rule, 'p'); $c = strpos( $rule, 'c'); $d = strpos( $rule, 'd'); if( false === $s || ! isset($args[$s]) ){ return null; } $key = $args[$s]; if( ! is_string($key) ){ return null; } $msgid = $key; $entry = array( 'id' => '', 'source' => $msgid, 'target' => '', ); if( is_int($c) && isset($args[$c]) ){ $entry['context'] = $context = $args[$c]; $key .= "\0". $context; } else if( '' === $msgid ){ return null; } else { $context = null; } if( $ref ){ $entry['refs'] = $ref; } if( is_int($d) && array_key_exists($d,$args) ){ $domain = $args[$d]; if( is_null($domain) ){ $domain = ''; } } else { $domain = $this->domain or $domain = $strings->getDomain(); } if( is_string($domain) && '' !== $domain ){ $entry['domain'] = $domain; $key .= "\1".$domain; } $parse_printf = true; if( $comment = $this->comment($comment) ){ if( preg_match('/^xgettext:\\s*([-a-z]+)-format\\s*/mi', $comment, $r, PREG_OFFSET_CAPTURE ) ){ $entry['format'] = $r[1][0]; $comment = trim( substr_replace( $comment,'', $r[0][1], strlen($r[0][0]) ) ); $parse_printf = ( 'no-' === substr($entry['format'],0,3) ) ? false : null; } if( preg_match('/^references?:( *.+:\\d+)*\\s*/mi', $comment, $r, PREG_OFFSET_CAPTURE ) ){ $entry['refs'] = trim($r[1][0],' '); $comment = trim( substr_replace( $comment, '', $r[0][1], strlen($r[0][0]) ) ); } $entry['notes'] = $comment; } if( $parse_printf && ( $format = $this->fsniff($msgid) ) ){ $entry['format'] = $format; } $index = $strings->pushMsgid( $key, $entry, $domain ); if( is_int($p) && isset($args[$p]) ){ $msgid_plural = $args[$p]; $entry = array( 'id' => '', 'source' => $msgid_plural, 'target' => '', 'plural' => 1, 'parent' => $index, ); if( false !== $parse_printf && ( $format = $this->fsniff($msgid_plural) ) ){ $entry['format'] = $format; } $strings->pushMsgidPlural( $key, $entry ); } return $index; } } +class LocoPHPTokens implements LocoTokensInterface, Countable { private $i; private $tokens; private $skip_tokens = array(); private $literal_tokens = array(); public function __construct( array $tokens ){ $this->tokens = $tokens; $this->rewind(); } public function literal( array $a ){ foreach( $a as $t ){ $this->literal_tokens[ $t ] = 1; } return $this; } public function ignore( array $a ){ foreach( $a as $t ){ $this->skip_tokens[$t] = true; } return $this; } public function export(){ $arr = array(); $this->rewind(); while( $tok = $this->advance() ){ $arr[] = $tok; } return $arr; } public function advance(){ $tok = $this->current(); $this->next(); return $tok; } public function rewind(){ $this->i = ( false === reset($this->tokens) ? null : key($this->tokens) ); } public function valid(){ while( isset($this->i) ){ $tok = $this->tokens[$this->i]; if( array_key_exists( is_array($tok) ? $tok[0] : $tok, $this->skip_tokens ) ){ $this->next(); } else { return true; } } return false; } public function key(){ return $this->i; } public function next(){ $this->i = ( false === next($this->tokens) ? null : key($this->tokens) ); } public function current(){ if( ! $this->valid() ){ return false; } $tok = $this->tokens[$this->i]; if( is_array($tok) && isset($this->literal_tokens[$tok[0]]) ){ return $tok[1]; } return $tok; } public function __toString(){ $s = array(); foreach( $this as $token ){ $s[] = is_array($token) ? $token[1] : $token; } return implode('',$s); } public function count(){ return count($this->tokens); } } +class LocoPHPEscapeParser extends LocoEscapeParser { public function __construct(){ parent::__construct( array( 'n' => "\n", 'r' => "\r", 't' => "\t", 'v' => "\x0B", 'f' => "\x0C", 'e' => "\x1B", '$' => '$', '\\' => '\\', '"' => '"', ) ); } protected function stripSlashes( $s ){ return preg_replace_callback('/\\\\(x[0-9A-Fa-f]{1,2}|[0-3]?[0-7]{1,2})/', array($this,'unescapeMatch'), $s, -1, $n ); } } +function loco_unescape_php_string( $s ){ static $l; if( is_null($l) ) { $l = new LocoPHPEscapeParser; } return $l->unescape($s); } +function loco_decapse_php_string( $s ){ if( ! $s ){ return (string) $s; } $q = $s[0]; if( "'" === $q ){ return str_replace( array('\\'.$q, '\\\\'), array($q, '\\'), substr( $s, 1, -1 ) ); } if( '"' !== $q ){ return $s; } return loco_unescape_php_string( substr($s,1,-1) ); } +function loco_parse_php_comment($comment){ $comment = trim( $comment,"/ \n\r\t" ); if( '' !== $comment && '*' === $comment[0] ){ $lines = array(); $junk = "\r\t/ *"; foreach( explode("\n",$comment) as $line ){ $line = trim($line,$junk); if( '' !== $line ){ $lines[] = $line; } } $comment = implode("\n", $lines); } return $comment; } +function loco_parse_wp_comment( $block ){ $header = array(); if( '*' === $block[1] ){ $junk = "\r\t/ *"; foreach( explode("\n", $block) as $line ){ if( false !== ( $i = strpos($line,':') ) ){ $key = substr($line,0,$i); $val = substr($line,++$i); $header[ trim($key,$junk) ] = trim($val,$junk); } } } return $header; } +function loco_sniff_printf( $s, $p, $limit = 0, $offset = 0 ){ $n = 0; while( is_string($s) && '' !== $s && false !== ( $i = strpos($s,'%',$offset) ) ){ if( 0 !== $i ){ $s = substr( $s, $i ); } if( preg_match( $p, $s, $r ) ){ $match = $r[0]; if( 0 < $n && isset($r[1]) && '' === $r[1] && '%' !== substr($match,-1) ){ return 0; } if( ++$n === $limit ){ break; } $offset = strlen($match); } else { return 0; } } return $n; } +function loco_sniff_php_printf( $s, $limit = 0 ){ return loco_sniff_printf( $s, '/^%(?:[1-9]\\d*\\$)?(?:\'.|[-+0 ])*\\d*(?:\\.\\d+)?[suxXbcdeEfFgGo%]/', $limit ); } +class LocoPHPExtractor extends LocoExtractor { private $defs = array(); public function tokenize( $src ){ return new LocoPHPTokens( token_get_all($src) ); } public function decapse( $raw ){ return loco_decapse_php_string( $raw ); } public function fsniff( $str ){ return loco_sniff_php_printf($str) ? 'php' : ''; } protected function comment( $comment ){ $comment = loco_parse_php_comment($comment); $comment = preg_replace('/^translators:\\s+/mi', '', $comment ); return $comment; } public function define( $name, $value ){ if( is_string($value) ){ $this->defs[$name] = $value; } return $this; } public function extract( LocoExtracted $strings, LocoTokensInterface $tokens, $fileref = '' ){ $tokens->ignore( array(T_WHITESPACE) ); $n = 0; $depth = 0; $comment = ''; $narg = 0; $args = array(); $ref = ''; $rule = ''; $wp = $this->getHeaders(); $tokens->rewind(); while( $tok = $tokens->advance() ){ if( is_string($tok) ){ $s = $tok; $t = null; } else { $t = $tok[0]; $s = $tok[1]; } if( $depth ){ if( ')' === $s || ']' === $s ){ if( 0 === --$depth ){ if( $this->push( $strings, $rule, $args, $comment, $ref ) ){ $n++; } $comment = ''; } } else if( '(' === $s || '[' === $s ){ $depth++; $args[$narg] = null; } else if( 1 === $depth ){ if( ',' === $s ){ $narg++; } else if( T_CONSTANT_ENCAPSED_STRING === $t ){ $args[$narg] = $this->decapse($s); } else if( T_STRING === $t && array_key_exists($s,$this->defs) ){ $args[$narg] = $this->defs[$s]; } else { $args[$narg] = null; } } } else if( T_COMMENT === $t || T_DOC_COMMENT === $t ){ $was_header = false; if( 0 === $n ){ if( false !== strpos($s,'* @package') ){ $was_header = true; } if( $wp && ( $header = loco_parse_wp_comment($s) ) ){ foreach( $wp as $domain => $tags ){ foreach( array_intersect_key($header,$tags) as $tag => $source ){ $strings->pushMeta( $source, $tags[$tag], $domain ); $was_header = true; } } } } if( ! $was_header ) { $comment = $s; } } else if( T_STRING === $t && '(' === $tokens->advance() && ( $rule = $this->rule($s) ) ){ $ref = $fileref ? $fileref.':'.$tok[2]: ''; $depth = 1; $args = array(); $narg = 0; } else if( $comment ){ if( false === stripos($comment, 'translators:') && false === strpos($comment, 'xgettext:') ){ $comment = ''; } } } return $this; } } +function loco_sniff_js_printf( $s, $limit = 0 ){ return loco_sniff_printf( $s, '/^%(?:[1-9]\\d*\\$)?\\+?(?:0|\'[^$])?-?\\d*(?:\\.\\d+)?[b-gijostTuvxX%]/', $limit ); } +class LocoJsExtractor extends LocoPHPExtractor { public function tokenize( $src ){ return new LocoJsTokens($src); } public function fsniff( $str ){ return loco_sniff_js_printf($str) ? 'javascript' : ''; } public function decapse( $encapsed ){ return LocoJsTokens::decapse($encapsed); } } +class LocoTwigExtractor extends LocoPHPExtractor { public function tokenize( $src ){ $src = ' 'sd', '_e' => 'sd', '_c' => 'sd', '_n' => 'sp_d', '_n_noop' => 'spd', '_nc' => 'sp_d', '__ngettext' => 'spd', '__ngettext_noop' => 'spd', '_x' => 'scd', '_ex' => 'scd', '_nx' => 'sp_cd', '_nx_noop' => 'spcd', 'esc_attr__' => 'sd', 'esc_html__' => 'sd', 'esc_attr_e' => 'sd', 'esc_html_e' => 'sd', 'esc_attr_x' => 'scd', 'esc_html_x' => 'scd', ); if( 'php' === $type ){ $extr = new LocoPHPExtractor($rules); } else if( 'twig' === $type ){ $extr = new LocoTwigExtractor($rules); } else if( 'js' === $type ){ $extr = new LocoJsExtractor($rules); } else { throw new InvalidArgumentException('No string extractor for '.$type); } return $extr; } +function loco_print_percent( $n, $t ){ $s = loco_string_percent( (int) $n, (int) $t ); echo $s,'%'; return ''; } +function loco_print_progress( $translated, $untranslated, $flagged ){ $total = $translated + $untranslated; $complete = loco_string_percent( $translated - $flagged, $total ); $class = 'progress'; if( ! $translated && ! $flagged ){ $class .= ' empty'; } else if( '100' === $complete ){ $class .= ' done'; } echo '
'; if( $flagged ){ $s = loco_string_percent( $flagged, $total ); echo '
 
'; } if( '0' === $complete ){ echo ' '; } else { $class = 'bar p'; $p = (int) $complete; $class .= sprintf(' p-%u', 10*floor($p/10) ); $style = 'width:'.$complete.'%'; if( $flagged ){ $remain = 100.0 - (float) $s; $style .= '; max-width: '.sprintf('%s',$remain).'%'; } echo '
 
'; } echo '
',$complete,'%
'; return ''; } +function loco_string_percent( $n, $t ){ if( ! $t || ! $n ){ $s = '0'; } else if( $t === $n ){ $s = '100'; } else { $dp = 0; $n = 100 * $n / $t; if( $n > 99 ){ $s = number_format( min( $n, 99.9 ), ++$dp ); } else if( $n < 0.5 ){ $n = max( $n, 0.0001 ); do { $s = number_format( $n, ++$dp ); } while( preg_match('/^0\\.0+$/',$s) && $dp < 4 ); $s = substr($s,1); } else { $s = number_format( $n, $dp ); } } return $s; } +defined('T_FINALLY') || define('T_FINALLY',500); diff --git a/vendor/loco-translate/lib/compiled/locales.php b/vendor/loco-translate/lib/compiled/locales.php new file mode 100644 index 0000000..73f8e30 --- /dev/null +++ b/vendor/loco-translate/lib/compiled/locales.php @@ -0,0 +1,5 @@ + strtolower( $tags[1] ), ); if( isset($tags[2]) && ( $subtag = $tags[2] ) ){ $data['region'] = strtoupper($tags[2]); } if( isset($tags[3]) && ( $subtag = $tags[3] ) ){ $data['variant'] = strtolower($tags[3]); } return $data; } diff --git a/vendor/loco-translate/lib/compiled/phpunit.php b/vendor/loco-translate/lib/compiled/phpunit.php new file mode 100644 index 0000000..a1ab402 --- /dev/null +++ b/vendor/loco-translate/lib/compiled/phpunit.php @@ -0,0 +1,6 @@ +preserveWhitespace = true; $dom->formatOutput = false; $source = ''.$source.''; $used_errors = libxml_use_internal_errors(true); $opts = LIBXML_HTML_NODEFDTD; $parsed = $dom->loadHTML( $source, $opts ); $errors = libxml_get_errors(); $used_errors || libxml_use_internal_errors(false); libxml_clear_errors(); if( $errors || ! $parsed ){ $e = new Loco_error_ParseException('Unknown parse error'); foreach( $errors as $error ){ $e = new Loco_error_ParseException( trim($error->message) ); $e->setContext( $error->line, $error->column, $source ); if( LIBXML_ERR_FATAL === $error->level ){ throw $e; } } if( ! $parsed ){ throw $e; } } return $dom; } public function __construct( $value ){ if( $value instanceof DOMDocument ){ $value = array( $value->documentElement ); } else if( $value instanceof DOMNode ){ $value = array( $value ); } if( is_iterable($value) ){ $nodes = array(); foreach( $value as $node ){ $nodes[] = $node; } } else if( is_string($value) || method_exists($value,'__toString') ){ $value = self::parse( $value ); $nodes = array( $value->documentElement ); } else { $type = is_object($value) ? get_class($value) : gettype($value); throw new InvalidArgumentException('Cannot construct DOM from '.$type ); } parent::__construct( $nodes ); } public function eq( $index ){ $q = new LocoDomQuery(array()); if( $el = $this[$index] ){ $q[] = $el; } return $q; } public function find( $value ){ $q = new LocoDomQuery( array() ); $f = new _LocoDomQueryFilter($value); foreach( $this as $el ){ foreach( $f->filter($el) as $match ){ $q[] = $match; } } return $q; } public function children(){ $q = new LocoDomQuery(array()); foreach( $this as $el ){ if( $el instanceof DOMNode ){ foreach( $el->childNodes as $child ) { $q[] = $child; } } } return $q; } public function text(){ $s = ''; foreach( $this as $el ){ $s .= $el->textContent; } return $s; } public function html(){ $s = ''; foreach( $this as $outer ){ foreach( $outer->childNodes as $inner ){ $s .= $inner->ownerDocument->saveXML($inner); } break; } return $s; } public function attr( $name ){ foreach( $this as $el ){ return $el->getAttribute($name); } return null; } public function serialize(){ $pairs = array(); foreach( array('input','select','textarea','button') as $type ){ foreach( $this->find($type) as $field ){ $name = $field->getAttribute('name'); if( ! $name ){ continue; } if( $field->hasAttribute('type') ){ $type = $field->getAttribute('type'); } if( 'select' === $type ){ $value = null; $f = new _LocoDomQueryFilter('option'); foreach( $f->filter($field) as $option ){ if( $option->hasAttribute('value') ){ $_value = $option->getAttribute('value'); } else { $_value = $option->nodeValue; } if( $option->hasAttribute('selected') ){ $value = $_value; break; } else if( is_null($value) ){ $value = $_value; } } if( is_null($value) ){ $value = ''; } } else if( 'checkbox' === $type || 'radio' === $type ){ if( $field->hasAttribute('checked') ){ $value = $field->getAttribute('value'); } else { continue; } } else if( 'file' === $type ){ $value = ''; } else if( $field->hasAttribute('value') ){ $value = $field->getAttribute('value'); } else { $value = $field->textContent; } $pairs[] = sprintf('%s=%s', rawurlencode($name), rawurlencode($value) ); } } return implode('&',$pairs); } } +class _LocoDomQueryFilter { private $tag; private $attr = array(); public function __construct( $value ){ $id = '[-_a-z][-_a-z0-9]*'; if( ! preg_match('/^([a-z1-6]*)(#'.$id.')?(\.'.$id.')?(\[(\w+)="(.+)"\])?$/i', $value, $r ) ){ throw new InvalidArgumentException('Bad filter, '.$value ); } if( $r[1] ){ $this->tag = $r[1]; } if( ! empty($r[2]) ){ $this->attr['id'] = substr($r[2],1); } if( ! empty($r[3]) ){ $this->attr['class'] = substr($r[3],1); } if( ! empty($r[4]) ){ $this->attr[ $r[5] ] = $r[6]; } } public function filter( DOMElement $el ){ if( $this->tag ){ $list = $el->getElementsByTagName($this->tag); $recursive = false; } else { $list = $el->childNodes; $recursive = true; } if( $this->attr ){ $list = $this->reduce( $list, new ArrayIterator, $recursive )->getArrayCopy(); } return $list; } public function reduce( DOMNodeList $list, ArrayIterator $reduced, $recursive ){ foreach( $list as $node ){ if( $node instanceof DOMElement ){ $matched = false; foreach( $this->attr as $name => $value ){ if( ! $node->hasAttribute($name) ){ $matched = false; break; } $values = array_flip( explode(' ', $node->getAttribute($name) ) ); if( ! isset($values[$value]) ){ $matched = false; break; } $matched = true; } if( $matched ){ $reduced[] = $node; } if( $recursive && $node->hasChildNodes() ){ $this->reduce( $node->childNodes, $reduced, true ); } } } return $reduced; } } diff --git a/vendor/loco-translate/lib/data/languages.php b/vendor/loco-translate/lib/data/languages.php new file mode 100644 index 0000000..4264415 --- /dev/null +++ b/vendor/loco-translate/lib/data/languages.php @@ -0,0 +1,5 @@ +'Afar','ab'=>'Abkhazian','ae'=>'Avestan','af'=>'Afrikaans','ak'=>'Akan','am'=>'Amharic','an'=>'Aragonese','ar'=>'Arabic','arq'=>'Algerian Arabic','ary'=>'Moroccan Arabic','as'=>'Assamese','ast'=>'Asturian','av'=>'Avaric','ay'=>'Aymara','az'=>'Azerbaijani','azb'=>'South Azerbaijani','ba'=>'Bashkir','bal'=>'Baluchi','bcc'=>'Southern Balochi','be'=>'Belarusian','bg'=>'Bulgarian','bi'=>'Bislama','bm'=>'Bambara','bn'=>'Bengali','bo'=>'Tibetan','br'=>'Breton','bs'=>'Bosnian','ca'=>'Catalan','ce'=>'Chechen','ceb'=>'Cebuano','ch'=>'Chamorro','ckb'=>'Central Kurdish','co'=>'Corsican','cr'=>'Cree','cs'=>'Czech','cu'=>'Church Slavic','cv'=>'Chuvash','cy'=>'Welsh','da'=>'Danish','de'=>'German','dv'=>'Dhivehi','dz'=>'Dzongkha','ee'=>'Ewe','el'=>'Greek','en'=>'English','eo'=>'Esperanto','es'=>'Spanish','et'=>'Estonian','eu'=>'Basque','fa'=>'Persian','ff'=>'Fulah','fi'=>'Finnish','fj'=>'Fijian','fo'=>'Faroese','fr'=>'French','frp'=>'Arpitan','fuc'=>'Pulaar','fur'=>'Friulian','fy'=>'Western Frisian','ga'=>'Irish','gd'=>'Scottish Gaelic','gl'=>'Galician','gn'=>'Guarani','gsw'=>'Swiss German','gu'=>'Gujarati','gv'=>'Manx','ha'=>'Hausa','haw'=>'Hawaiian','haz'=>'Hazaragi','he'=>'Hebrew','hi'=>'Hindi','ho'=>'Hiri Motu','hr'=>'Croatian','ht'=>'Haitian','hu'=>'Hungarian','hy'=>'Armenian','hz'=>'Herero','ia'=>'Interlingua','id'=>'Indonesian','ie'=>'Interlingue','ig'=>'Igbo','ii'=>'Sichuan Yi','ik'=>'Inupiaq','io'=>'Ido','is'=>'Icelandic','it'=>'Italian','iu'=>'Inuktitut','ja'=>'Japanese','jv'=>'Javanese','ka'=>'Georgian','kab'=>'Kabyle','kg'=>'Kongo','ki'=>'Kikuyu','kj'=>'Kuanyama','kk'=>'Kazakh','kl'=>'Kalaallisut','km'=>'Central Khmer','kn'=>'Kannada','ko'=>'Korean','kr'=>'Kanuri','ks'=>'Kashmiri','ku'=>'Kurdish','kv'=>'Komi','kw'=>'Cornish','ky'=>'Kirghiz','la'=>'Latin','lb'=>'Luxembourgish','lg'=>'Ganda','li'=>'Limburgan','ln'=>'Lingala','lo'=>'Lao','lt'=>'Lithuanian','lu'=>'Luba-Katanga','lv'=>'Latvian','mg'=>'Malagasy','mh'=>'Marshallese','mi'=>'Maori','mk'=>'Macedonian','ml'=>'Malayalam','mn'=>'Mongolian','mr'=>'Marathi','ms'=>'Malay','mt'=>'Maltese','my'=>'Burmese','na'=>'Nauru','nb'=>'Norwegian Bokmål','nd'=>'North Ndebele','ne'=>'Nepali','ng'=>'Ndonga','nl'=>'Dutch','nn'=>'Norwegian Nynorsk','no'=>'Norwegian','nr'=>'South Ndebele','nv'=>'Navajo','ny'=>'Nyanja','oc'=>'Occitan (post 1500)','oj'=>'Ojibwa','om'=>'Oromo','or'=>'Oriya','ory'=>'Oriya (individual language)','os'=>'Ossetian','pa'=>'Panjabi','pi'=>'Pali','pl'=>'Polish','ps'=>'Pushto','pt'=>'Portuguese','qu'=>'Quechua','rhg'=>'Rohingya','rm'=>'Romansh','rn'=>'Rundi','ro'=>'Romanian','ru'=>'Russian','rue'=>'Rusyn','rup'=>'Macedo-Romanian','rw'=>'Kinyarwanda','sa'=>'Sanskrit','sah'=>'Yakut','sc'=>'Sardinian','sd'=>'Sindhi','se'=>'Northern Sami','sg'=>'Sango','sh'=>'Serbo-Croatian','si'=>'Sinhala','sk'=>'Slovak','sl'=>'Slovenian','sm'=>'Samoan','sn'=>'Shona','so'=>'Somali','sq'=>'Albanian','sr'=>'Serbian','ss'=>'Swati','st'=>'Southern Sotho','su'=>'Sundanese','sv'=>'Swedish','sw'=>'Swahili','szl'=>'Silesian','ta'=>'Tamil','te'=>'Telugu','tg'=>'Tajik','th'=>'Thai','ti'=>'Tigrinya','tk'=>'Turkmen','tl'=>'Tagalog','tn'=>'Tswana','to'=>'Tonga (Tonga Islands)','tr'=>'Turkish','ts'=>'Tsonga','tt'=>'Tatar','tw'=>'Twi','twd'=>'Twents','ty'=>'Tahitian','tzm'=>'Central Atlas Tamazight','ug'=>'Uighur','uk'=>'Ukrainian','ur'=>'Urdu','uz'=>'Uzbek','ve'=>'Venda','vi'=>'Vietnamese','vo'=>'Volapük','wa'=>'Walloon','wo'=>'Wolof','xh'=>'Xhosa','xmf'=>'Mingrelian','yi'=>'Yiddish','yo'=>'Yoruba','za'=>'Zhuang','zh'=>'Chinese','zu'=>'Zulu','tlh'=>'Klingon'); diff --git a/vendor/loco-translate/lib/data/locales.php b/vendor/loco-translate/lib/data/locales.php new file mode 100644 index 0000000..81131b4 --- /dev/null +++ b/vendor/loco-translate/lib/data/locales.php @@ -0,0 +1,5 @@ +array(0=>'Afrikaans',1=>'Afrikaans'),'ar'=>array(0=>'Arabic',1=>'العربية'),'ary'=>array(0=>'Moroccan Arabic',1=>'العربية المغربية'),'as'=>array(0=>'Assamese',1=>'অসমীয়া'),'az'=>array(0=>'Azerbaijani',1=>'Azərbaycan dili'),'azb'=>array(0=>'South Azerbaijani',1=>'گؤنئی آذربایجان'),'bel'=>array(0=>'Belarusian',1=>'Беларуская мова'),'bg_BG'=>array(0=>'Bulgarian',1=>'Български'),'bn_BD'=>array(0=>'Bengali (Bangladesh)',1=>'বাংলা'),'bo'=>array(0=>'Tibetan',1=>'བོད་ཡིག'),'bs_BA'=>array(0=>'Bosnian',1=>'Bosanski'),'ca'=>array(0=>'Catalan',1=>'Català'),'ceb'=>array(0=>'Cebuano',1=>'Cebuano'),'cs_CZ'=>array(0=>'Czech',1=>'Čeština'),'cy'=>array(0=>'Welsh',1=>'Cymraeg'),'da_DK'=>array(0=>'Danish',1=>'Dansk'),'de_DE_formal'=>array(0=>'German (Formal)',1=>'Deutsch (Sie)'),'de_CH'=>array(0=>'German (Switzerland)',1=>'Deutsch (Schweiz)'),'de_CH_informal'=>array(0=>'German (Switzerland, Informal)',1=>'Deutsch (Schweiz, Du)'),'de_DE'=>array(0=>'German',1=>'Deutsch'),'dzo'=>array(0=>'Dzongkha',1=>'རྫོང་ཁ'),'el'=>array(0=>'Greek',1=>'Ελληνικά'),'en_GB'=>array(0=>'English (UK)',1=>'English (UK)'),'en_ZA'=>array(0=>'English (South Africa)',1=>'English (South Africa)'),'en_CA'=>array(0=>'English (Canada)',1=>'English (Canada)'),'en_AU'=>array(0=>'English (Australia)',1=>'English (Australia)'),'en_NZ'=>array(0=>'English (New Zealand)',1=>'English (New Zealand)'),'eo'=>array(0=>'Esperanto',1=>'Esperanto'),'es_GT'=>array(0=>'Spanish (Guatemala)',1=>'Español de Guatemala'),'es_ES'=>array(0=>'Spanish (Spain)',1=>'Español'),'es_AR'=>array(0=>'Spanish (Argentina)',1=>'Español de Argentina'),'es_CL'=>array(0=>'Spanish (Chile)',1=>'Español de Chile'),'es_MX'=>array(0=>'Spanish (Mexico)',1=>'Español de México'),'es_CO'=>array(0=>'Spanish (Colombia)',1=>'Español de Colombia'),'es_VE'=>array(0=>'Spanish (Venezuela)',1=>'Español de Venezuela'),'es_CR'=>array(0=>'Spanish (Costa Rica)',1=>'Español de Costa Rica'),'es_PE'=>array(0=>'Spanish (Peru)',1=>'Español de Perú'),'et'=>array(0=>'Estonian',1=>'Eesti'),'eu'=>array(0=>'Basque',1=>'Euskara'),'fa_IR'=>array(0=>'Persian',1=>'فارسی'),'fi'=>array(0=>'Finnish',1=>'Suomi'),'fr_BE'=>array(0=>'French (Belgium)',1=>'Français de Belgique'),'fr_CA'=>array(0=>'French (Canada)',1=>'Français du Canada'),'fr_FR'=>array(0=>'French (France)',1=>'Français'),'fur'=>array(0=>'Friulian',1=>'Friulian'),'gd'=>array(0=>'Scottish Gaelic',1=>'Gàidhlig'),'gl_ES'=>array(0=>'Galician',1=>'Galego'),'gu'=>array(0=>'Gujarati',1=>'ગુજરાતી'),'haz'=>array(0=>'Hazaragi',1=>'هزاره گی'),'he_IL'=>array(0=>'Hebrew',1=>'עִבְרִית'),'hi_IN'=>array(0=>'Hindi',1=>'हिन्दी'),'hr'=>array(0=>'Croatian',1=>'Hrvatski'),'hu_HU'=>array(0=>'Hungarian',1=>'Magyar'),'hy'=>array(0=>'Armenian',1=>'Հայերեն'),'id_ID'=>array(0=>'Indonesian',1=>'Bahasa Indonesia'),'is_IS'=>array(0=>'Icelandic',1=>'Íslenska'),'it_IT'=>array(0=>'Italian',1=>'Italiano'),'ja'=>array(0=>'Japanese',1=>'日本語'),'jv_ID'=>array(0=>'Javanese',1=>'Basa Jawa'),'ka_GE'=>array(0=>'Georgian',1=>'ქართული'),'kab'=>array(0=>'Kabyle',1=>'Taqbaylit'),'kk'=>array(0=>'Kazakh',1=>'Қазақ тілі'),'km'=>array(0=>'Khmer',1=>'ភាសាខ្មែរ'),'ko_KR'=>array(0=>'Korean',1=>'한국어'),'ckb'=>array(0=>'Kurdish (Sorani)',1=>'كوردی‎'),'lo'=>array(0=>'Lao',1=>'ພາສາລາວ'),'lt_LT'=>array(0=>'Lithuanian',1=>'Lietuvių kalba'),'lv'=>array(0=>'Latvian',1=>'Latviešu valoda'),'mk_MK'=>array(0=>'Macedonian',1=>'Македонски јазик'),'ml_IN'=>array(0=>'Malayalam',1=>'മലയാളം'),'mn'=>array(0=>'Mongolian',1=>'Монгол'),'mr'=>array(0=>'Marathi',1=>'मराठी'),'ms_MY'=>array(0=>'Malay',1=>'Bahasa Melayu'),'my_MM'=>array(0=>'Myanmar (Burmese)',1=>'ဗမာစာ'),'nb_NO'=>array(0=>'Norwegian (Bokmål)',1=>'Norsk bokmål'),'ne_NP'=>array(0=>'Nepali',1=>'नेपाली'),'nl_BE'=>array(0=>'Dutch (Belgium)',1=>'Nederlands (België)'),'nl_NL_formal'=>array(0=>'Dutch (Formal)',1=>'Nederlands (Formeel)'),'nl_NL'=>array(0=>'Dutch',1=>'Nederlands'),'nn_NO'=>array(0=>'Norwegian (Nynorsk)',1=>'Norsk nynorsk'),'oci'=>array(0=>'Occitan',1=>'Occitan'),'pa_IN'=>array(0=>'Punjabi',1=>'ਪੰਜਾਬੀ'),'pl_PL'=>array(0=>'Polish',1=>'Polski'),'ps'=>array(0=>'Pashto',1=>'پښتو'),'pt_BR'=>array(0=>'Portuguese (Brazil)',1=>'Português do Brasil'),'pt_PT_ao90'=>array(0=>'Portuguese (Portugal, AO90)',1=>'Português (AO90)'),'pt_PT'=>array(0=>'Portuguese (Portugal)',1=>'Português'),'rhg'=>array(0=>'Rohingya',1=>'Ruáinga'),'ro_RO'=>array(0=>'Romanian',1=>'Română'),'ru_RU'=>array(0=>'Russian',1=>'Русский'),'sah'=>array(0=>'Sakha',1=>'Сахалыы'),'si_LK'=>array(0=>'Sinhala',1=>'සිංහල'),'sk_SK'=>array(0=>'Slovak',1=>'Slovenčina'),'sl_SI'=>array(0=>'Slovenian',1=>'Slovenščina'),'sq'=>array(0=>'Albanian',1=>'Shqip'),'sr_RS'=>array(0=>'Serbian',1=>'Српски језик'),'sv_SE'=>array(0=>'Swedish',1=>'Svenska'),'szl'=>array(0=>'Silesian',1=>'Ślōnskŏ gŏdka'),'ta_IN'=>array(0=>'Tamil',1=>'தமிழ்'),'te'=>array(0=>'Telugu',1=>'తెలుగు'),'th'=>array(0=>'Thai',1=>'ไทย'),'tl'=>array(0=>'Tagalog',1=>'Tagalog'),'tr_TR'=>array(0=>'Turkish',1=>'Türkçe'),'tt_RU'=>array(0=>'Tatar',1=>'Татар теле'),'tah'=>array(0=>'Tahitian',1=>'Reo Tahiti'),'ug_CN'=>array(0=>'Uighur',1=>'ئۇيغۇرچە'),'uk'=>array(0=>'Ukrainian',1=>'Українська'),'ur'=>array(0=>'Urdu',1=>'اردو'),'uz_UZ'=>array(0=>'Uzbek',1=>'O‘zbekcha'),'vi'=>array(0=>'Vietnamese',1=>'Tiếng Việt'),'zh_TW'=>array(0=>'Chinese (Taiwan)',1=>'繁體中文'),'zh_CN'=>array(0=>'Chinese (China)',1=>'简体中文'),'zh_HK'=>array(0=>'Chinese (Hong Kong)',1=>'香港中文版 ')); diff --git a/vendor/loco-translate/lib/data/plurals.php b/vendor/loco-translate/lib/data/plurals.php new file mode 100644 index 0000000..6e7819e --- /dev/null +++ b/vendor/loco-translate/lib/data/plurals.php @@ -0,0 +1,5 @@ +1,'am'=>1,'ar'=>2,'ary'=>2,'be'=>3,'bm'=>4,'bo'=>4,'br'=>1,'bs'=>3,'cs'=>5,'cy'=>6,'dz'=>4,'ff'=>1,'fr'=>1,'ga'=>7,'gd'=>8,'gv'=>9,'hr'=>10,'id'=>4,'ii'=>4,'iu'=>11,'ja'=>4,'ka'=>4,'kk'=>4,'km'=>4,'kn'=>4,'ko'=>4,'kw'=>11,'ky'=>4,'ln'=>1,'lo'=>4,'lt'=>12,'lv'=>13,'mg'=>1,'mi'=>1,'mk'=>14,'ms'=>4,'mt'=>15,'my'=>4,'nr'=>4,'oc'=>1,'pl'=>16,'ro'=>17,'ru'=>3,'sa'=>11,'sg'=>4,'sk'=>5,'sl'=>18,'sm'=>4,'sr'=>3,'su'=>4,'th'=>4,'ti'=>1,'tl'=>1,'to'=>4,'tt'=>4,'ug'=>4,'uk'=>3,'vi'=>4,'wa'=>1,'wo'=>4,'yo'=>4,'zh'=>4,''=>array(0=>array(0=>'n != 1',1=>array(0=>'one',1=>'other')),1=>array(0=>'n > 1',1=>array(0=>'one',1=>'other')),2=>array(0=>'n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100 >= 3 && n%100<=10 ? 3 : n%100 >= 11 && n%100<=99 ? 4 : 5',1=>array(0=>'zero',1=>'one',2=>'two',3=>'few',4=>'many',5=>'other')),3=>array(0=>'(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>array(0=>'one',1=>'few',2=>'other')),4=>array(0=>'0',1=>array(0=>'other')),5=>array(0=>'( n == 1 ) ? 0 : ( n >= 2 && n <= 4 ) ? 1 : 2',1=>array(0=>'one',1=>'few',2=>'other')),6=>array(0=>'n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 5',1=>array(0=>'zero',1=>'one',2=>'two',3=>'few',4=>'many',5=>'other')),7=>array(0=>'n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4',1=>array(0=>'one',1=>'two',2=>'few',3=>'many',4=>'other')),8=>array(0=>'n==1||n==11 ? 0 : n==2||n==12 ? 1 :(n >= 3 && n<=10)||(n >= 13 && n<=19)? 2 : 3',1=>array(0=>'one',1=>'two',2=>'few',3=>'other')),9=>array(0=>'n%10==1 ? 0 : n%10==2 ? 1 : n%20==0 ? 2 : 3',1=>array(0=>'one',1=>'two',2=>'few',3=>'other')),10=>array(0=>'n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2',1=>array(0=>'one',1=>'few',2=>'other')),11=>array(0=>'n == 1 ? 0 : n == 2 ? 1 : 2',1=>array(0=>'one',1=>'two',2=>'other')),12=>array(0=>'(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>array(0=>'one',1=>'few',2=>'other')),13=>array(0=>'n % 10 == 1 && n % 100 != 11 ? 0 : n != 0 ? 1 : 2',1=>array(0=>'one',1=>'other',2=>'zero')),14=>array(0=>'( n % 10 == 1 && n % 100 != 11 ) ? 0 : 1',1=>array(0=>'one',1=>'other')),15=>array(0=>'(n==1 ? 0 : n==0||( n%100>1 && n%100<11)? 1 :(n%100>10 && n%100<20)? 2 : 3)',1=>array(0=>'one',1=>'few',2=>'many',3=>'other')),16=>array(0=>'(n==1 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>array(0=>'one',1=>'few',2=>'other')),17=>array(0=>'(n==1 ? 0 :(((n%100>19)||(( n%100==0)&&(n!=0)))? 2 : 1))',1=>array(0=>'one',1=>'few',2=>'other')),18=>array(0=>'n%100==1 ? 0 : n%100==2 ? 1 : n%100==3||n%100==4 ? 2 : 3',1=>array(0=>'one',1=>'two',2=>'few',3=>'other')))); diff --git a/vendor/loco-translate/lib/data/regions.php b/vendor/loco-translate/lib/data/regions.php new file mode 100644 index 0000000..47eda8b --- /dev/null +++ b/vendor/loco-translate/lib/data/regions.php @@ -0,0 +1,5 @@ +'Andorra','AE'=>'United Arab Emirates','AF'=>'Afghanistan','AG'=>'Antigua and Barbuda','AI'=>'Anguilla','AL'=>'Albania','AM'=>'Armenia','AO'=>'Angola','AQ'=>'Antarctica','AR'=>'Argentina','AS'=>'American Samoa','AT'=>'Austria','AU'=>'Australia','AW'=>'Aruba','AX'=>'Åland Islands','AZ'=>'Azerbaijan','BA'=>'Bosnia and Herzegovina','BB'=>'Barbados','BD'=>'Bangladesh','BE'=>'Belgium','BF'=>'Burkina Faso','BG'=>'Bulgaria','BH'=>'Bahrain','BI'=>'Burundi','BJ'=>'Benin','BL'=>'Saint Barthélemy','BM'=>'Bermuda','BN'=>'Brunei Darussalam','BO'=>'Bolivia','BQ'=>'Bonaire, Sint Eustatius and Saba','BR'=>'Brazil','BS'=>'Bahamas','BT'=>'Bhutan','BV'=>'Bouvet Island','BW'=>'Botswana','BY'=>'Belarus','BZ'=>'Belize','CA'=>'Canada','CC'=>'Cocos (Keeling) Islands','CD'=>'The Democratic Republic of the Congo','CF'=>'Central African Republic','CG'=>'Congo','CH'=>'Switzerland','CI'=>'Côte d\'Ivoire','CK'=>'Cook Islands','CL'=>'Chile','CM'=>'Cameroon','CN'=>'China','CO'=>'Colombia','CR'=>'Costa Rica','CU'=>'Cuba','CV'=>'Cabo Verde; Cape Verde','CW'=>'Curaçao','CX'=>'Christmas Island','CY'=>'Cyprus','CZ'=>'Czech Republic','DE'=>'Germany','DJ'=>'Djibouti','DK'=>'Denmark','DM'=>'Dominica','DO'=>'Dominican Republic','DZ'=>'Algeria','EC'=>'Ecuador','EE'=>'Estonia','EG'=>'Egypt','EH'=>'Western Sahara','ER'=>'Eritrea','ES'=>'Spain','ET'=>'Ethiopia','FI'=>'Finland','FJ'=>'Fiji','FK'=>'Falkland Islands (Malvinas)','FM'=>'Federated States of Micronesia','FO'=>'Faroe Islands','FR'=>'France','GA'=>'Gabon','GB'=>'United Kingdom','GD'=>'Grenada','GE'=>'Georgia','GF'=>'French Guiana','GG'=>'Guernsey','GH'=>'Ghana','GI'=>'Gibraltar','GL'=>'Greenland','GM'=>'Gambia','GN'=>'Guinea','GP'=>'Guadeloupe','GQ'=>'Equatorial Guinea','GR'=>'Greece','GS'=>'South Georgia and the South Sandwich Islands','GT'=>'Guatemala','GU'=>'Guam','GW'=>'Guinea-Bissau','GY'=>'Guyana','HK'=>'Hong Kong','HM'=>'Heard Island and McDonald Islands','HN'=>'Honduras','HR'=>'Croatia','HT'=>'Haiti','HU'=>'Hungary','ID'=>'Indonesia','IE'=>'Ireland','IL'=>'Israel','IM'=>'Isle of Man','IN'=>'India','IO'=>'British Indian Ocean Territory','IQ'=>'Iraq','IR'=>'Islamic Republic of Iran','IS'=>'Iceland','IT'=>'Italy','JE'=>'Jersey','JM'=>'Jamaica','JO'=>'Jordan','JP'=>'Japan','KE'=>'Kenya','KG'=>'Kyrgyzstan','KH'=>'Cambodia','KI'=>'Kiribati','KM'=>'Comoros','KN'=>'Saint Kitts and Nevis','KP'=>'Democratic People\'s Republic of Korea','KR'=>'Republic of Korea','KW'=>'Kuwait','KY'=>'Cayman Islands','KZ'=>'Kazakhstan','LA'=>'Lao People\'s Democratic Republic','LB'=>'Lebanon','LC'=>'Saint Lucia','LI'=>'Liechtenstein','LK'=>'Sri Lanka','LR'=>'Liberia','LS'=>'Lesotho','LT'=>'Lithuania','LU'=>'Luxembourg','LV'=>'Latvia','LY'=>'Libya','MA'=>'Morocco','MC'=>'Monaco','MD'=>'Moldova','ME'=>'Montenegro','MF'=>'Saint Martin (French part)','MG'=>'Madagascar','MH'=>'Marshall Islands','MK'=>'The Former Yugoslav Republic of Macedonia','ML'=>'Mali','MM'=>'Myanmar','MN'=>'Mongolia','MO'=>'Macao','MP'=>'Northern Mariana Islands','MQ'=>'Martinique','MR'=>'Mauritania','MS'=>'Montserrat','MT'=>'Malta','MU'=>'Mauritius','MV'=>'Maldives','MW'=>'Malawi','MX'=>'Mexico','MY'=>'Malaysia','MZ'=>'Mozambique','NA'=>'Namibia','NC'=>'New Caledonia','NE'=>'Niger','NF'=>'Norfolk Island','NG'=>'Nigeria','NI'=>'Nicaragua','NL'=>'Netherlands','NO'=>'Norway','NP'=>'Nepal','NR'=>'Nauru','NU'=>'Niue','NZ'=>'New Zealand','OM'=>'Oman','PA'=>'Panama','PE'=>'Peru','PF'=>'French Polynesia','PG'=>'Papua New Guinea','PH'=>'Philippines','PK'=>'Pakistan','PL'=>'Poland','PM'=>'Saint Pierre and Miquelon','PN'=>'Pitcairn','PR'=>'Puerto Rico','PS'=>'State of Palestine','PT'=>'Portugal','PW'=>'Palau','PY'=>'Paraguay','QA'=>'Qatar','RE'=>'Réunion','RO'=>'Romania','RS'=>'Serbia','RU'=>'Russian Federation','RW'=>'Rwanda','SA'=>'Saudi Arabia','SB'=>'Solomon Islands','SC'=>'Seychelles','SD'=>'Sudan','SE'=>'Sweden','SG'=>'Singapore','SH'=>'Saint Helena, Ascension and Tristan da Cunha','SI'=>'Slovenia','SJ'=>'Svalbard and Jan Mayen','SK'=>'Slovakia','SL'=>'Sierra Leone','SM'=>'San Marino','SN'=>'Senegal','SO'=>'Somalia','SR'=>'Suriname','SS'=>'South Sudan','ST'=>'Sao Tome and Principe','SV'=>'El Salvador','SX'=>'Sint Maarten (Dutch part)','SY'=>'Syrian Arab Republic','SZ'=>'Swaziland','TC'=>'Turks and Caicos Islands','TD'=>'Chad','TF'=>'French Southern Territories','TG'=>'Togo','TH'=>'Thailand','TJ'=>'Tajikistan','TK'=>'Tokelau','TL'=>'Timor-Leste','TM'=>'Turkmenistan','TN'=>'Tunisia','TO'=>'Tonga','TR'=>'Turkey','TT'=>'Trinidad and Tobago','TV'=>'Tuvalu','TW'=>'Taiwan','TZ'=>'United Republic of Tanzania','UA'=>'Ukraine','UG'=>'Uganda','UM'=>'United States Minor Outlying Islands','US'=>'United States','UY'=>'Uruguay','UZ'=>'Uzbekistan','VA'=>'Holy See (Vatican City State)','VC'=>'Saint Vincent and the Grenadines','VE'=>'Venezuela','VG'=>'British Virgin Islands','VI'=>'U.S. Virgin Islands','VN'=>'Viet Nam','VU'=>'Vanuatu','WF'=>'Wallis and Futuna','WS'=>'Samoa','YE'=>'Yemen','YT'=>'Mayotte','ZA'=>'South Africa','ZM'=>'Zambia','ZW'=>'Zimbabwe','ZZ'=>'Private use'); diff --git a/vendor/loco-translate/loco.php b/vendor/loco-translate/loco.php new file mode 100644 index 0000000..1fd7a36 --- /dev/null +++ b/vendor/loco-translate/loco.php @@ -0,0 +1,177 @@ + + + + + + src + tpl + loco.php + + + languages + + + + + + tmp + lib + pub + test + + diff --git a/vendor/loco-translate/pub/css/admin.css b/vendor/loco-translate/pub/css/admin.css new file mode 100644 index 0000000..c089a49 --- /dev/null +++ b/vendor/loco-translate/pub/css/admin.css @@ -0,0 +1 @@ +._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.4.0) 0 0 no-repeat;min-height:75px}._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.4.0);background-size:16px}._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.4.0);background-size:16px}}._green_glow_inner{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}.loco-font,#loco.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco.wrap .wp-list-table th.loco-sort.loco-desc:after,#loco.wrap .icon,#loco.wrap .has-icon:before{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@font-face{font-family:"loco";src:url("../font/loco.eot?v=2.4.0");src:url("../font/loco.eot?v=2.4.0?#iefix") format("embedded-opentype"),url("../font/loco.woff?v=2.4.0") format("woff"),url("../font/loco.ttf?v=2.4.0") format("truetype"),url("../font/loco.svg?v=2.4.0#loco") format("svg");font-weight:normal;font-style:normal}.tipsy{font-size:11px;position:absolute;padding:5px;z-index:500001;opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.tipsy.in{opacity:1}.tipsy-inner{background-color:#000;color:#fff;white-space:nowrap;padding:6px 8px;line-height:1.3em;text-align:center;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-font-smoothing:subpixel-antialiased}.tipsy-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.tipsy-n .tipsy-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-nw .tipsy-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-ne .tipsy-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-s .tipsy-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-sw .tipsy-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-se .tipsy-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-e .tipsy-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.tipsy-w .tipsy-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}#loco.wrap .selector li,#loco.wrap .selector .handle,#loco.wrap .selectoradd a,#loco.wrap .selectorsep:before,#loco.wrap .selectorsep span{padding:.3em .75em}#loco.wrap .selector{text-align:left;display:inline-block;white-space:nowrap}#loco.wrap .selectoradd a,#loco.wrap .selector .handle{cursor:default;display:block;position:relative;border-top:solid 1px #fff;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd;border-left:solid 1px #fff;color:#666;height:1.3em;overflow:hidden;white-space:normal}#loco.wrap .selectorsep{display:inline-block;border:solid 1px transparent}#loco.wrap .selectorsep:before{display:block;position:relative;color:#999;height:1.3em;overflow:hidden}#loco.wrap .selectorsep>*{display:block;line-height:1em;color:#666;height:1.3em;overflow:hidden}#loco.wrap .selector .handle{outline:none;white-space:nowrap;padding-right:2.3em;max-width:250px;text-overflow:ellipsis}#loco.wrap .selector .handle .prefix{padding-right:.6ex}#loco.wrap .selector .handle:after{font-family:loco;font-size:1.3em;color:#ccc;display:block;position:absolute;top:.25em;right:.6em;content:"▼"}#loco.wrap .selector .handle:focus:after,#loco.wrap .selector .handle:hover:after{color:#666}#loco.wrap .selector.no-caret .handle{padding-right:.75em}#loco.wrap .selector.no-caret .handle:after{display:none}#loco.wrap .selector.no-title .handle{padding-left:.5em;padding-right:.5em}#loco.wrap .selector.no-title .handle .label{display:none}#loco.wrap .selector.no-title .handle .icon{margin-right:0px}#loco.wrap .selector.dummy .handle{border-color:transparent}#loco.wrap .selector.dummy .handle:after{display:none}#loco.wrap .selectoradd{position:relative}#loco.wrap .selectoradd>*{display:block;float:left;clear:none}#loco.wrap .selectoradd>a.has-icon{width:1.3em}#loco.wrap .selectoradd>a.has-icon:before{color:#999;display:inline;padding-left:0;padding-right:0;line-height:1.4em}#loco.wrap .selectoradd>a.has-icon:hover:after{color:#2e892e}#loco.wrap .selectorsep{display:inline-block}#loco.wrap .selectorsep span{color:#666;height:1.3em}#loco.wrap .selector ul{padding:0}#loco.wrap .selector ul,#loco.wrap .selector li{display:block;position:relative;cursor:default;margin:0}#loco.wrap .selector ul{z-index:5;position:absolute;left:0;top:0;background:#f5f5f5;box-shadow:0 10px 5px rgba(0,0,0,.2);border:solid 1px #ccc;overflow:auto}#loco.wrap .selector.up ul{margin-top:0}#loco.wrap .selector.multi li input{display:none}#loco.wrap .selector.multi li.checked{background:#e5e5e5}#loco.wrap .selector li.active{background:#e5e5e5 !important}#loco.wrap .selector li.over{background:#ccc !important;color:#fff;text-shadow:1px 1px #aaa}#loco.wrap .selector li.over .label{color:#fff}#loco.wrap .selector .label{font:inherit;color:inherit}#loco.wrap .selector .icon{display:inline-block;min-width:1.2em;text-align:center;font-size:14px}#loco.wrap .selector .icon.no-icon{display:none}#loco.wrap .selector .icon:before{color:#666}#loco.wrap .selector .avtr{width:18px;height:18px;background-size:18px;background-repeat:no-repeat}#loco.wrap .selector .label{line-height:1}#loco.wrap .selector .icon,#loco.wrap .selector .icon-16{vertical-align:bottom}#loco.wrap .selector .icon,#loco.wrap .selector .lang,#loco.wrap .selector .icon-16{margin-right:5px}#loco.wrap .selector .region,#loco.wrap .selector .variant-wales,#loco.wrap .selector .region-gb.lang-cy,#loco.wrap .selector .variant-scotland,#loco.wrap .selector .region-gb.lang-gd,#loco.wrap .selector .variant-valencia,#loco.wrap .selector .region-es.variant-valencia,#loco.wrap .selector .lang-ca,#loco.wrap .selector .region-es.lang-ca,#loco.wrap .selector .lang-eo,#loco.wrap .selector .lang-eu{margin-left:2px;margin-right:7px}#loco.wrap .selector.ticked .icon.no-icon{font-size:12px;display:inline-block}#loco.wrap .selector.ticked .active .icon.no-icon:before{content:"✓"}#loco.wrap .selectoradd a:hover,#loco.wrap .selector a.handle:focus,#loco.wrap .selector a.handle:hover{color:#000;border-color:#999}#loco.wrap .selector.active .handle{border-color:#999;background-color:#eee;color:#999}#loco.wrap .selector.active .handle:after{color:#999;content:"▲"}#loco.wrap .selector.disabled{cursor:default;cursor:no-drop;cursor:not-allowed}#loco.wrap .selector.disabled .handle{pointer-events:none;border-top:solid 1px #fff;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd;border-left:solid 1px #fff;color:#999;padding-right:1em}#loco.wrap .selector.disabled .handle:after{display:none}#loco.wrap .selector.disabled .handle span.icon{color:#999 !important}#loco.wrap .selector li.disabled,#loco.wrap .selector li.disabled.over{color:#aaa;text-shadow:1px 1px #fff;pointer-events:none}#loco.wrap .selector li.disabled *{cursor:text}#loco.wrap .selector li.disabled .icon:before{color:#aaa}#loco.wrap .selector li.disabled .flag,#loco.wrap .selector li.disabled .icon-16{opacity:.4}#loco.wrap .selector.lefty ul{left:auto;right:0}#loco.wrap .selector.lefty ul .icon,#loco.wrap .selector.lefty ul .icon-32{display:block;float:right;clear:none}#loco.wrap .selector.lefty ul .label{padding-right:32px;padding-left:0}#loco.wrap .selector ul>form{margin:0;display:block}#loco.wrap .selector ul>form input{margin:0;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0}#loco.wrap .selector ul>form input:focus{-webkit-box-shadow:inset 0 0 5px 0 #3db63d;-moz-box-shadow:inset 0 0 5px 0 #3db63d;box-shadow:inset 0 0 5px 0 #3db63d}#loco.wrap .selector ul>form input.error{border-color:#c00;-webkit-box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5);-moz-box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5);box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5)}#loco.wrap .selector ul>form a.clear{margin:0;border:none}#loco.wrap .selector ul>form ::placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco.wrap .selector ul>form ::-webkit-input-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco.wrap .selector ul>form :-moz-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block;opacity:1}#loco.wrap .selector ul>form ::-moz-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block;opacity:1}#loco.wrap .selector ul>form :-ms-input-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco.wrap .selector ul>form .ielt10 .placeheld{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco.wrap div.auto-comp-wrap{width:100%}#loco.wrap div.auto-comp-wrap input{display:inline-block}#loco.wrap div.auto-comp-wrap.loading input{background:transparent url(../img/ajax-loader.gif?v=2.4.0) right 2px no-repeat}#loco.wrap div.auto-comp-drop{color:#333;background:#fff;border-top:none;position:absolute;width:auto;top:0;left:0;z-index:99;-webkit-box-shadow:0 5px 5px rgba(0,0,0,.4);-moz-box-shadow:0 5px 5px rgba(0,0,0,.4);box-shadow:0 5px 5px rgba(0,0,0,.4)}#loco.wrap div.auto-comp-result{padding:5px 10px;cursor:pointer;background:#f0f0f0;border-top:solid 1px #fff;border-bottom:solid 1px #ddd;white-space:nowrap}#loco.wrap div.auto-comp-result:first-child{border-top:solid 1px #ddd}#loco.wrap div.auto-comp-result>*{display:inline-block;vertical-align:middle;line-height:normal}#loco.wrap div.auto-comp-result .icon:before{padding-right:5px}#loco.wrap div.auto-comp-result:hover{background:#a8a8a8;color:#fff;border-top-color:#a8a8a8;border-bottom-color:#999}#loco.wrap div.auto-comp-result.selected{background:#666 !important;color:#fff;border-top-color:#666;border-bottom-color:#666}#loco.wrap div.auto-comp-result .lang,#loco.wrap div.auto-comp-result .region,#loco.wrap div.auto-comp-result .variant-wales,#loco.wrap div.auto-comp-result .region-gb.lang-cy,#loco.wrap div.auto-comp-result .variant-scotland,#loco.wrap div.auto-comp-result .region-gb.lang-gd,#loco.wrap div.auto-comp-result .variant-valencia,#loco.wrap div.auto-comp-result .region-es.variant-valencia,#loco.wrap div.auto-comp-result .lang-ca,#loco.wrap div.auto-comp-result .region-es.lang-ca,#loco.wrap div.auto-comp-result .lang-eo,#loco.wrap div.auto-comp-result .lang-eu,#loco.wrap div.auto-comp-result .avtr{margin-right:5px}#loco.wrap div.auto-comp-wrap.error a.icon.clear:before{color:#c00;opacity:1}#loco.wrap div.auto-comp-wrap.error input[type=text]{border-color:#c00;color:#c00}#loco.wrap div.auto-comp-wrap.error input[type=text]:focus{-webkit-box-shadow:0 0 .5em 0 rgba(153,0,0,.5);-moz-box-shadow:0 0 .5em 0 rgba(153,0,0,.5);box-shadow:0 0 .5em 0 rgba(153,0,0,.5)}#loco.wrap ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}#loco.wrap ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.4.0) 0 0 no-repeat;min-height:75px}#loco.wrap ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco.wrap ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.4.0);background-size:16px}#loco.wrap ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.4.0);background-size:16px}}#loco.wrap ._green_glow_inner{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco.wrap ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco.wrap .loco-font,#loco.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco.wrap .wp-list-table th.loco-sort.loco-desc:after,#loco.wrap .icon,#loco.wrap .has-icon:before{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco.wrap .has-icon:before{display:inline-block;padding-right:.3em}#loco.wrap a.icon-help{cursor:help}#loco.wrap a.icon-help span{display:none}#loco.wrap .icon-notag:before{content:""}#loco.wrap .icon-python:before{content:"🐍"}#loco.wrap .icon-unicode:before{content:"u"}#loco.wrap .icon-json:before{content:"{"}#loco.wrap .icon-bullist:before{content:""}#loco.wrap .icon-numlist:before{content:""}#loco.wrap .icon-indent:before{content:""}#loco.wrap .icon-outdent:before{content:""}#loco.wrap .icon-link:before{content:""}#loco.wrap .icon-unlink:before{content:""}#loco.wrap .icon-bold:before{content:"B"}#loco.wrap .icon-italic:before{content:"I"}#loco.wrap .icon-translate:before{content:""}#loco.wrap .icon-proj:before{content:""}#loco.wrap .icon-plural:before{content:"᛬"}#loco.wrap .icon-max:before,#loco.wrap .icon-full-screen:before{content:""}#loco.wrap .icon-min:before{content:""}#loco.wrap .icon-sort:before{content:""}#loco.wrap .icon-ok:before,#loco.wrap .notice-success>.has-icon:before,#loco.wrap .notice-success p>strong.has-icon:before{content:"✓"}#loco.wrap .icon-ok-empty:before{content:"🗌"}#loco.wrap .icon-checkbox-checked:before,#loco.wrap .selector.multi li.checked .icon-checkbox:before{content:"☑"}#loco.wrap .icon-checkbox-unchecked:before{content:"☐"}#loco.wrap .icon-checkbox-partial:before{content:"☉"}#loco.wrap .icon-radio-checked:before{content:"⚫"}#loco.wrap .icon-radio-unchecked:before{content:"⚪"}#loco.wrap .icon-ext:before{content:"⬈"}#loco.wrap .icon-share:before{content:""}#loco.wrap .icon-star:before{content:""}#loco.wrap .icon-user:before{content:""}#loco.wrap .icon-remove:before{content:"×"}#loco.wrap .icon-cog:before{content:""}#loco.wrap .icon-trash:before{content:""}#loco.wrap .icon-time:before,#loco.wrap .icon-history:before{content:""}#loco.wrap .icon-download:before{content:""}#loco.wrap .icon-revert:before{content:""}#loco.wrap .icon-sync:before{content:""}#loco.wrap .icon-lock:before,#loco.wrap .notice-locked>.has-icon:before,#loco.wrap .notice-locked p>strong.has-icon:before{content:""}#loco.wrap .icon-flag:before{content:""}#loco.wrap .icon-tag:before{content:""}#loco.wrap .icon-tags:before{content:""}#loco.wrap .icon-print:before{content:""}#loco.wrap .icon-camera:before{content:""}#loco.wrap .icon-pencil:before{content:""}#loco.wrap .icon-add:before{content:""}#loco.wrap .icon-del:before{content:""}#loco.wrap .icon-clear:before,#loco.wrap a.icon.clear:before{content:""}#loco.wrap .icon-ok-sign:before{content:"✔"}#loco.wrap .icon-help:before{content:"?"}#loco.wrap .icon-info:before,#loco.wrap .notice-info>.has-icon:before,#loco.wrap .notice-info p>strong.has-icon:before{content:"ℹ"}#loco.wrap .icon-cancel:before{content:""}#loco.wrap .icon-warn:before,#loco.wrap .notice-error>.has-icon:before,#loco.wrap .notice-error p>strong.has-icon:before,#loco.wrap .notice-warning>.has-icon:before,#loco.wrap .notice-warning p>strong.has-icon:before{content:""}#loco.wrap .icon-comment:before{content:""}#loco.wrap .icon-bar-chart:before{content:""}#loco.wrap .icon-key:before{content:""}#loco.wrap .icon-cogs:before{content:""}#loco.wrap .icon-comments:before{content:""}#loco.wrap .icon-signout:before{content:""}#loco.wrap .icon-signin:before{content:""}#loco.wrap .icon-upload:before{content:""}#loco.wrap .icon-twitter:before{content:"🐦"}#loco.wrap .icon-facebook:before{content:""}#loco.wrap .icon-github:before{content:""}#loco.wrap .icon-feed:before{content:""}#loco.wrap .icon-globe:before{content:""}#loco.wrap .icon-wrench:before,#loco.wrap .notice-debug>.has-icon:before,#loco.wrap .notice-debug p>strong.has-icon:before{content:""}#loco.wrap .icon-group:before{content:""}#loco.wrap .icon-cloud:before{content:""}#loco.wrap .icon-copy:before{content:""}#loco.wrap .icon-save:before{content:""}#loco.wrap .icon-menu:before{content:""}#loco.wrap .icon-table:before{content:""}#loco.wrap .icon-caret-down:before{content:"▼"}#loco.wrap .icon-caret-up:before{content:"▲"}#loco.wrap .icon-caret-right:before{content:"▶"}#loco.wrap .icon-mail:before{content:""}#loco.wrap .icon-cloud-upload:before{content:""}#loco.wrap .icon-file:before{content:""}#loco.wrap .icon-circle-white:before{content:"⚬"}#loco.wrap .icon-circle-black:before{content:"●"}#loco.wrap .icon-eraser:before{content:""}#loco.wrap .icon-unlock:before{content:""}#loco.wrap .icon-apple:before{content:""}#loco.wrap .icon-android:before{content:""}#loco.wrap .icon-robot:before{content:"🤖"}#loco.wrap .icon-back:before{content:"⬅"}#loco.wrap .icon-next:before{content:"➔"}#loco.wrap .icon-arrow-up:before{content:""}#loco.wrap .icon-ccard:before{content:""}#loco.wrap .icon-caret-left:before{content:"◀"}#loco.wrap .icon-pro:before{content:"⚡"}#loco.wrap .icon-bell:before{content:""}#loco.wrap .icon-code:before{content:""}#loco.wrap .icon-privacy:before{content:"🛡"}#loco.wrap .icon-hellip:before{content:"…"}#loco.wrap .icon-vellip:before{content:"⁞"}#loco.wrap .icon-collapse:before{content:""}#loco.wrap .icon-expand:before{content:""}#loco.wrap .icon-wordpress:before{content:""}#loco.wrap .icon-database:before{content:""}#loco.wrap .icon-restore:before{content:""}#loco.wrap .icon-pilcrow:before{content:"¶"}#loco.wrap .icon-status.is-translated:before,#loco.wrap .is-translated>header>.icon-status:before{color:#2e892e;content:"✓";text-align:center}#loco.wrap .icon-status.is-untranslated:before,#loco.wrap .is-untranslated>header>.icon-status:before{color:#aaa;content:"×";text-align:center;font-size:1.1em}#loco.wrap .icon-status.is-flagged:before,#loco.wrap .is-flagged>header>.icon-status:before{color:#bd2c00;content:"";text-align:center}#loco.wrap .icon-status.is-translated.is-blank:before,#loco.wrap .icon-status.is-translated.is-inherit:before,#loco.wrap .is-translated.is-blank>header>.icon-status:before,#loco.wrap .is-translated.is-inherit>header>.icon-status:before{content:"🗌"}#loco.wrap .icon-status.is-fuzzy:before,#loco.wrap .is-fuzzy>header>.icon-status:before{color:#666;content:""}#loco.wrap .lang,#loco.wrap .region,#loco.wrap .variant-wales,#loco.wrap .region-gb.lang-cy,#loco.wrap .variant-scotland,#loco.wrap .region-gb.lang-gd,#loco.wrap .variant-valencia,#loco.wrap .region-es.variant-valencia,#loco.wrap .lang-ca,#loco.wrap .region-es.lang-ca,#loco.wrap .lang-eo,#loco.wrap .lang-eu{color:#fff;background:#2e892e;display:inline-block;text-transform:uppercase;overflow:hidden;font-family:Verdana,Arial,sans-serif;font-size:9px;font-weight:normal;font-style:normal;line-height:12px;text-align:center;white-space:normal;text-shadow:none}#loco.wrap .lang{width:20px;height:12px;line-height:12px;vertical-align:middle}#loco.wrap .lang:before{content:attr(lang);vertical-align:baseline}#loco.wrap .no-lang{width:18px;height:10px;border:solid 1px #2e892e;background:transparent}#loco.wrap .lang-el{background-color:#1d48a3}#loco.wrap .lang-el:before{content:"Ελ"}#loco.wrap .region,#loco.wrap .variant-wales,#loco.wrap .region-gb.lang-cy,#loco.wrap .variant-scotland,#loco.wrap .region-gb.lang-gd,#loco.wrap .variant-valencia,#loco.wrap .region-es.variant-valencia,#loco.wrap .lang-ca,#loco.wrap .region-es.lang-ca,#loco.wrap .lang-eo,#loco.wrap .lang-eu{width:16px;height:12px;margin:0 2px;background-image:url(../img/flags.png?v=2.4.0);background-repeat:no-repeat;background-color:transparent}#loco.wrap .region:before,#loco.wrap .variant-wales:before,#loco.wrap .region-gb.lang-cy:before,#loco.wrap .variant-scotland:before,#loco.wrap .region-gb.lang-gd:before,#loco.wrap .variant-valencia:before,#loco.wrap .region-es.variant-valencia:before,#loco.wrap .lang-ca:before,#loco.wrap .region-es.lang-ca:before,#loco.wrap .lang-eo:before,#loco.wrap .lang-eu:before{visibility:hidden}#loco.wrap .lang-zh{background-color:#b90000}#loco.wrap .lang-zh.script-hans:before{content:"中国"}#loco.wrap .lang-zh.script-hant:before{content:"中國"}#loco.wrap .__{background-position:0 0}#loco.wrap .lang-eo{background-position:0 -12px}#loco.wrap .lang-eu{background-position:0 -24px}#loco.wrap .lang-ca,#loco.wrap .region-es.lang-ca{background-position:0 -36px}#loco.wrap .region-tg{background-position:0 -48px}#loco.wrap .region-me{background-position:0 -60px}#loco.wrap .region-la{background-position:0 -73px}#loco.wrap .region-mr{background-position:0 -85px}#loco.wrap .region-ni{background-position:0 -97px}#loco.wrap .region-lv{background-position:0 -109px}#loco.wrap .region-om{background-position:0 -121px}#loco.wrap .region-af{background-position:0 -133px}#loco.wrap .region-cy{background-position:0 -145px}#loco.wrap .region-bj{background-position:0 -157px}#loco.wrap .region-aq{background-position:0 -169px}#loco.wrap .region-cn{background-position:0 -186px}#loco.wrap .region-co{background-position:0 -198px}#loco.wrap .region-cx{background-position:0 -210px}#loco.wrap .region-ag{background-position:0 -222px}#loco.wrap .region-ms{background-position:0 -234px}#loco.wrap .region-md{background-position:0 -246px}#loco.wrap .region-zm{background-position:0 -258px}#loco.wrap .region-vn{background-position:0 -270px}#loco.wrap .region-tf{background-position:0 -282px}#loco.wrap .region-td{background-position:0 -294px}#loco.wrap .region-yt{background-position:0 -306px}#loco.wrap .region-lb{background-position:0 -318px}#loco.wrap .region-mf{background-position:0 -330px}#loco.wrap .region-lu{background-position:0 -347px}#loco.wrap .region-mq{background-position:0 -359px}#loco.wrap .region-cz{background-position:0 -371px}#loco.wrap .region-ae{background-position:0 -383px}#loco.wrap .region-cm{background-position:0 -395px}#loco.wrap .region-bi{background-position:0 -407px}#loco.wrap .region-ar{background-position:0 -419px}#loco.wrap .region-as{background-position:0 -431px}#loco.wrap .region-bh{background-position:0 -443px}#loco.wrap .region-cl{background-position:0 -455px}#loco.wrap .region-ad{background-position:0 -467px}#loco.wrap .region-mp{background-position:0 -479px}#loco.wrap .region-lt{background-position:0 -491px}#loco.wrap .region-mg{background-position:0 -503px}#loco.wrap .region-lc{background-position:0 -515px}#loco.wrap .region-tr{background-position:0 -527px}#loco.wrap .region-ua{background-position:0 -539px}#loco.wrap .region-tv{background-position:0 -551px}#loco.wrap .region-vi{background-position:0 -563px}#loco.wrap .region-mt{background-position:0 -575px}#loco.wrap .region-no{background-position:0 -587px}#loco.wrap .region-mc{background-position:0 -599px}#loco.wrap .region-ch{background-position:0 -611px}#loco.wrap .region-bl{background-position:0 -623px}#loco.wrap .region-aw{background-position:0 -640px}#loco.wrap .region-bz{background-position:0 -652px}#loco.wrap .region-bm{background-position:0 -664px}#loco.wrap .region-ci{background-position:0 -676px}#loco.wrap .region-mu{background-position:0 -688px}#loco.wrap .region-us{background-position:0 -700px}#loco.wrap .region-tw{background-position:0 -712px}#loco.wrap .region-ye{background-position:0 -724px}#loco.wrap .region-mw{background-position:0 -736px}#loco.wrap .region-nl{background-position:0 -748px}#loco.wrap .region-ls{background-position:0 -760px}#loco.wrap .region-bo{background-position:0 -772px}#loco.wrap .region-at{background-position:0 -784px}#loco.wrap .region-ck{background-position:0 -796px}#loco.wrap .region-by{background-position:0 -808px}#loco.wrap .region-au{background-position:0 -820px}#loco.wrap .region-bn{background-position:0 -832px}#loco.wrap .region-ma{background-position:0 -844px}#loco.wrap .region-nz{background-position:0 -856px}#loco.wrap .region-lr{background-position:0 -868px}#loco.wrap .region-mv{background-position:0 -880px}#loco.wrap .region-tc{background-position:0 -892px}#loco.wrap .region-ug{background-position:0 -904px}#loco.wrap .region-tt{background-position:0 -916px}#loco.wrap .region-pl{background-position:0 -928px}#loco.wrap .region-rs{background-position:0 -940px}#loco.wrap .region-in{background-position:0 -952px}#loco.wrap .region-ge{background-position:0 -964px}#loco.wrap .region-gr{background-position:0 -976px}#loco.wrap .region-gs{background-position:0 -988px}#loco.wrap .region-gd{background-position:0 -1000px}#loco.wrap .region-io{background-position:0 -1012px}#loco.wrap .region-hk{background-position:0 -1024px}#loco.wrap .region-kp{background-position:0 -1036px}#loco.wrap .region-kg{background-position:0 -1048px}#loco.wrap .region-pm{background-position:0 -1060px}#loco.wrap .region-sv{background-position:0 -1072px}#loco.wrap .region-re{background-position:0 -1084px}#loco.wrap .region-sa{background-position:0 -1096px}#loco.wrap .region-sc{background-position:0 -1108px}#loco.wrap .region-st{background-position:0 -1120px}#loco.wrap .region-ke{background-position:0 -1132px}#loco.wrap .region-im{background-position:0 -1144px}#loco.wrap .region-kr{background-position:0 -1161px}#loco.wrap .region-gf{background-position:0 -1173px}#loco.wrap .region-dj{background-position:0 -1185px}#loco.wrap .region-gq{background-position:0 -1197px}#loco.wrap .region-gp{background-position:0 -1209px}#loco.wrap .region-dk{background-position:0 -1221px}#loco.wrap .region-gg{background-position:0 -1233px}#loco.wrap .region-il{background-position:0 -1250px}#loco.wrap .region-pn{background-position:0 -1262px}#loco.wrap .region-sb{background-position:0 -1274px}#loco.wrap .region-py{background-position:0 -1286px}#loco.wrap .region-ru{background-position:0 -1298px}#loco.wrap .region-kw{background-position:0 -1310px}#loco.wrap .region-do{background-position:0 -1322px}#loco.wrap .region-gt{background-position:0 -1334px}#loco.wrap .region-gb{background-position:0 -1346px}#loco.wrap .region-gu{background-position:0 -1358px}#loco.wrap .region-je{background-position:0 -1370px}#loco.wrap .region-hm{background-position:0 -1387px}#loco.wrap .region-sg{background-position:0 -1399px}#loco.wrap .region-pk{background-position:0 -1411px}#loco.wrap .region-sr{background-position:0 -1423px}#loco.wrap .region-se{background-position:0 -1435px}#loco.wrap .region-jp{background-position:0 -1447px}#loco.wrap .region-gw{background-position:0 -1459px}#loco.wrap .region-eh{background-position:0 -1471px}#loco.wrap .region-dz{background-position:0 -1483px}#loco.wrap .region-ga{background-position:0 -1495px}#loco.wrap .region-fr{background-position:0 -1507px}#loco.wrap .region-dm{background-position:0 -1519px}#loco.wrap .region-hn{background-position:0 -1531px}#loco.wrap .region-sd{background-position:0 -1543px}#loco.wrap .region-rw{background-position:0 -1555px}#loco.wrap .region-ph{background-position:0 -1567px}#loco.wrap .region-ss{background-position:0 -1579px}#loco.wrap .region-qa{background-position:0 -1596px}#loco.wrap .region-pe{background-position:0 -1608px}#loco.wrap .region-pr{background-position:0 -1620px}#loco.wrap .region-si{background-position:0 -1632px}#loco.wrap .region-ht{background-position:0 -1644px}#loco.wrap .region-es{background-position:0 -1656px}#loco.wrap .region-gl{background-position:0 -1668px}#loco.wrap .region-gm{background-position:0 -1680px}#loco.wrap .region-er{background-position:0 -1692px}#loco.wrap .region-fi{background-position:0 -1704px}#loco.wrap .region-ee{background-position:0 -1716px}#loco.wrap .region-kn{background-position:0 -1728px}#loco.wrap .region-hu{background-position:0 -1740px}#loco.wrap .region-iq{background-position:0 -1752px}#loco.wrap .region-ky{background-position:0 -1764px}#loco.wrap .region-sh{background-position:0 -1776px}#loco.wrap .region-ps{background-position:0 -1788px}#loco.wrap .region-pf{background-position:0 -1800px}#loco.wrap .region-sj{background-position:0 -1812px}#loco.wrap .region-id{background-position:0 -1824px}#loco.wrap .region-is{background-position:0 -1836px}#loco.wrap .region-eg{background-position:0 -1848px}#loco.wrap .region-fk{background-position:0 -1860px}#loco.wrap .region-fj{background-position:0 -1872px}#loco.wrap .region-gn{background-position:0 -1884px}#loco.wrap .region-gy{background-position:0 -1896px}#loco.wrap .region-ir{background-position:0 -1908px}#loco.wrap .region-km{background-position:0 -1920px}#loco.wrap .region-ie{background-position:0 -1932px}#loco.wrap .region-kz{background-position:0 -1944px}#loco.wrap .region-ro{background-position:0 -1956px}#loco.wrap .region-sk{background-position:0 -1968px}#loco.wrap .region-pg{background-position:0 -1980px}#loco.wrap .region-pt{background-position:0 -1992px}#loco.wrap .region-so{background-position:0 -2004px}#loco.wrap .region-sx{background-position:0 -2016px}#loco.wrap .region-hr{background-position:0 -2033px}#loco.wrap .region-ki{background-position:0 -2045px}#loco.wrap .region-jm{background-position:0 -2057px}#loco.wrap .region-ec{background-position:0 -2069px}#loco.wrap .region-et{background-position:0 -2081px}#loco.wrap .region-fo{background-position:0 -2093px}#loco.wrap .region-kh{background-position:0 -2105px}#loco.wrap .region-sy{background-position:0 -2117px}#loco.wrap .region-sn{background-position:0 -2129px}#loco.wrap .region-pw{background-position:0 -2141px}#loco.wrap .region-sl{background-position:0 -2153px}#loco.wrap .region-fm{background-position:0 -2165px}#loco.wrap .region-gi{background-position:0 -2177px}#loco.wrap .region-de{background-position:0 -2189px}#loco.wrap .region-gh{background-position:0 -2201px}#loco.wrap .region-jo{background-position:0 -2213px}#loco.wrap .region-it{background-position:0 -2225px}#loco.wrap .region-pa{background-position:0 -2237px}#loco.wrap .region-sz{background-position:0 -2249px}#loco.wrap .region-sm{background-position:0 -2261px}#loco.wrap .region-tn{background-position:0 -2273px}#loco.wrap .region-ml{background-position:0 -2285px}#loco.wrap .region-cg{background-position:0 -2297px}#loco.wrap .region-ax{background-position:0 -2309px}#loco.wrap .region-ao{background-position:0 -2321px}#loco.wrap .region-bt{background-position:0 -2333px}#loco.wrap .region-an{background-position:0 -2345px}#loco.wrap .region-bb{background-position:0 -2357px}#loco.wrap .region-cf{background-position:0 -2369px}#loco.wrap .region-mm{background-position:0 -2381px}#loco.wrap .region-li{background-position:0 -2393px}#loco.wrap .region-na{background-position:0 -2405px}#loco.wrap .region-mz{background-position:0 -2417px}#loco.wrap .region-to{background-position:0 -2429px}#loco.wrap .region-vg{background-position:0 -2441px}#loco.wrap .region-ve{background-position:0 -2453px}#loco.wrap .region-tz{background-position:0 -2465px}#loco.wrap .region-tm{background-position:0 -2477px}#loco.wrap .region-mx{background-position:0 -2489px}#loco.wrap .region-nc{background-position:0 -2501px}#loco.wrap .region-mo{background-position:0 -2513px}#loco.wrap .region-lk{background-position:0 -2525px}#loco.wrap .region-cd{background-position:0 -2537px}#loco.wrap .region-al{background-position:0 -2549px}#loco.wrap .region-bw{background-position:0 -2561px}#loco.wrap .region-cs{background-position:0 -2573px}#loco.wrap .region-cr{background-position:0 -2585px}#loco.wrap .region-bv{background-position:0 -2597px}#loco.wrap .region-am{background-position:0 -2609px}#loco.wrap .region-az{background-position:0 -2621px}#loco.wrap .region-ba{background-position:0 -2633px}#loco.wrap .region-mn{background-position:0 -2645px}#loco.wrap .region-nu{background-position:0 -2657px}#loco.wrap .region-my{background-position:0 -2669px}#loco.wrap .region-tl{background-position:0 -2681px}#loco.wrap .region-ws{background-position:0 -2693px}#loco.wrap .region-th{background-position:0 -2705px}#loco.wrap .region-nf{background-position:0 -2717px}#loco.wrap .region-ly{background-position:0 -2729px}#loco.wrap .region-ai{background-position:0 -2741px}#loco.wrap .region-br{background-position:0 -2753px}#loco.wrap .region-cv{background-position:0 -2765px}#loco.wrap .region-be{background-position:0 -2777px}#loco.wrap .region-ca{background-position:0 -2789px}#loco.wrap .region-bd{background-position:0 -2801px}#loco.wrap .region-cw{background-position:0 -2813px}#loco.wrap .region-bs{background-position:0 -2830px}#loco.wrap .region-ng{background-position:0 -2842px}#loco.wrap .region-mk{background-position:0 -2854px}#loco.wrap .region-np{background-position:0 -2866px}#loco.wrap .region-va{background-position:0 -2878px}#loco.wrap .region-uz{background-position:0 -2890px}#loco.wrap .region-um{background-position:0 -2902px}#loco.wrap .region-tk{background-position:0 -2914px}#loco.wrap .region-vc{background-position:0 -2926px}#loco.wrap .region-zw{background-position:0 -2938px}#loco.wrap .region-nr{background-position:0 -2950px}#loco.wrap .region-ne{background-position:0 -2962px}#loco.wrap .region-cu{background-position:0 -2974px}#loco.wrap .region-bq{background-position:0 -2986px}#loco.wrap .region-bf{background-position:0 -2998px}#loco.wrap .region-bg{background-position:0 -3010px}#loco.wrap .region-cc{background-position:0 -3022px}#loco.wrap .region-mh{background-position:0 -3034px}#loco.wrap .region-za{background-position:0 -3046px}#loco.wrap .region-uy{background-position:0 -3058px}#loco.wrap .region-wf{background-position:0 -3070px}#loco.wrap .region-vu{background-position:0 -3082px}#loco.wrap .region-tj{background-position:0 -3094px}#loco.wrap .variant-scotland,#loco.wrap .region-gb.lang-gd{background-position:0 -3106px}#loco.wrap .variant-valencia,#loco.wrap .region-es.variant-valencia{background-position:0 -3118px}#loco.wrap .variant-wales,#loco.wrap .region-gb.lang-cy{background-position:0 -3130px}#loco.wrap .x-eu{background-position:0 -3142px}#loco.wrap span.lang code{display:none}#loco.wrap .icon-notag:before{content:""}#loco.wrap .icon-python:before{content:"🐍"}#loco.wrap .icon-unicode:before{content:"u"}#loco.wrap .icon-json:before{content:"{"}#loco.wrap .icon-bullist:before{content:""}#loco.wrap .icon-numlist:before{content:""}#loco.wrap .icon-indent:before{content:""}#loco.wrap .icon-outdent:before{content:""}#loco.wrap .icon-link:before{content:""}#loco.wrap .icon-unlink:before{content:""}#loco.wrap .icon-bold:before{content:"B"}#loco.wrap .icon-italic:before{content:"I"}#loco.wrap .icon-translate:before{content:""}#loco.wrap .icon-proj:before{content:""}#loco.wrap .icon-plural:before{content:"᛬"}#loco.wrap .icon-max:before,#loco.wrap .icon-full-screen:before{content:""}#loco.wrap .icon-min:before{content:""}#loco.wrap .icon-sort:before{content:""}#loco.wrap .icon-ok:before,#loco.wrap .notice-success>.has-icon:before,#loco.wrap .notice-success p>strong.has-icon:before{content:"✓"}#loco.wrap .icon-ok-empty:before{content:"🗌"}#loco.wrap .icon-checkbox-checked:before,#loco.wrap .selector.multi li.checked .icon-checkbox:before{content:"☑"}#loco.wrap .icon-checkbox-unchecked:before{content:"☐"}#loco.wrap .icon-checkbox-partial:before{content:"☉"}#loco.wrap .icon-radio-checked:before{content:"⚫"}#loco.wrap .icon-radio-unchecked:before{content:"⚪"}#loco.wrap .icon-ext:before{content:"⬈"}#loco.wrap .icon-share:before{content:""}#loco.wrap .icon-star:before{content:""}#loco.wrap .icon-user:before{content:""}#loco.wrap .icon-remove:before{content:"×"}#loco.wrap .icon-cog:before{content:""}#loco.wrap .icon-trash:before{content:""}#loco.wrap .icon-time:before,#loco.wrap .icon-history:before{content:""}#loco.wrap .icon-download:before{content:""}#loco.wrap .icon-revert:before{content:""}#loco.wrap .icon-sync:before{content:""}#loco.wrap .icon-lock:before,#loco.wrap .notice-locked>.has-icon:before,#loco.wrap .notice-locked p>strong.has-icon:before{content:""}#loco.wrap .icon-flag:before{content:""}#loco.wrap .icon-tag:before{content:""}#loco.wrap .icon-tags:before{content:""}#loco.wrap .icon-print:before{content:""}#loco.wrap .icon-camera:before{content:""}#loco.wrap .icon-pencil:before{content:""}#loco.wrap .icon-add:before{content:""}#loco.wrap .icon-del:before{content:""}#loco.wrap .icon-clear:before,#loco.wrap a.icon.clear:before{content:""}#loco.wrap .icon-ok-sign:before{content:"✔"}#loco.wrap .icon-help:before{content:"?"}#loco.wrap .icon-info:before,#loco.wrap .notice-info>.has-icon:before,#loco.wrap .notice-info p>strong.has-icon:before{content:"ℹ"}#loco.wrap .icon-cancel:before{content:""}#loco.wrap .icon-warn:before,#loco.wrap .notice-error>.has-icon:before,#loco.wrap .notice-error p>strong.has-icon:before,#loco.wrap .notice-warning>.has-icon:before,#loco.wrap .notice-warning p>strong.has-icon:before{content:""}#loco.wrap .icon-comment:before{content:""}#loco.wrap .icon-bar-chart:before{content:""}#loco.wrap .icon-key:before{content:""}#loco.wrap .icon-cogs:before{content:""}#loco.wrap .icon-comments:before{content:""}#loco.wrap .icon-signout:before{content:""}#loco.wrap .icon-signin:before{content:""}#loco.wrap .icon-upload:before{content:""}#loco.wrap .icon-twitter:before{content:"🐦"}#loco.wrap .icon-facebook:before{content:""}#loco.wrap .icon-github:before{content:""}#loco.wrap .icon-feed:before{content:""}#loco.wrap .icon-globe:before{content:""}#loco.wrap .icon-wrench:before,#loco.wrap .notice-debug>.has-icon:before,#loco.wrap .notice-debug p>strong.has-icon:before{content:""}#loco.wrap .icon-group:before{content:""}#loco.wrap .icon-cloud:before{content:""}#loco.wrap .icon-copy:before{content:""}#loco.wrap .icon-save:before{content:""}#loco.wrap .icon-menu:before{content:""}#loco.wrap .icon-table:before{content:""}#loco.wrap .icon-caret-down:before{content:"▼"}#loco.wrap .icon-caret-up:before{content:"▲"}#loco.wrap .icon-caret-right:before{content:"▶"}#loco.wrap .icon-mail:before{content:""}#loco.wrap .icon-cloud-upload:before{content:""}#loco.wrap .icon-file:before{content:""}#loco.wrap .icon-circle-white:before{content:"⚬"}#loco.wrap .icon-circle-black:before{content:"●"}#loco.wrap .icon-eraser:before{content:""}#loco.wrap .icon-unlock:before{content:""}#loco.wrap .icon-apple:before{content:""}#loco.wrap .icon-android:before{content:""}#loco.wrap .icon-robot:before{content:"🤖"}#loco.wrap .icon-back:before{content:"⬅"}#loco.wrap .icon-next:before{content:"➔"}#loco.wrap .icon-arrow-up:before{content:""}#loco.wrap .icon-ccard:before{content:""}#loco.wrap .icon-caret-left:before{content:"◀"}#loco.wrap .icon-pro:before{content:"⚡"}#loco.wrap .icon-bell:before{content:""}#loco.wrap .icon-code:before{content:""}#loco.wrap .icon-privacy:before{content:"🛡"}#loco.wrap .icon-hellip:before{content:"…"}#loco.wrap .icon-vellip:before{content:"⁞"}#loco.wrap .icon-collapse:before{content:""}#loco.wrap .icon-expand:before{content:""}#loco.wrap .icon-wordpress:before{content:""}#loco.wrap .icon-database:before{content:""}#loco.wrap .icon-restore:before{content:""}#loco.wrap .icon-pilcrow:before{content:"¶"}#loco.wrap .icon,#loco.wrap .has-icon:before,#loco.wrap .has-dashicon:before{speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco.wrap .icon,#loco.wrap .has-icon:before{font-family:"loco"}#loco.wrap .has-dashicon:before{font-family:"dashicons";font-size:1.4em}#loco.wrap .has-icon:before,#loco.wrap .has-dashicon:before,#loco.wrap .has-icon>span{display:inline-block;vertical-align:middle}#loco.wrap .only-icon{text-align:center}#loco.wrap .only-icon:before{text-align:center;padding:0}#loco.wrap .only-icon span{display:none}#loco.wrap a,#loco.wrap .wp-core-ui .button-link{text-decoration:none}#loco.wrap h3:hover>a.loco-anchor{color:#ccc}#loco.wrap h3:hover>a.loco-anchor:before{content:"¶"}#loco.wrap .has-lang>span{display:inline-block;vertical-align:middle}#loco.wrap a.has-lang:hover>span:last-child{text-decoration:underline}#loco.wrap h1 ul,#loco.wrap h1 li{margin:0;padding:0}#loco.wrap h1 li{display:inline-block}#loco.wrap h1 li:after{content:"/";color:#999;text-shadow:none;display:inline-block}#loco.wrap h1 li:last-child:after{content:""}#loco.wrap h1 li:last-child a{color:inherit;pointer-events:none;cursor:auto}#loco.wrap h2 span{color:#999;font-weight:normal}#loco.wrap h2 .loco-meta,#loco.wrap h3 .loco-meta{color:inherit;font-size:14px;font-weight:normal;vertical-align:middle}#loco.wrap .wp-list-table td:first-child .icon{width:16px;display:inline-block;text-align:center}#loco.wrap .wp-list-table td{white-space:nowrap}#loco.wrap .wp-list-table td>a,#loco.wrap .wp-list-table td>time{display:inline-block;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}#loco.wrap .wp-list-table th.loco-sort{cursor:pointer}#loco.wrap .wp-list-table th.loco-sort:hover{color:#000}#loco.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco.wrap .wp-list-table th.loco-sort.loco-desc:after{padding:0 0 0 4px;color:#999}#loco.wrap .wp-list-table th.loco-sort.loco-desc:after{content:"▼"}#loco.wrap .wp-list-table th.loco-sort.loco-asc:after{content:"▲"}#loco.wrap .wp-list-table td.has-row-actions{overflow:visible}#loco.wrap form.loco-filter{display:block;margin-bottom:5px}#loco.wrap form.loco-filter .icon-filter{color:#999}#loco.wrap nav.above-list-table{margin-bottom:1em}#loco.wrap nav.above-list-table a{display:inline-block;margin-right:1em}#loco.wrap .wp-core-ui button.inverted,#loco.wrap .wp-core-ui button.inverted:hover,#loco.wrap .po-fuzzy button.icon-cloud{background:-moz-linear-gradient(top, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);background:-webkit-linear-gradient(top, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);background:linear-gradient(to bottom, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);-webkit-box-shadow:0 1px 0 #fff;-moz-box-shadow:0 1px 0 #fff;box-shadow:0 1px 0 #fff;border-color:gray}#loco.wrap .wp-core-ui button:active,#loco.wrap .wp-core-ui button.inverted:active{border-color:#5b9dd9}#loco.wrap .loco-clearable{display:inline-block;vertical-align:middle;position:relative}#loco.wrap .loco-clearable a.clear,#loco.wrap .auto-comp-wrap a.clear{top:0;right:0;outline:none;margin:0;border:solid 1px transparent;padding:5px 5px;position:absolute;font-size:1em;line-height:normal}#loco.wrap .loco-clearable a.clear:before,#loco.wrap .auto-comp-wrap a.clear:before{vertical-align:middle;padding:0;color:#999}#loco.wrap .loco-clearable a.clear:hover:before,#loco.wrap .auto-comp-wrap a.clear:hover:before{color:#333}#loco.wrap .loco-clearable a.clear span,#loco.wrap .auto-comp-wrap a.clear span{display:none}#loco.wrap .loco-clearable ::-ms-clear,#loco.wrap .auto-comp-wrap ::-ms-clear{display:none}#loco.wrap div.progress{color:#000;background:transparent !important}#loco.wrap div.progress *{height:100%;overflow:hidden;white-space:nowrap}#loco.wrap div.progress .t{background-color:#ddd;border:1px solid #ccc}#loco.wrap div.progress .t .bar{float:left;clear:none;background-color:#3db63d}#loco.wrap div.progress .t .bar.f{background-color:#bd2c00}#loco.wrap div.progress .l{display:block}#loco.wrap td div.progress .t{border:none}#loco.wrap td div.progress .l{display:none}#loco.wrap code.path{color:#333;margin:0;padding:0;display:inline;background:transparent}#loco.wrap .loco-danger{color:#d54e21}#loco.wrap .notice,#loco.wrap .panel{background:#fff;position:relative;margin:1em 0;padding:1px 12px}#loco.wrap .notice-generic{border-color:#ddd}#loco.wrap .notice-success>.has-icon,#loco.wrap .notice-success p>strong.has-icon{color:#000}#loco.wrap .notice-warning{border-color:orange}#loco.wrap .notice-error{border-color:#dc3232}#loco.wrap .notice-debug{border-color:#00a0d2}#loco.wrap .notice-danger{border-color:#dc3232}#loco.wrap .notice-locked{border-color:orange}#loco.wrap .notice>.has-icon:before,#loco.wrap .notice p>strong.has-icon:before{padding-right:6px}#loco.wrap .notice>p>a.button.has-icon:before{width:1.2em}#loco.wrap .notice>p>em{color:#d54e21;font-style:normal}#loco.wrap .notice>p>em a{color:inherit}#loco.wrap .notice>p a:hover,#loco.wrap .notice>nav a:hover{text-decoration:underline}#loco.wrap .notice>p a.button,#loco.wrap .notice>nav a.button{text-decoration:inherit}#loco.wrap .notice.has-nav{display:flex;flex-direction:row}#loco.wrap .notice.has-nav p,#loco.wrap .notice.has-nav nav{line-height:22px;flex-grow:1}#loco.wrap .notice.has-nav nav{text-align:right;padding:2px;margin:.5em 0}#loco.wrap .notice.has-nav.is-dismissible{padding-right:38px}#loco.wrap .notice.has-nav a{white-space:nowrap}#loco.wrap .notice.has-nav nav>span{color:#666}#loco.wrap .notice>h3>span{display:inline-block;vertical-align:middle}#loco.wrap ul.problems li{font-style:italic}#loco.wrap label{position:relative}#loco.wrap label.for-disabled,#loco.wrap label.for-disabled>input{cursor:default !important}#loco.wrap input.regular-text,#loco.wrap textarea.regular-text{width:25em}#loco.wrap .button-link{padding:0 10px 1px}#loco.wrap .button-danger{background:#ba0000;border-color:#900 #600 #600;-webkit-box-shadow:0 1px 0 #600;-moz-box-shadow:0 1px 0 #600;box-shadow:0 1px 0 #600;color:#fff;text-shadow:0 -1px 1px #600,1px 0 1px #600,0 1px 1px #600,-1px 0 1px #600}#loco.wrap .button-success{background:#00b500;border-color:#090 #2e892e #2e892e;-webkit-box-shadow:0 1px 0 #2e892e;-moz-box-shadow:0 1px 0 #2e892e;box-shadow:0 1px 0 #2e892e;color:#fff;text-shadow:0 -1px 1px #2e892e,1px 0 1px #2e892e,0 1px 1px #2e892e,-1px 0 1px #2e892e}#loco.wrap .button-success:hover{background:#3db63d}#loco.wrap form button.loco-loading.button-large{padding-left:0}#loco.wrap form button.loco-loading.button-large:before{width:16px;height:16px;margin:0 4px;content:" ";font-size:16px;line-height:1;display:inline-block;vertical-align:sub}#loco.wrap ::placeholder{color:#ccc}#loco.wrap ::-webkit-input-placeholder{color:#ccc}#loco.wrap :-moz-placeholder{color:#ccc;opacity:1}#loco.wrap ::-moz-placeholder{color:#ccc;opacity:1}#loco.wrap :-ms-input-placeholder{color:#ccc}#loco.wrap .ielt10 .placeheld{color:#ccc}#loco.wrap a.has-raquo:after{content:" »"}#loco.wrap a.has-laquo:before{content:"« "}#loco.wrap span.inline-spinner{display:inline-block;min-width:16px;min-height:16px;background:transparent url(../img/spin-modal.gif?v=2.4.0) 0 0 no-repeat}.js #wpbody-content>.notice{display:none}.js #wpbody-content>.notice.inline{display:block}.js #loco.wrap .jshide,.no-js #loco.wrap .jsonly{display:none !important}#loco.wrap .invis{visibility:hidden}.form-table tr{vertical-align:top}.form-table tr.compact td{padding-top:0}.loco-modal{min-width:50%;min-height:100px}.loco-modal-wide{min-width:90% !important}.loco-modal.request-filesystem-credentials-dialog{top:15% !important;max-height:85% !important}.loco-modal.request-filesystem-credentials-dialog>.ui-dialog-content{background:inherit}.loco-modal.request-filesystem-credentials-dialog .ftp-password>label>em:last-child{display:none}.ui-dialog-content>div.loco-loading{height:100%;background:transparent url(../img/spin-modal.gif?v=2.4.0) center 20px no-repeat}#loco-po-ref ol li{color:#aaa;margin:0;white-space:pre;padding:0 0 0 1em;font:normal 12px/17px Consolas,Monaco,monospace;background:transparent;border-left:1px solid #eee}#loco-po-ref ol li code{margin:0;padding:0;display:inline;background:inherit}#loco-po-ref ol li.highlighted{color:#666;background-color:#f8eec7}#loco-po-ref ol li.highlighted code.T_CONSTANT_ENCAPSED_STRING{color:#c931c7}#loco-credit>*{vertical-align:middle}#loco-credit>a{display:inline-block;position:relative;overflow:hidden;background:transparent url(../img/logo-foot.gif?v=2.4.0) 0 0 no-repeat;height:30px;width:100px;text-indent:200px;-webkit-transition-duration:0s;transition-duration:0s}#loco-credit>a:hover{background-position:0 -35px}#loco-content{position:relative}#footer-upgrade span:before{color:#ccc;content:" | ";display:inline;padding-left:.5em;padding-right:.5em}#footer-upgrade span:first-child:before{content:"";display:none}.loco-clearfix:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}dl.debug dt{font-weight:bold}dl.debug dt,dl.debug dd{white-space:pre}.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(0,115,170,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#0073aa}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../img/skins/fresh/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/bundle.css b/vendor/loco-translate/pub/css/bundle.css new file mode 100644 index 0000000..f0d4090 --- /dev/null +++ b/vendor/loco-translate/pub/css/bundle.css @@ -0,0 +1 @@ +form.loco-filter{float:right}@media only screen and (max-width: 1024px){table.wp-list-table a.row-title{max-width:100px}} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/config.css b/vendor/loco-translate/pub/css/config.css new file mode 100644 index 0000000..a2196ab --- /dev/null +++ b/vendor/loco-translate/pub/css/config.css @@ -0,0 +1 @@ +form#loco-conf>div{overflow:visible;border-bottom:solid 1px #ccc;padding-top:2em}form#loco-conf>div h2{margin-top:0}form#loco-conf td.twin>div{float:left;clear:none;width:50%}form#loco-conf td .description:first-child{margin-top:0;margin-bottom:4px}form#loco-conf a.icon-del{display:block;float:right;z-index:99;color:#aaa;outline:none}form#loco-conf a.icon-del:hover{color:#c00}form#loco-conf>div:first-child a.icon-del{display:none}form#loco-conf p.description{color:#aaa;font-size:12px;text-indent:.25em}form#loco-conf tr:hover p.description{color:#666}form#loco-reset{position:absolute;bottom:0;right:0} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/editor.css b/vendor/loco-translate/pub/css/editor.css new file mode 100644 index 0000000..77f1be5 --- /dev/null +++ b/vendor/loco-translate/pub/css/editor.css @@ -0,0 +1 @@ +#loco-editor{border:solid 1px #ccc}#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}#loco-editor ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.4.0) 0 0 no-repeat;min-height:75px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.4.0);background-size:16px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.4.0);background-size:16px}}#loco-editor ._green_glow_inner,#loco-editor .is-editable>.wg-content>textarea:focus,#loco-editor .is-editable>.wg-content.has-focus .ace_scroller,#loco-editor .is-editable>.wg-content.has-focus .wysihtml-editor,#loco-editor .is-editable>.wg-content.has-focus .mce-content-body{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-editor ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-editor .loco-font,#loco-editor .is-table .wg-thead .wg-sortable>header:after{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-editor div.ta-mirror{position:absolute;top:0;border:solid 1px transparent;color:transparent;padding:.4em .6em;pointer-events:none}#loco-editor div.ta-mirror span{position:relative}#loco-editor div.ta-mirror span:after{color:#ccc;white-space:pre;display:inline-block;position:absolute;top:0;line-height:normal}#loco-editor div.ta-mirror .crlf:after{content:"¬"}#loco-editor div.ta-mirror .eof:after{content:"¶"}#loco-editor div.ta-mirror .x20:after{content:"·";color:#aaa}#loco-editor div.ta-mirror .x9:after{content:"⟶"}#loco-editor div.ta-mirror,#loco-editor .has-mirror textarea{white-space:pre-wrap;word-wrap:break-word;word-spacing:0px}#loco-editor .has-mirror ::placeholder{color:transparent}#loco-editor .has-mirror ::-webkit-input-placeholder{color:transparent}#loco-editor .has-mirror :-moz-placeholder{color:transparent;opacity:1}#loco-editor .has-mirror ::-moz-placeholder{color:transparent;opacity:1}#loco-editor .has-mirror :-ms-input-placeholder{color:transparent}#loco-editor .has-mirror .ielt10 .placeheld{color:transparent}#loco-editor div.ta-mirror{left:0;text-align:left}#loco-editor div.ta-mirror span:after{left:0}#loco-editor div.ta-mirror .eol:after{padding-left:.2em}#loco-editor [dir=RTL] div.ta-mirror{left:auto;right:0;text-align:right}#loco-editor [dir=RTL] div.ta-mirror span:after{right:0}#loco-editor [dir=RTL] div.ta-mirror .eol:after{padding-left:0;padding-right:.2em}#loco-editor .has-proxy>textarea{display:none !important}#loco-editor .has-proxy .ace_editor{height:100%;font-size:13px !important;line-height:1.4 !important}#loco-editor .has-proxy .ace_editor .ace_marker-layer .ace_bracket{display:none}#loco-editor .has-proxy .ace_print-margin{display:none}#loco-editor .ace_printf{color:#b90690;background-color:#edf1be}#loco-editor .ace_locked{color:gray}#loco-editor .ace_icu-quoted{color:gray}#loco-editor .ace_icu{color:#697eb9}#loco-editor .ace_icu.ace_name{color:#b90600}#loco-editor .resizer{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0 0 6px 0;background:#f0f0f0 url(../img/wg/splity.png?v=2.4.0) center bottom no-repeat;border:1px solid #ddd;overflow:hidden;cursor:move;cursor:row-resize;cursor:s-resize}#loco-editor .resizer>*{height:100%;border:none}#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}#loco-editor ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.4.0) 0 0 no-repeat;min-height:75px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.4.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.4.0);background-size:16px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.4.0);background-size:16px}}#loco-editor ._green_glow_inner,#loco-editor .is-editable>.wg-content>textarea:focus,#loco-editor .is-editable>.wg-content.has-focus .ace_scroller,#loco-editor .is-editable>.wg-content.has-focus .wysihtml-editor,#loco-editor .is-editable>.wg-content.has-focus .mce-content-body{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-editor ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-editor .loco-font,#loco-editor .is-table .wg-thead .wg-sortable>header:after{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-editor .wg-cell,#loco-editor .wg-cell>div{clear:both;position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;outline:none}#loco-editor .wg-cell{left:0;top:0;padding:0;margin:0;overflow:hidden}#loco-editor .wg-split{background:#eee}#loco-editor .wg-body:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}#loco-editor .wg-split-x>div>.not-first>*{margin-left:6px}#loco-editor .wg-split-y>div>.not-first>*{margin-top:6px}#loco-editor .wg-split>div>.has-title .wg-content{margin-top:0}#loco-editor .wg-split-x>div>.wg-cell{float:left;clear:none;height:100%}#loco-editor .wg-split-x>div{cursor:move;cursor:ew-resize;cursor:col-resize}#loco-editor .wg-split>div>.not-first:before{display:block;position:absolute;overflow:hidden;content:" "}#loco-editor .wg-split-x>div>.not-first:before{width:6px;height:100%;background:transparent url(../img/wg/splitx.png?v=2.4.0) center center no-repeat}#loco-editor .wg-split-y>div{cursor:move;cursor:ns-resize;cursor:row-resize}#loco-editor .wg-split-y>div>.not-first:before{height:6px;width:100%;background:transparent url(../img/wg/splity.png?v=2.4.0) center center no-repeat}#loco-editor .wg-split>div.locked{cursor:default}#loco-editor .wg-split-x>div.locked>.not-first>*{margin-left:0px}#loco-editor .wg-split-y>div.locked>.not-first>*{margin-top:0px}#loco-editor .wg-split>div.locked>.not-first:before{display:none}#loco-editor .has-title>header{background:#e2e2e2;cursor:default !important;margin:0;white-space:nowrap}#loco-editor .wg-content{background:#fff;cursor:default;padding:4px 6px;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#loco-editor .wg-toolbar{top:0;right:0;margin-top:6px;position:absolute}#loco-editor .wg-toolbar>span{color:#fff;background:#000;display:block;padding:0 6px;cursor:default !important}#loco-editor .wg-toolbar>span:active{color:#000;background-color:#fff}#loco-editor .wg-content,#loco-editor .wg-tbody>div{overflow:scroll;overflow-x:hidden;overflow-y:auto}#loco-editor .is-table{background-color:#fff}#loco-editor .is-table .wg-thead .has-title>header{font-weight:normal;background:transparent;padding:4px 0;margin:0 0 0 10px}#loco-editor .is-table .wg-thead>div>.not-first:before{background-position:center center}#loco-editor .is-table .wg-thead{background:#e2e2e2;border-bottom:solid 1px #ccc}#loco-editor .is-table .wg-tbody{background-image:url(data:image/gif;base64,R0lGODlhAQAsAIABAPz8/P///yH5BAEAAAEALAAAAAABACwAAAIIjI+pAe0PIygAOw==);position:relative}#loco-editor .is-table .wg-cols>div{float:left;clear:none}#loco-editor .is-table .wg-cols>div>div{white-space:nowrap;line-height:1.7em;padding-left:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;background-color:#fff}#loco-editor .is-table .wg-cols>div>div:nth-child(even){background-color:#f7f7f7}#loco-editor .is-table .wg-cols>div>div.selected{background-color:#3db63d;color:#fff}#loco-editor .is-table .wg-cols>div>div.selected::selection{background-color:#fff;color:#000}#loco-editor .is-table .wg-cols>div:first-child>div{padding-left:4px}#loco-editor .is-table .wg-dead{clear:both}#loco-editor .is-table .wg-thead .wg-sortable>header{cursor:pointer !important}#loco-editor .is-table .wg-thead .wg-sortable>header:after{padding:0 0 0 5px;color:#999}#loco-editor .is-table .wg-thead .wg-sortable.wg-asc>header:after{content:"▲"}#loco-editor .is-table .wg-thead .wg-sortable.wg-desc>header:after{content:"▼"}#loco-editor .is-table .wg-thead .wg-sortable:hover>header:after{color:#000}#loco-editor .is-field>.wg-content{cursor:text;padding:0;line-height:normal;overflow:hidden;overflow-y:hidden}#loco-editor .is-field>.wg-content>div,#loco-editor .is-field>.wg-content>textarea{font-size:14px;line-height:1.4;border:1px solid #ddd;width:100%;height:100%;padding:8px 10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0}#loco-editor .is-field>.wg-content textarea{resize:none;overflow:auto;display:block}#loco-editor .is-field>.wg-content>.ace_editor{padding:0;border-width:0}#loco-editor .is-field>.wg-content>div[contenteditable]{overflow:scroll;overflow-x:hidden;overflow-y:auto}#loco-editor .is-readonly>.wg-content{cursor:default}#loco-editor .is-readonly>.wg-content>div,#loco-editor .is-readonly>.wg-content>textarea,#loco-editor .is-readonly>.wg-content>textarea[readonly]{background:#f8f8f8;text-shadow:0 1px #fff;color:inherit}#loco-editor .is-readonly>.wg-content .ace_scroller{cursor:default;background:#f8f8f8}#loco-editor .is-readonly>.wg-content .ace_cursor-layer{display:none}#loco-editor .is-readonly>.wg-content>textarea[readonly]{cursor:default}#loco-editor .is-editable>.wg-content[dir=RTL] .ace_editor .ace_line{direction:ltr;unicode-bidi:bidi-override}#loco-editor .wg-split-x>nav.wg-tabs{white-space:nowrap;text-align:center;cursor:default}#loco-editor .wg-split-x>nav.wg-tabs>a{display:inline-block;padding:.5em 1em;margin-top:.2em;color:#000;text-decoration:none;-webkit-border-radius:.2em .2em 0 0;-moz-border-radius:.2em .2em 0 0;-ms-border-radius:.2em .2em 0 0;-o-border-radius:.2em .2em 0 0;border-radius:.2em .2em 0 0;background-color:#f3f7fd}#loco-editor .wg-split-x>nav.wg-tabs>a:hover{background-color:#fff}#loco-editor .wg-split-x>nav.wg-tabs>a.active{background-color:#3db63d;color:#fff}#loco-editor .wg-split>div>.has-nav>.wg-body{margin-top:0px}#loco-editor .wg-dead{visibility:hidden}@media all and (max-width: 768px){#loco-editor .wg-split-x>div>.not-first>*{margin-left:20px}#loco-editor .wg-split-y>div>.not-first>*{margin-top:20px}#loco-editor .wg-split-x>div>.not-first:before{width:20px}#loco-editor .wg-split-y>div>.not-first:before{height:20px}#loco-editor .is-table .wg-thead header{padding-left:20px}}#loco-editor .is-table .po-fuzzy{color:#b59829;font-weight:bold}#loco-editor .is-table .po-empty{color:#1f507a;font-weight:bold}#loco-editor .is-table .po-flagged{color:#bd2c00}#loco-editor .is-table .wg-cols>div:first-child>div:before{font-family:loco;vertical-align:inherit;display:inline-block;content:" ";width:1.3em;line-height:1}#loco-editor .is-table .wg-cols>div:first-child>div.po-fuzzy:before{content:""}#loco-editor .is-table .wg-cols>div:first-child>div.po-flagged:before{content:""}#loco-editor .is-table .wg-cols>div:first-child>div.po-comment:before{content:"";color:#999}#loco-editor .is-table .wg-cols>div:first-child>div.po-unsaved:before{content:"";color:#f1d040}#loco-editor .is-table .wg-cols>div:first-child>div.selected:before{color:#fff !important}#loco-editor .wg-cell>.meta{color:#333;margin:0 !important;padding:6px 10px;font-weight:normal;font-size:13px;line-height:1.4em;cursor:default !important}#loco-editor .wg-cell>.meta>*{display:inline-block;margin-top:3px;margin-bottom:3px}#loco-editor .wg-cell>.meta>span{border:1px solid transparent;border-left:none}#loco-editor .wg-cell>.meta>mark{color:#fff;border-radius:2px;background-color:silver;border:1px solid silver;padding:0 .3em}#loco-editor .wg-cell>.meta>mark.tag{color:#999;background-color:#eee}#loco-editor .wg-cell>.meta>p{display:block;white-space:pre-line}#loco-editor .wg-cell>.meta .icon-warn{color:#c00}#loco-editor .wg-cell>.meta .has-icon:before{padding-right:0;width:17px}#loco-editor .wg-cell>.meta code{font-size:12px}#loco-editor .is-table .wg-cols>div>div>mark{display:inline-block;vertical-align:text-bottom;font:inherit;font-weight:normal;color:#fff;border-radius:2px;font-size:90%;line-height:1;padding:.2em .3em;background-color:rgba(0,0,0,.25)}#loco-editor .is-table .wg-cols>div>div.selected.po-flagged{background-color:#bd2c00}#loco-editor .is-table .wg-cols>div>div.selected.po-fuzzy{background-color:#b59829}#loco-editor .is-table .wg-cols>div>div.selected.po-empty{background-color:#999}#loco-editor #po-target header nav{display:block;position:absolute;right:0px;top:0px;padding:2px}#loco-editor #po-target header nav button{margin-left:5px}#loco-editor #po-target header nav.po-empty .icon-cloud{display:none !important}#loco-editor #po-list .wg-content{padding:0}#loco-editor #po-source>.wg-body>.has-title>header{background:transparent;font-weight:normal;float:left;clear:none;min-width:3.4em}#loco-editor #po-source>.wg-body>.has-title>.wg-content{clear:none}#loco-editor .has-title>header{line-height:normal;padding:6px}#loco-editor .has-title>header .lang{margin-right:6px;margin-bottom:1px}#loco-editor .trg-rtl #po-list-tbody .wg-cols>div[for=po-list-col-target]>div,#loco-editor .src-rtl #po-list-tbody .wg-cols>div[for=po-list-col-source]>div{direction:rtl;padding-left:0;padding-right:10px;text-align:right}#loco-editor #po-source>.wg-body>.has-title>h2{min-width:4.5em}#loco-editor .is-table .wg-td{font-size:13px}#loco-editor header,#loco-editor nav{display:block;position:relative}#loco-editor-inner{min-height:600px;font-size:14px;clear:both}#loco-editor-inner>div.loco-loading{height:100px;background:transparent url(../img/spin-editor-button.gif?v=2.4.0) center 20px no-repeat}#loco-editor-inner h2{color:#000;line-height:1}#loco-editor-inner .wg-cell>.meta code{padding:0;color:#0073aa;background:inherit;cursor:pointer}#loco-editor-inner .wg-cell>.meta code:hover{text-decoration:underline}#loco.wrap #loco-toolbar{font-size:14px;height:50px}#loco.wrap #loco-toolbar form{display:block;float:left;clear:none;padding:0;margin:0}#loco.wrap #loco-toolbar form.aux{float:right;margin-right:5px}#loco.wrap #loco-toolbar fieldset{display:block;position:relative;float:left;clear:none}#loco.wrap #loco-toolbar button,#loco.wrap #loco-toolbar input[type=text]{display:block;position:relative;float:left;clear:none;margin:5px 0 0 5px;height:36px;text-align:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#loco.wrap #loco-toolbar input[type=text]{padding:0 10px;font-size:14px;line-height:normal}#loco.wrap #loco-toolbar .invalid input[type=text]:focus{border-color:#c00;-webkit-box-shadow:0 0 2px rgba(153,0,0,.5);-moz-box-shadow:0 0 2px rgba(153,0,0,.5);box-shadow:0 0 2px rgba(153,0,0,.5)}#loco.wrap #loco-toolbar .loco-clearable{padding:0 20px}#loco.wrap #loco-toolbar .loco-clearable.invalid a.clear:before{color:#c00}#loco.wrap #loco-toolbar .loco-clearable a.clear{right:25px;line-height:2}#loco.wrap #loco-toolbar .loco-clearable a.clear:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}#loco.wrap #loco-toolbar .loco-clearable a.clear:hover:before{color:#c00}#loco.wrap #loco-toolbar .loco-clearable a.clear:active:before{color:#000}#loco.wrap #loco-toolbar button.only-icon{width:40px}#loco.wrap button.has-icon:before{width:16px;padding:0}#loco.wrap button.has-icon.loco-loading:before{content:" ";height:16px;background:transparent url(../img/spin-editor-button.gif?v=2.4.0) 0 0 no-repeat}#loco.wrap .button,#loco.wrap .button-link,#loco.wrap input[type=text]{border-color:#aaa;color:#444}#loco.wrap .button-primary{color:#fff}#loco.wrap button.icon-translate:before{font-size:16px}.loco-modal .loco-api{position:relative;padding:10px;background:#f7f7f7;border:solid 1px #eee;font-size:14px;margin-bottom:16px}.loco-modal .loco-api p{padding:0;margin:0;font-size:inherit}.loco-modal .loco-api blockquote{font-weight:bold;margin:0;padding:10px 0}.loco-modal .loco-api a.loco-api-credit{padding:0;display:block;position:absolute;right:10px;bottom:10px;text-decoration:none;white-space:nowrap;overflow:hidden;font-size:12px}.loco-modal .loco-api a.loco-api-credit:hover{text-decoration:underline}.loco-modal .loco-api-loading{text-indent:20px;background:transparent url(../img/spin-modal.gif?v=2.4.0) 10px center no-repeat}.loco-modal .loco-alert p{margin-bottom:2em;font-size:14px}.loco-modal .loco-alert nav{display:block;position:relative;margin:1em 0}.loco-modal .loco-alert nav a{display:inline-block;margin-right:1em;padding:10px}#loco-auto{display:none;min-width:50%;min-height:300px;position:relative}#loco-auto form blockquote{margin:0;padding:1em 0;font-size:14px}.loco-api a.loco-api-credit{color:inherit}.loco-api-yandex a.loco-api-credit:before{content:"Powered by "}.loco-api-google a.loco-api-credit{text-indent:200px;width:122px;height:16px;background:transparent url(../img/api/google.png?v=2.4.0) 0 0 no-repeat}.loco-api-microsoft a.loco-api-credit{text-indent:200px;width:152px;height:16px;background:transparent url(../img/api/microsoft.png?v=2.4.0) 0 0 no-repeat}.loco-api-microsoft a.loco-api-credit:before{content:"Translated by "} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/fileinfo.css b/vendor/loco-translate/pub/css/fileinfo.css new file mode 100644 index 0000000..ddcdd48 --- /dev/null +++ b/vendor/loco-translate/pub/css/fileinfo.css @@ -0,0 +1 @@ +#loco.wrap .notice-info dl{margin-top:0;display:inline-block}#loco.wrap .notice-info dl dt,#loco.wrap .notice-info dl dd{line-height:1.4em}#loco.wrap .notice-info dl dt{font-weight:bold;color:#555}#loco.wrap .notice-info dl dd{margin-left:0;margin-bottom:.8em}#loco.wrap .notice-info dl div.progress .l{display:none} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/locale.css b/vendor/loco-translate/pub/css/locale.css new file mode 100644 index 0000000..3f88011 --- /dev/null +++ b/vendor/loco-translate/pub/css/locale.css @@ -0,0 +1 @@ +#loco.wrap td.loco-not-active{color:#aaa}#loco.wrap div.loco-projects>h3{float:left}#loco.wrap div.loco-projects form.loco-filter{float:right;margin:1em 0} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/podiff.css b/vendor/loco-translate/pub/css/podiff.css new file mode 100644 index 0000000..e73ff8a --- /dev/null +++ b/vendor/loco-translate/pub/css/podiff.css @@ -0,0 +1 @@ +#loco.wrap .revisions-diff{padding:10px;min-height:20px}#loco.wrap table.diff{border-collapse:collapse}#loco.wrap table.diff td{white-space:nowrap;overflow:hidden;font:normal 12px/17px "Monaco","Menlo","Ubuntu Mono","Consolas","source-code-pro",monospace;padding:2px}#loco.wrap table.diff td>span{color:#aaa}#loco.wrap table.diff td>span:after{content:". "}#loco.wrap table.diff tbody{border-top:1px dashed #ccc}#loco.wrap table.diff tbody:first-child{border-top:none}#loco.wrap .revisions.loading .diff-meta{color:#eee}#loco.wrap .revisions.loading .loading-indicator span.spinner{visibility:visible;background:#fff url(../img/spin-modal.gif?v=2.4.0) center center no-repeat}#loco.wrap .revisions-meta{clear:both;padding:10px 12px;margin:0;position:relative;top:10px}#loco.wrap .revisions-meta .diff-meta{clear:none;float:left;width:50%;padding:0;min-height:auto}#loco.wrap .revisions-meta .diff-meta button{margin-top:5px}#loco.wrap .revisions-meta .diff-meta-current{float:right;text-align:right}#loco.wrap .revisions-meta time{color:#72777c}#loco.wrap .revisions-control-frame{margin:10px 0}#loco.wrap .revisions-diff-frame{margin-top:20px} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/poinit.css b/vendor/loco-translate/pub/css/poinit.css new file mode 100644 index 0000000..b961105 --- /dev/null +++ b/vendor/loco-translate/pub/css/poinit.css @@ -0,0 +1 @@ +form#loco-poinit .loco-locales fieldset{float:left;margin-right:2em}form#loco-poinit .loco-locales fieldset.disabled span.lang{visibility:hidden !important}form#loco-poinit .loco-locales fieldset span.nolang{background:#999}form#loco-poinit .loco-locales fieldset>label span{width:20px;text-align:center;display:inline-block;margin-right:4px}form#loco-poinit a.icon-help{color:#999;font-style:normal;text-decoration:none}form#loco-poinit a.icon-help:hover{color:#666}form#loco-poinit .form-table th{padding:15px 10px}form#loco-poinit .form-table tr:first-child td,form#loco-poinit .form-table tr:first-child th{padding-top:25px}form#loco-poinit label.for-disabled input{visibility:hidden}form#loco-poinit label.for-disabled .icon-lock{top:0;left:0;display:block;position:absolute;width:1em;font-size:14px;text-align:center;color:gray} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/poview.css b/vendor/loco-translate/pub/css/poview.css new file mode 100644 index 0000000..0bb35ca --- /dev/null +++ b/vendor/loco-translate/pub/css/poview.css @@ -0,0 +1 @@ +.js #loco.wrap .loco-loading{min-height:100px;background:#fff url(../img/spin-modal.gif?v=2.4.0) center center no-repeat}.js #loco.wrap .loco-loading ol.msgcat{display:none}#loco.wrap #loco-po{padding-right:0;overflow:auto}#loco.wrap ol.msgcat{margin-left:3em;padding-top:1em;border-top:1px dashed #ccc}#loco.wrap ol.msgcat:first-child{padding-top:0;border-top:none}#loco.wrap ol.msgcat li{color:#aaa;margin:0;padding:0 0 0 1em;font:normal 12px/17px "Monaco","Menlo","Ubuntu Mono","Consolas","source-code-pro",monospace;border-left:1px solid #eee}#loco.wrap ol.msgcat li>*{color:#333;white-space:pre}#loco.wrap ol.msgcat li>.po-comment{color:#3cc200}#loco.wrap ol.msgcat li>.po-refs{color:#0073aa}#loco.wrap ol.msgcat li>.po-refs a{color:inherit;text-decoration:none}#loco.wrap ol.msgcat li>.po-refs a:hover{text-decoration:underline}#loco.wrap ol.msgcat li>.po-flags{color:#77904a}#loco.wrap ol.msgcat li>.po-flags em{font-style:normal}#loco.wrap ol.msgcat li>.po-word{color:#000}#loco.wrap ol.msgcat li>.po-junk{font-style:italic;color:#ccc}#loco.wrap ol.msgcat li>.po-string>span{color:#c931c7}#loco.wrap form.loco-filter{top:0;right:0;position:absolute}#loco.wrap .loco-invalid form.loco-filter input[type=text]:focus{border-color:#c00;-webkit-box-shadow:0 0 2px rgba(153,0,0,.5);-moz-box-shadow:0 0 2px rgba(153,0,0,.5);box-shadow:0 0 2px rgba(153,0,0,.5)}#loco.wrap .loco-invalid ol.msgcat{list-style-type:none}#loco.wrap .loco-invalid ol.msgcat li{color:#000} \ No newline at end of file diff --git a/vendor/loco-translate/pub/css/skins/blue.css b/vendor/loco-translate/pub/css/skins/blue.css new file mode 100644 index 0000000..ddc9d99 --- /dev/null +++ b/vendor/loco-translate/pub/css/skins/blue.css @@ -0,0 +1 @@ +.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(9,100,132,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#096484}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../../img/skins/blue/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} diff --git a/vendor/loco-translate/pub/css/skins/coffee.css b/vendor/loco-translate/pub/css/skins/coffee.css new file mode 100644 index 0000000..68fbc45 --- /dev/null +++ b/vendor/loco-translate/pub/css/skins/coffee.css @@ -0,0 +1 @@ +.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(199,165,137,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#c7a589}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../../img/skins/coffee/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} diff --git a/vendor/loco-translate/pub/css/skins/ectoplasm.css b/vendor/loco-translate/pub/css/skins/ectoplasm.css new file mode 100644 index 0000000..b5be89c --- /dev/null +++ b/vendor/loco-translate/pub/css/skins/ectoplasm.css @@ -0,0 +1 @@ +.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(163,183,69,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#a3b745}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../../img/skins/ectoplasm/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} diff --git a/vendor/loco-translate/pub/css/skins/light.css b/vendor/loco-translate/pub/css/skins/light.css new file mode 100644 index 0000000..c0ff7fa --- /dev/null +++ b/vendor/loco-translate/pub/css/skins/light.css @@ -0,0 +1 @@ +.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(136,136,136,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#888}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../../img/skins/light/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} diff --git a/vendor/loco-translate/pub/css/skins/midnight.css b/vendor/loco-translate/pub/css/skins/midnight.css new file mode 100644 index 0000000..e6882a0 --- /dev/null +++ b/vendor/loco-translate/pub/css/skins/midnight.css @@ -0,0 +1 @@ +.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(225,77,67,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#e14d43}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../../img/skins/midnight/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} diff --git a/vendor/loco-translate/pub/css/skins/ocean.css b/vendor/loco-translate/pub/css/skins/ocean.css new file mode 100644 index 0000000..c07ff51 --- /dev/null +++ b/vendor/loco-translate/pub/css/skins/ocean.css @@ -0,0 +1 @@ +.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(158,186,160,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#9ebaa0}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../../img/skins/ocean/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} diff --git a/vendor/loco-translate/pub/css/skins/sunrise.css b/vendor/loco-translate/pub/css/skins/sunrise.css new file mode 100644 index 0000000..c22a810 --- /dev/null +++ b/vendor/loco-translate/pub/css/skins/sunrise.css @@ -0,0 +1 @@ +.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(221,130,59,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#dd823b}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}form button.loco-loading.button-primary[disabled]:before{background:transparent url(../../img/skins/sunrise/spin-primary-button.gif?v=2.4.0) 0 0 no-repeat !important} diff --git a/vendor/loco-translate/pub/font/loco.eot b/vendor/loco-translate/pub/font/loco.eot new file mode 100644 index 0000000000000000000000000000000000000000..5e62034c624e6acb575fa82fd5ceafb8592b9b7b GIT binary patch literal 24692 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 + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/loco-translate/pub/font/loco.ttf b/vendor/loco-translate/pub/font/loco.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fb8f51181b0f686af593f8539e4a862390fc095b GIT binary patch literal 24540 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 A*#H0l literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/api/microsoft.png b/vendor/loco-translate/pub/img/api/microsoft.png new file mode 100644 index 0000000000000000000000000000000000000000..1ffffd900cda4404bc22d71601c764e0ff01b302 GIT binary patch literal 1637 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 vjeQXK<-#eXnx<&j1YTW$O_TA=C{q_3M(a`|4 zIyJ^+_4W1P;^9rob=%zA&CSg&rdG+x$#uMplh38K;KKU(`Tzd^sL-^$yu1OMFo4gP z;`8PJvNjR7NY>WY@bK`)+{^#?{_^tj*YMsLr$_*;F81^FrQ)|8yiq2cObw(!=I7=B zw?6Xm^7-`lm*1;1yJ7J0@$~WY{QLXv?(X>a_xk<%_4)Pj@$&NV@%8WW?(^>Q@bK~Q z@&Et-A^8LW00000EC2ui05kwa000L6K!9*aEEM zL|lVuNNEKU5)Bs+igJt~3|9;`HeEwD7ELyVd8xCju0sq45~K#BrGa)~Ba(6tO;A=W z5X}h&HUMD^#t9E~bwf|R62GLEVFnp+Wd&zxG!JkRWe^6dHE*A0O$M9*HVtJgz?XJ# zAN(}cCW0gc=uW96`D$UD#hMdp-D23IaA8WW(~a(GbGeT-q4q421G6)RYFQ z>J&mrFO9~2EkH3+XE1}pRt;Ps2!VxSVT`L1ea!g*&9#DqF>sr?DX6ob1%b$GmBnK+ zp-xjyy@+a9Q4KOA8sWw&S_>D%nH|fA=!MBeDyv4*F~J9QrCiHV=o#q9Kb0&=NCiC; zZ-p0FvFPQ8C&dd4^ldNKs{x>x5(thhZ~mLWFnf^F3mIb-l8=DR^zw@Vi415?di(`O z5GZ8$HCudheU+YCBiK;?Lq*p$a2Wu0fT*DbY9*0|0f{9-ieG45AmfHa*m4krP}oQV zd?_Yj6I3H;BnK$gG+>{IMN9_5l0-1MWQ0gOnMw`Su~UX{Xf*N#2($F{M^7|psRk-G zu;5~Q{6HzD5*>mt20I0+xu%csu<(nAbK;Q-4S?l2CX;>!D(Iku7OLV2C(K~z5-uQs zz=sVOaDohr8X?0AFH|r<1S_mC00$>jN`wpuG%$b$1Srr#3kn2)fT%;f@PG;gtSZ2* z0=Nn*03-Mi0RaM}FhB>m>I$m}6lfqos}ulxtFe_fI)DiZEO5aD&gS~65FMBE`7z|)91qQr8DXA<_VDAJKAm9Q3Gh{k}y&E)u zz`UGD+kw0A3b3lKCm3)l0UelNLJTD6i$Dk}Xppf99Z>MX3@1#0>c}aCfB*|MaFS^U z9XJs2vjVfLti%hX(7^&AykG#W%P!!60t!?hg37m6>vPL0Y;eNB03d)u3N4U;?X4}i ziU0;XyK6xN3Uq+NwL51WLaGUC&_dBP3@bnh8aN<=4?`fp0Sa0J`?l8u_$>ejAtkc@p01P5jEy4+87mWh~0eJ8>2_it5d%Plq z@Vfw~i}1qQEiABh(Gs%og?9mjcjn zk61s$fvh|Lx)yYR04sBV18P`01-uS^N#q*7HWvV&A+2mFpdJViPysWZk#;wz!2%wJ zG-6e-;5kV^00n5Kst%-J11t~$2R5*PLLPtvNURzOHsAn5-VsqCfI%Y{aDV_@UOX*kkb$vB?3WifQnZ1zyNyaLkwVW zma9C13xcTzagkt)in}5fJE`*K3!yDB422%=Q9eWJcQ#t;{;R)3u$d%XZM(3cGDrckQ|fvoQIvU-tR< ze0bmA{Ga!kH)GRA!&(bOAo2r(+!}~^`t<3S$94CwwSPUh;fK4v@21}Hcjj+-A3yy1 zoA-D8#ar^PpB~I!Zv6SlKYyD2{Nc^FkpHKm{w+zZvs!jpw@DjpyS7U$RhGu;otABD zY_C-AM4}!8gz_I3^_0#{-~2+VF)uxSjSdU(x72}K0!RdJkV;XMANAKEG|fa_GxiQ= zMtW{v_nj4;zhW7|-cED+;5VG~ga&cFxC5DsYo!9Q!Gf$J`F*wpVwh?vs>R<4L zL03p)bSusR;9GO~EBC&a!YaE%K@M6j!*I$@C74`A4gdk&Ue=VuV@vf1UT=Esh~Zdr zN%A5E4W={(C|@vs3P>Z_u6w zT<&o;XV*EBjde>HEEuzp%NL1$j5~_VoR@v767{U0Z{+uAIoD{rMgT>Q#1;tftEcTS zQP5cs`;U(_BI3mCMf*AO`a9<7JjEeB>AG|Bm}G8?_KB2F(keA@D*>j6)t1SspKsOf zQyF*k?LF8*XZLq@lo^}#`jh&_TtG0TdSOK3KrS-!+WbmCrELYxjEy6h=8pzlCJ;GC zTb|2JImO)gBy_Vo{lN`57XI$??`xMs$?V{Fqt@fh{VhAQqzQIi&AD7`+IF#(T5VG}q z+_DOSz%98pEkl$Mj8fU9AxI?0TD_M~&^5L_2q4%RYf0=Pi5E=zb%3-9`bj<+`OClS zCsn>7S#tW+A-99eP$+U%-L%(MamB6gcpiTcDrMXcW4Lnw;tgkul~U-oS7QpQr_FKm zTsKM9{#dVC7ETZat15VqPnZdzQmJ4FjCgf#c~&oI-%wsEAXW=9YLdxL`I3eR)+{Xa zf(BKo_e&L%s&T~=Q&Nd2P8{NuzE$k~!zRo2C|<_lGuB4&Yu*Q0x_0Yj{e+JzY}zu6 zgZab{E~V9YTVv#cso#EU7c&&Ul)y6(tdY-W_aIy>XaWp_3W?`pDI)HmhM#UpLaUWa z7Bbkfkc{%^%+T@G#-rJ%54?B#&t2*_Fa0b42R-SfifY%<)2mXFq+PdRk|@nH8PTGf zU3osiX*sLYi1shSLfj9!ue$7+iD3{gx=}yp=BPoB{e`6%%C4*zDIq}{rgDYv@ zkZCL8-1=c-c@&V!ZF<=%?Z1Q_E(i6?_qKeQe}eDWFMS47C9xSQ4ihDqaN$ zA=-iRgfzRF|BQ-=Vx&u(srPzFH<>z?@(5NRYJ5 z@n~IypyQ1>u<6Ap-9()+%^+q{cMtb|9EN|HnOA8G9iOow`Td~BWz6I3D_|;*jY&h; zJRStX{6sy2`!TGo!iGXJw@TN*x|K^SMF&fkrnH8s9Ur3987Td37DVb4??q2AHhO1z$Gb#z|16(QO_$`mzg;75JtX*Hi|JM`nASp8rFhC*Hn p#Tp87*Q;r)6|RrlEQDn|l=@8t=sUcct=%D~xPT@l@DVN4e*hG%AkzQ< literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/skins/coffee/spin-primary-button.gif b/vendor/loco-translate/pub/img/skins/coffee/spin-primary-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..e6f077dd87975a9a6be13b08537a19654ed1815e GIT binary patch literal 1849 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 literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/skins/fresh/spin-primary-button.gif b/vendor/loco-translate/pub/img/skins/fresh/spin-primary-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..2a25e4f0a55ea6815c405dfa5bbae7afd03e4d46 GIT binary patch literal 1849 zcma*odr(u^9S88sz31lM+(&YV$cD%=Ap}iAV!|s#aqUe2L7)^^gZ0f_;A3{T3qqtLcE=W`wmWX?RCm}NbzKW>oodIeO_;*ukN(l~ z=Wphm^O^7O{N|)@-)7ikfe1wYfgnh?_r;4Bg8pCcoxT(C-i?p{@|}D3p09G|iw9pm zev&`_2kzYb!za(mKe_#{=ikqMvotXGwQtk^zasxFNvX41_F8vI8*F=bOD$EF#_Bzm zT^nt0R_;L}p84`acW1rlMHiAL#Q5N~r@gsD+|tLgoi69ayeR%}@0lDW$tQ2p z*J96!7%{%*cbntnl6@ElD0!1Q9tdfQ1`);|oE5#DcN%79>59}FdN%907ZJgMKI=uC- zdP1Nps4=P)X94hTyn4rd@b!?&?qHCOmdP-jvQzOUSD^zyK)07RW%Jk){o!|--ackH zkyMrQ#J3_Z z2T4PDXog5FRn32;6Kl?}i#6K{#g7*@O=RZ|rNzgf6jV4-lZ@rjm0j<&t4xJuTF(KL z<;vt9XLDAaBgt5|iopUg%emZ6@L}AMWX6*0bCsxP9X*%Vqvc#p@68m$Jk=K_Ze3Z6zG&3=YV46P~bQwV8 z9BX+cC;2op_nY7y?zBg9a3b`>wU2ApLdpH1@5Zd}GY@y}$%-p0Ec)A>&H~S+*s7lt z0xP$-K0~W*F#n*{Q`sDK*fXH-KN7V9zykrze!wScAHXRiT}zS~6?HI~vFBfmM%|-P zI^NJR^J(dnWW%+JLB&ug)}P67;SpC~n!YRwk!WM5ZCC5M*i^c z`WcmXSeBG_bHMH3(iMvA^|$P`Ra{Z)2cBo221^q0k4);_6MtqCQF{Ph()$S2H%P^nZf1V+4dpe(Z&v~Mjd5fB>$=`~4Yr+igI1ZtKC zdRc?2)Q6;s8P%lXxhb(&6e|uIm;SP7{P)`}yCZq&N6%Rs#cz*4%G9-6uj;3~TtU;$ z5gaTfe0n9dX1q08F1Y#Lw{|f@@k+Io=?ta;&{`r;f1>lG$twd4nI(~M2a-y{BE=&}qdS=2} zboV1J#yc(NbsEv3wY`@$;ez>>Pfv;aLH9M6JtH9m;styd&Dt;m6ACGNalWjHk9MM@ zpf8FVMEOEJZYyf2Xi%;6iT}Sf>a2d%vnw;`p<&%g+Hx%Ui$imxL9ZJe<>rJ3Zw^J! z-eFTY;w=AFWB4Sl9-F=u95&f^YV7mS$(w5y<`sMqF*`B(vJ}uHFPhql5iE(*3>BvW zgb?jOc|x0t=4)|$GaQVOW7xh`4Hc-V_rIFuY^saT$?s9)nXtC_7v5SXe$bp({8W&* z#_@D>n4sg`MX>#~NZnMOG1VYuQudAX-Uz|}oRM2;3!YrCA$k3v$7Rgr?CW3(kBv@6 z*jye2!n_1MgZnV7t-^*vGN(${z`B*IBSi;FR=c#3shu3A)afYwVJ1ZC6d#3W_8J(n zEoE^*72MHw&~!;XDCur}xL&-4YISs8`cs%__ZU;ytbw2PndjAfrfuNKkXZd_D~3W| qGQ}G5bGE2ytQBsF-64dfJe2xb1?W4vfvtT*PH}!svi~DmUjG4%pdQEo literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/skins/light/spin-primary-button.gif b/vendor/loco-translate/pub/img/skins/light/spin-primary-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..2069b443e417774c5456664730cc826c600e4952 GIT binary patch literal 1849 zcmb8weNL>eOXgb*|di3x8Zigh;u1c5Q23N0@s5yK3H8mI_s z5y_hnYS?Ij2t>X^5X?RB?AbHeK3M<$tn~1u_rCbrGyQvi=jCO3v$9{7M`F|?v-;&fit7Wfsm$bpQcem71WofM5W7)OA z_FCm0BHsT4)|QC|_p5JYXmrM3x9H8V)>I5L9DHb@(qfwHFu)9D@65u5qlhLmy(X=({zr2uO%f5ic z##uLZr5VYOjId+0eP(e|5UL%DFxz*_#hs~^7*2|J+<0KmJV%lz;c(;lR@C9Ef6*HT zT_KIp9-IZhx8eGi?t?FfRd$7f9JE}9;gp?9Fu95x00O$LtSN`bmg*0`+4RP7!^z~5 zDSS#9sgo&#z`^*al$RoZH`8Y@# zc7|t))Kb;lS30rg9d@B+YmxZd`HkZ_c?0PQu_y%Rvr}fLZfM81X(ul-?Tx8^p#kGD)>l&IFpFl9prv_an5IIL$ zUdT;3!`%9H=yrGdqg!x1{L<=gYga?b{eeG^Sl?nE?%0zZUtU!F*DpH?y_e&veq02s z+}`?3t+v7Z1CO_|Ir^~osJ`z=^fCYs1~dl%zf$`FP8sQ1l+388gDH%?U@Qi84@c{G z1INv0q?3~M(-r-SfpDxZi{m2KUVm=tiYQE?jhnJziLlLQ9xuEo@dC{B)kGl>vi1Aj zvI>I0Ex9%=LzEGWQrW2?NF>KveSlBUHMac-AlMpfN$fI-7fkv|fV2(zNj@3*!@ucg zRK7u3a{BC1w}Z=2D00@_w%1m1#h$a?C)YxyjQcM!+(iKKh6}|?DRkSbF$LA#>bQNe zizI8muUD-KCy0V|6+Fl%%!E*>R4@cayndiOs|U1gDK8Ze>jfD#$z+FoMMDH@mKJ(R zgR0brq>35UgyN|wsYDbf4jGmHvUv29ZI<0pyo_V#t&QS0MjvJA+N{_0lRmDnX~z%_ z789>sO{*F8#K;A+KmW!qW+;9sfoC9CBcIRiN4Qwf1Q-St5--G3MBEV#Ki!gqRx4L5 zWUyr^8Rd!j!MD~MPh_7v{O;Y)JJoMr{g(h7@urt5s$D0}txHLgcHV_aqBQSJM2qhJ z+OY(u<$_KlI<&gyiY8Jp_xzbjaUbZKcG)u%!ysPBhcT=TBQT+mvX>Odn)ql3N(y?T zseY6%)Z@0|hKdH&@|^hpTcghIQ$4vlgB}{xouVzrQ$9O%YdGX(gJY*T@xf~YYiZx0 zX(!^``F>;M1g;*Lx*ZxZ(R+I2tf>#Ynx$;2OU}#hQKMO~w&WMSS|*|2oL}--khIG2 zcvFO+{ih3H+e=Zp$vR`2LCmD?8|wKe4F4iCuhJGeF>gci`#`tLn8(@Iz*HU^lZLQ) zJP3sOiFyY2V^~{-4TWTGm9BwxD_2&E4wkG;X#-O`F-WO1Q2J69MCugpMrQRG7_v2W zVO|y5-g?kpI5iQk!0HL8BssI20 literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/skins/midnight/spin-primary-button.gif b/vendor/loco-translate/pub/img/skins/midnight/spin-primary-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..5be38ea68647d7a127fbef61c6773b8fa796e089 GIT binary patch literal 1849 zcmb8weNL>eOXgb*|d2?=i@igh;u1c5T33N0@q0mBT1notqe zB9a$`V0cre!)n!ywJ6#GzMQQq2$6HN>v5Gc&vsnrj(XUpEp@Q2n|AG7!Wo?Wv48se z^Y_Q|e9rgx{LYiTeVbvE1tJjn2ZG#5h<*0#*{7Sdk9?hXw{7`yc4p!DV4$;fdE&{v zKg~OA530-l{l&sx+nT@q`s;tree!r@82K(0^B+k@qt&w4x=Y$@+q+w8sk5}y@3HJk zu)S8h2Z?zK5Grt7%rm+mYsX6&#=@+m1RWL@XsLs@1d#~dER~`tKjzOPXr_t0ZtNe; ziT2*R;Xg0BIAa;Z-pO?N;a@oE53WQQAHDpfzi^ma`h{$#+jX%hmj9dkCTB(Zshjk* z#B(A>jPLnmbCO)L590tOZ&fD)Ax*KsRTYbpJcQi^+EW29`IwA;J(Z@dG5_O*gEf@D>SmHP-?z{fTo^zHYPr|X5$!)09-}I6< z0=mOmVmoja0Dr>OyPkuuMAY_%gM73~hT)W*N;bJmod5#5tFkqp$5!YMzuEf6al^^9 z^0XBS8cJyiQtmJT3dkh0WMtn&x5qu5)TkbP?zE$DHlh=4M^m;B~M1LP5(i~JlU z4b_o3BDGXC_dqAsyu&UwY%3K%p5HW?UpSnV9FI~^;X+L^mPgn2yxFBPl~!rJ2T+!) zl6zfkd5z9AW8*3Y3&kwwawjE#@x+ihOR|quqP}(Xt)f0H=N|9U2%yNB(hdQB?W`T9 z2zc-K5vs5q)8-S{b~J5E+CXrzdRywFc%qleQAAw(z%XiCZ`Zg^E-ns2Z&tb z?JpFhpJ8tOI(&yGYvC50jC^nHW5-%3c{u#VxbeLlB!C}{(je2;=Pnu_rp?P z<@Pq^XtmAe?{#=<+hPxUkLm}H#I6AFP(WJ{@Jn?7;F6Kkse=y1}*|0R-D%EstLz@j^*I3X-SU;I)( ztMZS?(z0$I^*Fg~g(82$ZM&n6E9-dI`}BiwDdYKD9Cragy!m{YQVKoxdQ3s}bvkcf z=p{+VS52xlkpxk^p@s+fgqaX3l?sNyh}REP<@STFtyL8QVxu6tA&vCOS2aYaW_h8P zHKHjKc8LdsrVENkVXK9m#; z#8N{jU#Q1zWz99ss+BqM|G!3^H>i4gWfna&qB})fj;H_r(5Iv2-E^Zd(;#Lt_Ko&`6oLOSr?A!*J~eMciUvWS+gQli*TD=P8<&Z& zg**s^MJaj)4`5hZjSYolL7lFd^(a?YiVl^mPAP$LOpQ?LY?OX47b1;{_oH+B4Gh_t zu{f^^@9sQkx}+YG^mcr@3YI$o7iTu_r9{D_w8zia#*p#T5? literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/skins/ocean/spin-primary-button.gif b/vendor/loco-translate/pub/img/skins/ocean/spin-primary-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..eb641dcba7605b115ae5c938565dc01d3bf401a5 GIT binary patch literal 1849 zcmb8weNx&TKkp-Y0Ib9NaH9Rhb&A5196C zvAkJ%0E&7JAi{rK)C)2e`EgB@m-%AfhJx@Hx8$brix2ufIq1cRf<1{gqglr`mW=u+*mcbeWlsXLuq zlDtZRgDH&x%4d|H0@Cnw3Enf=>2%D+*C|I|I$N9P3u}j4pfF+8wAZ+(V>sAjftO`) z-QMs_fl{oP|577Vou?OTb`}Z0Ti80AlQ)!}5DOEG%nlnQG>5G0dZ$BSC@NRGj=(fq zE_K#bX4v#1;mi*GH^O zBF|kA`@%9S_c)7A@{kFN?W2sZau^93Zk-b(y64C#~u> zh5n7cBgZ?*?0$D=nZ8-8J*!>K1q4&7S4JcZu68{mdN}m$g!w({n>`1zr#B-v}*DD5PL*Yn&7RyF%y!z6$%YrbGI_{bUNn|>_#@WI#kqaP(FFl2TPuCxI zN-8i6HRW2=6jp{&a(R~u!=W5=^${*c)>sZh0HbTnC9$g{PB7``0n#qUPx4CeAOBP9 zQ+S6Z$?3NToHjN?Cd=7$*IHY}7Pr3ddj4Ukm~#F-h8+V8+HkR0E@qt8YD7l#wA=2E zb>n#L_w|Z(;TTr1se;3BF(by8%ViXXU~e5M&*}voJIYIW*k)cvO)~D5u4%Af&B{Wr zXkdl%s95Gxcx20lq!K}#Fl18vo8rko?=tO=;$)n-U~Uw?J^3U{(_y}r>y}xga^q|U#Yj;BBh#d$<<0wfH@d|+P z;ZB&twwI?+?0PLqGgqfi(+R26L!-U7!q6`=^C~T&o&^h(-w%2m`aIUUfl1}iF=-H; z$6)|JKT%7eehh7?u)qwSTcv5Bo$|GnB7-GsQ`$n+dWH#Q225VcVxT(N2a#F5Itp)3 zU0hIvcDA<}rj>)D?$&QM3AYoiHuv=B5rX{_R8g~vxzcBxS8}QLf$xWe$|pMznBk-l ow5}j`yOKm&neB1A`AiuHCVo)?`c7=7Yu}I(Y(SF|_=r~OKVShNw*UYD literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/skins/sunrise/spin-primary-button.gif b/vendor/loco-translate/pub/img/skins/sunrise/spin-primary-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..378a26b607a841de26972418f8d83c3ec0c39390 GIT binary patch literal 1849 zcmb8wYfw{X8VB&hIq%6iIhW)mA`Ou`Ap}iAV!|y%vF=F#L0~CRg_g^bh@pl;4OE0} z5y=H1$W>WgtXA!2TNJH;m+5v3LS#m}uC2^Ey=}Wyhwezrw$RJ2cH4CmW?}N7U-tR< ze0bmA{Ga!kH)G3Y!+HxuAo3l8{JAFj(W6K2?$+Kr-!|R6asK_u&)@9#cjj)4{&V(k zpS*1Qu&?-sZ{|MpHvIJOAHMzUy;+|Z`F|?vKa$ist7W%!hqS@Ad#BV=WofM5W!bUL z_I%|oB97!gOC7i+fJE>HsT4)|QJ)W@X(sZTv3Dpl z(sSp!@2u#;q-7X;EzRkJf9IsXx*TSlefmLfo|jvAQ?||JypSKwfA_A*QJQk%CVe&T zjEE8AyWZOnFPH4WI6%pp)CoXHQ!H?nN24SUVRwL*B*05JBBNhOqG@Z?|9Bz6mOTNB zjkB)rPBW747-8pV$JD}vAXGaPVYcs-i@Q=SF`N|dyf$mkJWZ0v;c(;FX4K)Uf65aE zT_KIptvCySZ{3wo-TR*jtLzR1IcT{I!znwJU~&~X00eY-ae8l)EAdO6ykv*dwZr4P7oqFi8leKwMVQpv&5+<&?=rhk7AdmP`-YwUc@<|6S|Gwa84^1SH@u_y% zxyRX@UFS$P)-7YOV9a7JA0_%R?kF;IL3TqW>RCnK%J0!~u90?)0E!%mEfC;WPupRl zptB(MUvFzf#EJWt?B~equbZdy6o>Vs>+Z?plKE}gAEkVfR;hto2{1*hwoF$2WUF?+ z%J^L0zC#^!c7JC_nXy@~KdE2J1q4&77e^!xO?tA|+Vts}AV%x6l`0}FSZ$9lT^jwUqdbS8y zx!v`dT5W^*7pj4P~@z+ZLh83id$dzJbWuu%DBId;m!ewH=He2N}=0cjVY*}HplIA z-6UE2eZ6W$I6)Mwso+6AVJ3u1rGgm*yI({<`wmcoBo2WCU8N^KLo}u1%!thTr^D1qj<1;oSzaR9tjCq`W6-?!^F=+^! z$AdtapQvYWKZdnc*icC3R_Pj8w{m%<=wQk6l-4n|d}LOyfg#&c z=Vw%*9c}wf7u5rj?$$5Xh&NKLj?RmJjS%e|VTzhH@a;bHw3^Sf9sb@cR?lt1P{>Q6 oSVKYXMm3GK!i{lTg|Li=QopSLeMi=^wa>{ZE}%&Xd_;@&U!5Tz5dZ)H literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/spin-editor-button.gif b/vendor/loco-translate/pub/img/spin-editor-button.gif new file mode 100644 index 0000000000000000000000000000000000000000..04deeaed852ec34067de6b85cdf425ff30d991bb GIT binary patch literal 1849 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 literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/wg/splitx.png b/vendor/loco-translate/pub/img/wg/splitx.png new file mode 100644 index 0000000000000000000000000000000000000000..73ff789f4bdc1b19323816d301317f83d82bc27d GIT binary patch literal 87 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c9$P6TZ{`m6`NU;U@gt-3y|Nr#q({CE~Cjmux kJY5_^IIbs0H1IPq^z7qI{KOmj2`J9s>FVdQ&MBb@0Q+AWO8@`> literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/img/wg/splity.png b/vendor/loco-translate/pub/img/wg/splity.png new file mode 100644 index 0000000000000000000000000000000000000000..57b607e8e4d42efa7f94a0b58c782253a9731873 GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^{6NgY$P6U2?|(l9q}T#{LR|m<|9|@Q={F7glR!#5 mT^vI=t|$Na-_OW#K!ri}0rT%5qYM?G6oaR$pUXO@geCwq%^L{- literal 0 HcmV?d00001 diff --git a/vendor/loco-translate/pub/js/min/admin.js b/vendor/loco-translate/pub/js/min/admin.js new file mode 100644 index 0000000..2dcf36b --- /dev/null +++ b/vendor/loco-translate/pub/js/min/admin.js @@ -0,0 +1,196 @@ +(function(r,s,k,R){var n=function(){function f(d){throw Error("Failed to require "+d);}var d={};return{register:function(f,m){d[f]=m},require:function(k,m){return d[k]||f(m)},include:function(k,m,g){return d[k]||(g?f(m):null)}}}();n.register("$1",function(f,d,k){function m(g){var c=typeof g;if("string"===c)if(/[^ <>!=()%^&|?:n0-9]/.test(g))console.error("Invalid plural: "+g);else return new Function("n","return "+g);"function"!==c&&(g=function(b){return 1!=b});return g}f.init=function(g){function c(a, +l,c){return(a=b[a])&&a[c]?a[c]:l||""}g=m(g);var b={};return{_:function(a){return c(a,a,0)},_x:function(a,b){return c(b+"\u0004"+a,a,0)},_n:function(a,b,e){e=Number(g(e));isNaN(e)&&(e=0);return c(a,e?b:a,e)},load:function(a){b=a||{};return this},pluraleq:function(a){g=m(a);return this}}};return f}({},r,s));n.register("$2",function(f,d,n){f.ie=function(){var d=k&&k.browser||{},g=d.msie&&11>Number(d.version),d=null;return function(){return g}}();f.init=function(){return f};return f}({},r,s));n.register("$3", +function(f,d,k){Number.prototype.format=function(d){d=Math.pow(10,d||0);var g=Math.round(d*this)/d;d=[];var g=String(g),c=g.split("."),g=c[0],c=c[1],b=g.length;do d.unshift(g.substring(b-3,b));while(0<(b-=3));g=d.join(",");if(d=c){d=c;for(var a,c=d.length;"0"===d.charAt(--c);)a=c;a&&(d=d.substring(0,a));d=c=d}d&&(g+="."+c);return g};Number.prototype.percent=function(d){var g=0,c=this&&d?100*(this/d):0;if(0===c)return"0";if(100===c)return"100";if(99 +c){c=Math.max(c,1E-4);do d=c.format(++g);while("0"===d&&4>g);d=d.substr(1)}else d=c.format(0);return d};return f}({},r,s));n.register("$4",function(f,d,k){Array.prototype.indexOf||(Array.prototype.indexOf=function(d){if(null==this)throw new TypeError;var g,c=Object(this),b=c.length>>>0;if(0===b)return-1;g=0;1=b)return-1;for(g=0<=g?g:Math.max(b-Math.abs(g),0);g ').appendTo(B));q.off("click").click(c);k(d).triggerHandler("resize");h();w=p.length;p.push(c);b&&(e=l(b)); +return{link:function(b,l){var c=l||b,e=k(a).find("nav"),c=k("").append(k("").attr("href",b).text(c));v?(v.push(c.html()),e.html(v.join(" | "))):(v=[c.html()],k(a).addClass("has-nav").append(c));return this},stick:function(){e&&e.die();e=null;p[w]=null;return this},slow:function(a){l(a||1E4);return this}}}function b(a,b,c){var l=n.require("$20","dom.js").el;a=k('
').prependTo(k("#loco-notices"));var e=k(l("p")); +c=k(l("span")).text(c);b=k(l("strong","has-icon")).text(b+": ");e.append(b).append(c).appendTo(a);return a}function a(a,l,e,w){a=b(e,l,a).css("opacity","0").fadeTo(500,1);k(d).triggerHandler("resize");return c(a,w)}function l(b){return a(b,D,"warning")}function e(){k("#loco-notices").find("div.notice").each(function(a,b){if(-1===b.className.indexOf("jshide")){var l=-1===b.className.indexOf("notice-success")?null:5E3;c(b,l)}})}var p=[],h=Date.now||function(){return(new Date).getTime()},v,D,q,w;f.error= +function(b){return a(b,v,"error")};f.warn=l;f.info=function(b){return a(b,q,"info")};f.success=function(b){return a(b,w,"success",5E3)};f.warning=l;f.log=function(){d.console&&console.log&&console.log.apply(console,arguments)};f.debug=function(a,b){d.console&&console.error&&(console.error("Loco Error: "+a),b&&console.debug&&console.debug(b))};f.clear=function(){for(var a=-1,b,l=p,c=l.length;++a"+a+"").text();b&&(b=b.replace(/[\r\n]+/g,"\n").replace(/(^|\n)\s+/g,"$1").replace(/\s+$/,""));b||(b=a)||(b="Blank response from server");return b}function g(a){return(a=a.split(/[\r\n]/)[0])?(a=a.replace(/ +in +\S+ on line \d+/,""),a=a.replace(/^[()! ]+Fatal error:\s*/,"")):t._("Server returned invalid data")} +function c(a,b,l){a[b]=l}function b(a,b,l){a.push({name:b,value:l})}function a(a,b,l){a.append(b,l)}function l(a,b,l,c){function e(b,c,v){if("abort"!==c){var d=p||{_:function(a){return a}},B=b.status,u=b.responseText,A=m(u),q=b.getResponseHeader("Content-Type")||"text/html",f=b.getResponseHeader("Content-Length")||u.length;"success"===c&&v?z.error(v):(z.error(g(A)+".\n"+d._("Check console output for debugging information")),z.debug("Ajax failure for "+a,{status:B,error:c,message:v,output:u}),"parsererror"=== +c&&(v="Response not JSON"),z.log([d._("Provide the following text when reporting a problem")+":","----","Status "+B+' "'+(v||d._("Unknown error"))+'" ('+q+" "+f+" bytes)",A,"===="].join("\n")));l&&l.call&&l(b,c,v);h=b}}c.url=v;c.dataType="json";var z=n.require("$6","notices.js").clear();h=null;return k.ajax(c).fail(e).done(function(a,l,c){var w=a&&a.data,h=a&&a.notices,v=h&&h.length;for(!w||a.error?e(c,l,a&&a.error&&a.error.message):b&&b(w,l,c);v--;)z.raise(h[v])})}var e={},p,h,v=d.ajaxurl||"/wp-admin/admin-ajax.php"; +f.init=function(a){e=a.nonces||e;return f};f.localise=function(a){p=a;return f};f.xhr=function(){return h};f.strip=m;f.parse=g;f.submit=function(a,b,c){function e(a,b){b.disabled?b.setAttribute("data-was-disabled","true"):b.disabled=!0}function h(a,b){b.getAttribute("data-was-disabled")||(b.disabled=!1)}function v(a){a.find(".button-primary").removeClass("loading");a.find("button").each(h);a.find("input").each(h);a.find("select").each(h);a.find("textarea").each(h);a.removeClass("disabled loading")} +var g=k(a),p=g.serialize();(function(a){a.find(".button-primary").addClass("loading");a.find("button").each(e);a.find("input").each(e);a.find("select").each(e);a.find("textarea").each(e);a.addClass("disabled loading")})(g);return l(a.route.value,function(a,l,c){v(g);b&&b(a,l,c)},function(a,b,l){v(g);c&&c(a,b,l)},{type:a.method,data:p})};f.post=function(h,v,w,g){var p,z=!0;v=v||{};(p=e[h])||(d.console&&console.error&&console.error('No nonce for "'+h+'"'),p="");var H=p;d.FormData&&v instanceof FormData? +(z=!1,p=a):p=Array.isArray(v)?b:c;p(v,"action","loco_json");p(v,"route",h);p(v,"loco-nonce",H);return l(h,w,g,{type:"post",data:v,processData:z,contentType:z?"application/x-www-form-urlencoded; charset=UTF-8":!1})};f.setNonce=function(a,b){e[a]=b;return f};return f}({},r,s));n.register("$21",{arab:1,aran:1,hebr:1,nkoo:1,syrc:1,syrn:1,syrj:1,syre:1,samr:1,mand:1,mend:1,thaa:1,adlm:1,cprt:1,phnx:1,armi:1,prti:1,phli:1,phlp:1,phlv:1,avst:1,mani:1,khar:1,orkh:1,ital:1,lydi:1,ar:1,ary:1,ckb:1,dv:1,fa:1, +he:1,nqo:1,ps:1,ur:1,yi:1});n.register("$8",function(f,d,k){function m(){}var g,c=n.require("$21","rtl.json");f.init=function(){return new m};f.cast=function(b){return b instanceof m?b:"string"===typeof b?f.parse(b):f.clone(b)};f.clone=function(b){var a,l=new m;for(a in b)l[a]=b[a];return l};f.parse=function(b){if(!(g||(g=/^([a-z]{2,3})(?:[-_]([a-z]{2}))?(?:[-_]([a-z0-9]{3,8}))?$/i)).exec(b))return null;var a=new m;a.lang=RegExp.$1.toLowerCase();if(b=RegExp.$2)a.region=b.toUpperCase();if(b=RegExp.$3)a.variant= +b.toLowerCase();return a};d=m.prototype;d.isValid=function(){return!!this.lang};d.isKnown=function(){var b=this.lang;return!(!b||"zxx"===b)};d.toString=function(b){b=b||"-";var a,l=this.lang||"zxx";if(a=this.region)l+=b+a;if(a=this.variant)l+=b+a;return l};d.getIcon=function(){for(var b=3,a,l,c=["variant","region","lang"],p=[];0!==b--;)if(a=c[b],l=this[a])p.push(a),p.push(a+"-"+l.toLowerCase());return p.join(" ")};d.isRTL=function(){return!!c[String(this.lang).toLowerCase()]};d=null;return f}({}, +r,s));n.register("$22",{"\u00e1":"a","\u00e0":"a","\u0103":"a","\u1eaf":"a","\u1eb1":"a","\u1eb5":"a","\u1eb3":"a","\u00e2":"a","\u1ea5":"a","\u1ea7":"a","\u1eab":"a","\u1ea9":"a","\u01ce":"a","\u00e5":"a","\u01fb":"a","\u00e4":"a","\u01df":"a","\u00e3":"a","\u0227":"a","\u01e1":"a","\u0105":"a","\u0101":"a","\u1ea3":"a","\u0201":"a","\u0203":"a","\u1ea1":"a","\u1eb7":"a","\u1ead":"a","\u1e01":"a","\u01fd":"\u00e6","\u01e3":"\u00e6","\u1e03":"b","\u1e05":"b","\u1e07":"b","\u0107":"c","\u0109":"c", +"\u010d":"c","\u010b":"c","\u00e7":"c","\u1e09":"c","\u010f":"d","\u1e0b":"d","\u1e11":"d","\u0111":"d","\u1e0d":"d","\u1e13":"d","\u1e0f":"d","\u00f0":"d","\ua77a":"d","\u01c6":"\u01f3","\u00e9":"e","\u00e8":"e","\u0115":"e","\u00ea":"e","\u1ebf":"e","\u1ec1":"e","\u1ec5":"e","\u1ec3":"e","\u011b":"e","\u00eb":"e","\u1ebd":"e","\u0117":"e","\u0229":"e","\u1e1d":"e","\u0119":"e","\u0113":"e","\u1e17":"e","\u1e15":"e","\u1ebb":"e","\u0205":"e","\u0207":"e","\u1eb9":"e","\u1ec7":"e","\u1e19":"e","\u1e1b":"e", +"\u1e1f":"f","\ua77c":"f","\u01f5":"g","\u011f":"g","\u011d":"g","\u01e7":"g","\u0121":"g","\u0123":"g","\u1e21":"g","\ua7a1":"g","\u1d79":"g","\u0125":"h","\u021f":"h","\u1e27":"h","\u1e23":"h","\u1e29":"h","\u0127":"h","\u210f":"h","\u1e25":"h","\u1e2b":"h","\u1e96":"h","\u00ed":"i","\u00ec":"i","\u012d":"i","\u00ee":"i","\u01d0":"i","\u00ef":"i","\u1e2f":"i","\u0129":"i","\u012f":"i","\u012b":"i","\u1ec9":"i","\u0209":"i","\u020b":"i","\u1ecb":"i","\u1e2d":"i","\u0135":"j","\u01f0":"j","\u1e31":"k", +"\u01e9":"k","\u0137":"k","\ua7a3":"k","\u1e33":"k","\u1e35":"k","\u013a":"l","\u013e":"l","\u013c":"l","\u0142":"l","\u1e37":"l","\u1e39":"l","\u1e3d":"l","\u1e3b":"l","\u0140":"l","\u1e3f":"m","\u1e41":"m","\u1e43":"m","\u0144":"n","\u01f9":"n","\u0148":"n","\u00f1":"n","\u1e45":"n","\u0146":"n","\ua7a5":"n","\u1e47":"n","\u1e4b":"n","\u1e49":"n","\u00f3":"o","\u00f2":"o","\u014f":"o","\u00f4":"o","\u1ed1":"o","\u1ed3":"o","\u1ed7":"o","\u1ed5":"o","\u01d2":"o","\u00f6":"o","\u022b":"o","\u0151":"o", +"\u00f5":"o","\u1e4d":"o","\u1e4f":"o","\u022d":"o","\u022f":"o","\u0231":"o","\u00f8":"o","\u01ff":"o","\u01eb":"o","\u01ed":"o","\u014d":"o","\u1e53":"o","\u1e51":"o","\u1ecf":"o","\u020d":"o","\u020f":"o","\u01a1":"o","\u1edb":"o","\u1edd":"o","\u1ee1":"o","\u1edf":"o","\u1ee3":"o","\u1ecd":"o","\u1ed9":"o","\u1e55":"p","\u1e57":"p","\u0155":"r","\u0159":"r","\u1e59":"r","\u0157":"r","\ua7a7":"r","\u0211":"r","\u0213":"r","\u1e5b":"r","\u1e5d":"r","\u1e5f":"r","\ua783":"r","\u015b":"s","\u1e65":"s", +"\u015d":"s","\u0161":"s","\u1e67":"s","\u1e61":"s","\u015f":"s","\ua7a9":"s","\u1e63":"s","\u1e69":"s","\u0219":"s","\u017f":"s","\ua785":"s","\u1e9b":"s","\u0165":"t","\u1e97":"t","\u1e6b":"t","\u0163":"t","\u1e6d":"t","\u021b":"t","\u1e71":"t","\u1e6f":"t","\ua787":"t","\u00fa":"u","\u00f9":"u","\u016d":"u","\u00fb":"u","\u01d4":"u","\u016f":"u","\u00fc":"u","\u01d8":"u","\u01dc":"u","\u01da":"u","\u01d6":"u","\u0171":"u","\u0169":"u","\u1e79":"u","\u0173":"u","\u016b":"u","\u1e7b":"u","\u1ee7":"u", +"\u0215":"u","\u0217":"u","\u01b0":"u","\u1ee9":"u","\u1eeb":"u","\u1eef":"u","\u1eed":"u","\u1ef1":"u","\u1ee5":"u","\u1e73":"u","\u1e77":"u","\u1e75":"u","\u1e7d":"v","\u1e7f":"v","\u1e83":"w","\u1e81":"w","\u0175":"w","\u1e98":"w","\u1e85":"w","\u1e87":"w","\u1e89":"w","\u1e8d":"x","\u1e8b":"x","\u00fd":"y","\u1ef3":"y","\u0177":"y","\u1e99":"y","\u00ff":"y","\u1ef9":"y","\u1e8f":"y","\u0233":"y","\u1ef7":"y","\u1ef5":"y","\u017a":"z","\u1e91":"z","\u017e":"z","\u017c":"z","\u1e93":"z","\u1e95":"z", +"\u01ef":"\u0292","\u1f00":"\u03b1","\u1f04":"\u03b1","\u1f84":"\u03b1","\u1f02":"\u03b1","\u1f82":"\u03b1","\u1f06":"\u03b1","\u1f86":"\u03b1","\u1f80":"\u03b1","\u1f01":"\u03b1","\u1f05":"\u03b1","\u1f85":"\u03b1","\u1f03":"\u03b1","\u1f83":"\u03b1","\u1f07":"\u03b1","\u1f87":"\u03b1","\u1f81":"\u03b1","\u03ac":"\u03b1","\u1f71":"\u03b1","\u1fb4":"\u03b1","\u1f70":"\u03b1","\u1fb2":"\u03b1","\u1fb0":"\u03b1","\u1fb6":"\u03b1","\u1fb7":"\u03b1","\u1fb1":"\u03b1","\u1fb3":"\u03b1","\u1f10":"\u03b5", +"\u1f14":"\u03b5","\u1f12":"\u03b5","\u1f11":"\u03b5","\u1f15":"\u03b5","\u1f13":"\u03b5","\u03ad":"\u03b5","\u1f73":"\u03b5","\u1f72":"\u03b5","\u1f20":"\u03b7","\u1f24":"\u03b7","\u1f94":"\u03b7","\u1f22":"\u03b7","\u1f92":"\u03b7","\u1f26":"\u03b7","\u1f96":"\u03b7","\u1f90":"\u03b7","\u1f21":"\u03b7","\u1f25":"\u03b7","\u1f95":"\u03b7","\u1f23":"\u03b7","\u1f93":"\u03b7","\u1f27":"\u03b7","\u1f97":"\u03b7","\u1f91":"\u03b7","\u03ae":"\u03b7","\u1f75":"\u03b7","\u1fc4":"\u03b7","\u1f74":"\u03b7", +"\u1fc2":"\u03b7","\u1fc6":"\u03b7","\u1fc7":"\u03b7","\u1fc3":"\u03b7","\u1f30":"\u03b9","\u1f34":"\u03b9","\u1f32":"\u03b9","\u1f36":"\u03b9","\u1f31":"\u03b9","\u1f35":"\u03b9","\u1f33":"\u03b9","\u1f37":"\u03b9","\u03af":"\u03b9","\u1f77":"\u03b9","\u1f76":"\u03b9","\u1fd0":"\u03b9","\u1fd6":"\u03b9","\u03ca":"\u03b9","\u0390":"\u03b9","\u1fd3":"\u03b9","\u1fd2":"\u03b9","\u1fd7":"\u03b9","\u1fd1":"\u03b9","\u1f40":"\u03bf","\u1f44":"\u03bf","\u1f42":"\u03bf","\u1f41":"\u03bf","\u1f45":"\u03bf", +"\u1f43":"\u03bf","\u03cc":"\u03bf","\u1f79":"\u03bf","\u1f78":"\u03bf","\u1fe4":"\u03c1","\u1fe5":"\u03c1","\u1f50":"\u03c5","\u1f54":"\u03c5","\u1f52":"\u03c5","\u1f56":"\u03c5","\u1f51":"\u03c5","\u1f55":"\u03c5","\u1f53":"\u03c5","\u1f57":"\u03c5","\u03cd":"\u03c5","\u1f7b":"\u03c5","\u1f7a":"\u03c5","\u1fe0":"\u03c5","\u1fe6":"\u03c5","\u03cb":"\u03c5","\u03b0":"\u03c5","\u1fe3":"\u03c5","\u1fe2":"\u03c5","\u1fe7":"\u03c5","\u1fe1":"\u03c5","\u1f60":"\u03c9","\u1f64":"\u03c9","\u1fa4":"\u03c9", +"\u1f62":"\u03c9","\u1fa2":"\u03c9","\u1f66":"\u03c9","\u1fa6":"\u03c9","\u1fa0":"\u03c9","\u1f61":"\u03c9","\u1f65":"\u03c9","\u1fa5":"\u03c9","\u1f63":"\u03c9","\u1fa3":"\u03c9","\u1f67":"\u03c9","\u1fa7":"\u03c9","\u1fa1":"\u03c9","\u03ce":"\u03c9","\u1f7d":"\u03c9","\u1ff4":"\u03c9","\u1f7c":"\u03c9","\u1ff2":"\u03c9","\u1ff6":"\u03c9","\u1ff7":"\u03c9","\u1ff3":"\u03c9","\u0491":"\u0433","\u0450":"\u0435","\u0451":"\u0435","\u04c2":"\u0436","\u045d":"\u0438","\u04e3":"\u0438","\u04ef":"\u0443"}); +n.register("$9",function(f,d,k){f.init=function(){function d(a){return h[a]||a}function g(a,b,l,c){b=a.split(b);for(var e=b.length;0!==e--;)(a=b[e])&&null==c[a]&&(l.push(a),c[a]=!0);return l}function c(a){return g(String(a||"").toLowerCase().replace(e,d),p,[],{})}function b(a,b){for(var c=[],h={},A,u=b.length,z=p;0!==u--;)(A=b[u])&&g(String(A||"").toLowerCase().replace(e,d),z,c,h);l[a]=c}function a(a,b){var c=[],e=-1,h=l,p=h.length,g,d,C,f,k,B,I=a.length,L=b?!0:!1;a:for(;++e\[\]\/\\\u00a0\u1680\u180e\u2000-\u206f\u2e00-\u2e7f\u3000-\u303f]+/,h=n.require("$22","flatten.json");return{split:c,pull:function(b,c){return a(b,c)},find:function(b,l){return a(c(b),l)},add:function(a,b){l[a]=c(b)},push:function(a){b(l.length,a)},index:function(a,c){b(a,c)},size:function(){return l.length},clear:function(){l= +[]},remove:function(a){l[a]=null}}};return f}({},r,s));n.register("$10",function(f,d,n){f.listen=function(f,g){function c(){q[e?"show":"hide"]()}function b(a){D&&f.setAttribute("size",2+a.length);e=a;c();return a}function a(){p=null;g(e)}function l(){var c=f.value;v&&c===v&&(c="");c!==e&&(p&&clearTimeout(p),b(c),h?p=setTimeout(a,h):a())}f instanceof jQuery&&(f=f[0]);var e,p,h=150,v=d.attachEvent&&f.getAttribute("placeholder"),D=1===Number(f.size),q=k('clear').click(function(){f.value= +"";l();return!1});b(f.value);k(f).on("input blur focus",function(){l();return!0}).after(q);c();return{delay:function(a){h=a},ping:function(c){c?(p&&clearTimeout(p),c=f.value,v&&c===v&&(c=""),b(c),a(),c=void 0):c=l();return c},val:function(a){if(null==a)return e;p&&clearTimeout(p);f.value=b(a);c()},el:function(){return f},blur:function(a){return k(f).on("blur",a)}}};return f}({},r,s));n.register("$11",function(f,d,n){function m(b,a){this.$element=k(b);this.options=a;this.enabled=!0;this.fixTitle()} +f.init=function(b,a){var l={fade:!0,offset:5,delayIn:g,delayOut:c,anchor:b.attr("data-anchor"),gravity:b.attr("data-gravity")||"s"};a&&(l=k.extend({},l,a));b.tipsy(l)};f.delays=function(b,a){g=b||150;c=a||100};f.kill=function(){k("div.tipsy").remove()};f.text=function(b,a){a.data("tipsy").setTitle(b)};var g,c;f.delays();k(n.body).on("overlayOpened overlayClosing",function(b){f.kill();return!0});m.prototype={show:function(){var b=this.getTitle();if(b&&this.enabled){var a=this.tip();a.find(".tipsy-inner")[this.options.html? +"html":"text"](b);a[0].className="tipsy";a.remove().css({top:0,left:0}).prependTo(n.body);var b=(b=this.options.anchor)?this.$element.find(b):this.$element,b=k.extend({},b.offset(),{width:b[0].offsetWidth,height:b[0].offsetHeight}),c=a[0].offsetWidth,e=a[0].offsetHeight,p="function"==typeof this.options.gravity?this.options.gravity.call(this.$element[0]):this.options.gravity,h;switch(p.charAt(0)){case "n":h={top:b.top+b.height+this.options.offset,left:b.left+b.width/2-c/2};break;case "s":h={top:b.top- +e-this.options.offset,left:b.left+b.width/2-c/2};break;case "e":h={top:b.top+b.height/2-e/2,left:b.left-c-this.options.offset};break;case "w":h={top:b.top+b.height/2-e/2,left:b.left+b.width+this.options.offset}}2==p.length&&("w"==p.charAt(1)?h.left=b.left+b.width/2-15:h.left=b.left+b.width/2-c+15);a.css(h).addClass("tipsy-"+p);a.find(".tipsy-arrow")[0].className="tipsy-arrow tipsy-arrow-"+p.charAt(0);this.options.className&&a.addClass("function"==typeof this.options.className?this.options.className.call(this.$element[0]): +this.options.className);a.addClass("in")}},hide:function(){this.tip().remove()},fixTitle:function(){var b=this.$element,a=b.attr("title")||"";(a||"string"!==typeof b.attr("original-title"))&&b.attr("original-title",a).removeAttr("title")},getTitle:function(){var b,a=this.$element,c=this.options;this.fixTitle();"string"==typeof c.title?b=a.attr("title"==c.title?"original-title":c.title):"function"==typeof c.title&&(b=c.title.call(a[0]));return(b=(""+b).replace(/(^\s*|\s*$)/,""))||c.fallback},setTitle:function(b){var a= +this.$element;a.attr("default-title")||a.attr("default-title",this.getTitle());null==b&&(b=a.attr("default-title")||this.getTitle());a.attr("original-title",b);if(this.$tip)this.$tip.find(".tipsy-inner")[this.options.html?"html":"text"](b)},tip:function(){this.$tip||(this.$tip=k('
').html('
'),this.$tip.data("tipsy-pointee",this.$element[0]));return this.$tip},validate:function(){this.$element[0].parentNode||(this.hide(), +this.options=this.$element=null)},enable:function(){this.enabled=!0},disable:function(){this.hide();this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled}};k.fn.tipsy=function(b){function a(a){var c=k.data(a,"tipsy");c||(c=new m(a,k.fn.tipsy.elementOptions(a,b)),k.data(a,"tipsy",c));return c}function c(){var l=a(this),e=b.delayIn;l.hoverState="in";0==e?l.show():(l.fixTitle(),setTimeout(function(){"in"==l.hoverState&&l.show()},e))}function e(){var c=a(this),l=b.delayOut;c.hoverState= +"out";0==l?c.hide():(c.tip().removeClass("in"),setTimeout(function(){"out"==c.hoverState&&c.hide()},l))}b=k.extend({},k.fn.tipsy.defaults,b);b.live||this.each(function(){a(this)});if("manual"!=b.trigger){var p=b.live?"live":"bind",h="hover"==b.trigger?"mouseleave":"blur";this[p]("hover"==b.trigger?"mouseenter":"focus",c)[p](h,e)}return this};k.fn.tipsy.defaults={className:null,delayIn:0,delayOut:0,fade:!1,fallback:"",gravity:"n",html:!1,live:!1,offset:0,opacity:0.8,title:"title",trigger:"hover",anchor:null}; +k.fn.tipsy.elementOptions=function(b,a){return k.metadata?k.extend({},a,k(b).metadata()):a};k.fn.tipsy.autoNS=function(){return k(this).offset().top>k(n).scrollTop()+k(d).height()/2?"s":"n"};k.fn.tipsy.autoWE=function(){return k(this).offset().left>k(n).scrollLeft()+k(d).width()/2?"e":"w"};k.fn.tipsy.autoBounds=function(b,a){return function(){var c=a[0],e=1&]/g;a=/(\r\n|\n|\r)/g;l=/(?:https?):\/\/(\S+)/ig;e=location.hostname;d=null}function g(a){return"&#"+a.charCodeAt(0)+";"}function c(a, +b){return''+b+""}var b,a,l,e;return function(e,h){d&&d();var v=e.replace(b,g);h&&(v=v.replace(l,c).replace(a,"
"));return v}}();return f}({},r,s));n.register("$36",function(f,d,k){function m(){}var g,c,b=n.require("$21","rtl.json");f.init=function(){return new m};f.cast=function(a){return a instanceof m?a:"string"===typeof a?f.parse(a):f.clone(a)};f.clone=function(a){var b,c=new m;for(b in a)c[b]=a[b];return c};f.parse=function(a){g|| +(c=/[-_+]/,g=/^([a-z]{2,3})(?:-([a-z]{4}))?(?:-([a-z]{2}|[0-9]{3}))?(?:-([0-9][a-z0-9]{3,8}|[a-z0-9]{5,8}))?(?:-([a-z]-[-a-z]+))?$/i);a=String(a).split(c).join("-");if(!g.exec(a))return null;var b=new m;b.lang=RegExp.$1.toLowerCase();if(a=RegExp.$2)b.script=a.charAt(0).toUpperCase()+a.substr(1).toLowerCase();if(a=RegExp.$3)b.region=a.toUpperCase();if(a=RegExp.$4)b.variant=a.toLowerCase();if(a=RegExp.$5)b.extension=a;return b};d=m.prototype;d.isValid=function(){return!!this.lang};d.isKnown=function(){var a= +this.lang;return!(!a||"zxx"===a)};d.toString=function(a){a=a||"-";var b,c=this.lang||"zxx";if(b=this.script)c+=a+b;if(b=this.region)c+=a+b;if(b=this.variant)c+=a+b;if(b=this.extension)c+=a+b;return c};d.getIcon=function(){for(var a=4,b,c,g=["variant","region","script","lang"],h=[];0!==a--;)if(b=g[a],c=this[b])c.join&&(c=c.join("-")),1===a&&3===c.length?h.push("region-m49"):h=h.concat([b,b+"-"+c.toLowerCase()]);return h.join(" ")};d.isRTL=function(){return!!b[String(this.script||this.lang).toLowerCase()]}; +d=null;return f}({},r,s));n.register("$37",function(f,d,k){function m(a){d.console&&console.error&&console.error(a)}function g(){m("Method not implemented")}function c(){}function b(a){}c.prototype.toString=function(){return"[Undefined]"};b.prototype._validate=function(a){var b,e,p=!0;for(b in this)e=this[b],e===g?(m(a+"."+b+"() must be implemented"),p=!1):e instanceof c&&(m(a+"."+b+" must be defined"),p=!1);return p};f.init=function(a,l){var e,p=new b;if(a)for(e=a.length;0!==e--;)p[a[e]]=g;if(l)for(e= +l.length;0!==e--;)p[l[e]]=new c;return p};f.validate=function(a){var b=/function (\w+)\(/.exec(a.toString())?RegExp.$1:"";a.prototype._validate(b||"Object")};return f}({},r,s));n.register("$46",function(f,d,k){var m=d.requestAnimationFrame,g=d.cancelAnimationFrame,c=0;if(!m||!g)for(var b in{ms:1,moz:1,webkit:1,o:1})if(m=d[b+"RequestAnimationFrame"])if(g=d[b+"CancelAnimationFrame"]||d[b+"CancelRequestAnimationFrame"])break;m&&g||(m=function(b){var e=a();timeToCall=Math.max(0,16-(e-c));nextTime=e+timeToCall; +timerId=d.setTimeout(function(){b(nextTime)},timeToCall);c=nextTime;return timerId},g=function(a){clearTimeout(a)});var a=Date.now||function(){return(new Date).getTime()};f.loop=function(a,b){function c(){d=m(c,b);a(h++)}var h=0,d;c();return{stop:function(){d&&g(d);d=null}}};return f}({},r,s));n.register("$43",function(f,d,k){function m(a,c,e,l){if(b){var h=e;e=function(a){if((a.MSPOINTER_TYPE_TOUCH||"touch")===a.pointerType)return h(a)}}a.addEventListener(c,e,l);return{unbind:function(){a.removeEventListener(c, +e,l)}}}function g(a){a.preventDefault();a.stopPropagation();return!1}var c,b=!!d.navigator.msPointerEnabled,a=b?"MSPointerDown":"touchstart",l=b?"MSPointerMove":"touchmove",e=b?"MSPointerUp":"touchend";f.ok=function(a){null==c&&(c="function"===typeof k.body.addEventListener);c&&a&&a(f);return c};f.ms=function(){return b};f.dragger=function(b,c){function h(a){b.addEventListener(a,d[a],!1)}function w(a){b.removeEventListener(a,d[a],!1)}var d={};d[a]=function(b){p(b,function(e,h){h.type=a;c(b,h,u)}); +h(l);h(e);return!0};d[e]=function(a){w(l);w(e);p(a,function(b,h){h.type=e;c(a,h,u)});return!0};d[l]=function(a){p(a,function(b,e){e.type=l;c(a,e,u)});return g(a)};h(a);var u={kill:function(){w(a);w(l);w(e);b=u=c=null}};return u};f.swiper=function(c,d,f){function w(a){c.addEventListener(a,k[a],!1)}function A(a){c.removeEventListener(a,k[a],!1)}function u(){z&&z.stop();z=null}var z,H,C,k={},m=[],B=[],I=[];k[a]=function(a){H=!1;u();var b=h();p(a,function(a,c){m[a]=b;B[a]=c.clientX;I[a]=c.clientY});C= +c.scrollLeft;return!0};k[e]=function(a){p(a,function(a,b){var c=h()-m[a],e=B[a]-b.clientX,c=Math.abs(e)/c;d(c,e?0>e?-1:1:0)});C=null;return!0};k[l]=function(a){var b,e;null==C||p(a,function(a,c){b=B[a]-c.clientX;e=I[a]-c.clientY});if(e&&Math.abs(e)>Math.abs(b))return H=!0;b&&(H=!0,c.scrollLeft=Math.max(0,C+b));return g(a)};if(!b||f)w(a),w(l),w(e),b&&(c.className+=" mstouch");return{kill:function(){A(a);A(l);A(e);u()},swiped:function(){return H},ms:function(){return b},snap:function(a){b&&!f&&(c.style["-ms-scroll-snap-points-x"]= +"snapInterval(0px,"+a+"px)",c.style["-ms-scroll-snap-type"]="mandatory",c.style["-ms-scroll-chaining"]="none")},scroll:function(a,b,e){u();var h=c.scrollLeft,l=a>h?1:-1,B=Math[1===l?"min":"max"],g=Math.round(16*b*l);return z=n.require("$46","fps.js").loop(function(b){b&&(h=Math.max(0,B(a,h+g)),c.scrollLeft=h,a===h&&(u(),e&&e(h)))},c)}}};f.start=function(b,c){return m(b,a,c,!1)};f.move=function(a,b){return m(a,l,b,!1)};f.end=function(a,b){return m(a,e,b,!1)};var p=f.each=function(a,c){if(b)(a.MSPOINTER_TYPE_TOUCH|| +"touch")===a.pointerType&&c(0,a);else for(var e=-1,h=(a.originalEvent||a).changedTouches||[];++e\r\n')+'';return!0}function b(a){return''+a+""}var a=d.parentNode,l=a.insertBefore(n.createElement("div"),d);k(d).on("input",c).on("scroll",g);k(a).addClass("has-mirror");l.className="ta-mirror";var e=d.offsetWidth-d.clientWidth;2/},{token:"locked",regex:/<(?:xliff:)?(?:g|ph)[^>]*>[^<]*<\/(?:xliff:)?(?:g|ph)>/},{token:"locked",regex:/<(?:xliff:)?(bx|ex|x)[^\/>]*\/>/},{token:"constant.language",regex:/<\/?[:a-z]+[^>]*>/}]},c=l(a);"icu"===a?b={start:b.start.concat([{token:"icu-quoted", +regex:/'([{}][^']*)?'/},{token:"printf",regex:"{[^!-/:-@\\[-^{-~\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a9\u00ab\u00ac\u00ae\u00b0\u00b1\u00b6\u00bb\u00bf\u00d7\u00f7\\u2010-\\u2027\\u2030-\\u203E\\u2041-\\u2053\\u2055-\\u205E\\u2190-\\u245F\\u2500-\\u2775\\u2794-\\u2BFF\\u2E00-\\u2E7F\\u3001-\\u3003\\u3008-\\u3020\\u3030\\uFD3E\\uFD3F\\uFE45\\uFE46]+(,[\\s\\u0085\\u200E\\u200F\\u2028\\u2029]*(?:number|date|time|spellout|ordinal|duration)[\\s\\u0085\\u200E\\u200F\\u2028\\u2029]*(,[\\s\\u0085\\u200E\\u200F\\u2028\\u2029]*[^{}]+)?)?}"}, +{token:"icu",regex:/{/,next:"icuName"},{token:"icu",regex:/}/,next:"icuType"}]),icuName:[{token:"icu",regex:"[\\s\\u0085\\u200E\\u200F\\u2028\\u2029]+"},{token:"icu.name",regex:"[^\\s\\u0085\\u200E\\u200F\\u2028\\u2029!-/:-@\\[-^{-~\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a9\u00ab\u00ac\u00ae\u00b0\u00b1\u00b6\u00bb\u00bf\u00d7\u00f7\\u2010-\\u2027\\u2030-\\u203E\\u2041-\\u2053\\u2055-\\u205E\\u2190-\\u245F\\u2500-\\u2775\\u2794-\\u2BFF\\u2E00-\\u2E7F\\u3001-\\u3003\\u3008-\\u3020\\u3030\\uFD3E\\uFD3F\\uFE45\\uFE46]+", +next:"icuType"},{defaultToken:"icu",next:"icuType"}],icuType:[{token:"icu",regex:/[{}]/,next:"start"},{defaultToken:"icu"}]}:c&&b.start.push({token:"printf",regex:c});this.$rules=b}}function l(a){switch(a){case "objc":return/%(?:\d+\$)?[-+'0# ]*\d*(?:\.\d+|\.\*(?:\d+\$)?)?(?:hh?|ll?|[qjzTL])?[sScCdDioOuUxXfFeEgGaAp%@]/;case "java":return/%(?:\d+\$)?[-+,(0# ]*\d*(?:\.\d+)?(?:[bBhHsScCdoxXeEfgGaA%n]|[tT][HIklMSLNpzZsQBbhAaCYyjmdeRTrDFc])/;case "php":return/%(?:\d+\$)?(?:'.|[-+0 ])*\d*(?:\.\d+)?[suxXbcdeEfFgGo%]/; +case "python":return/%(?:\([a-z]+\))?[-+0# ]*(?:\d+|\*)?(?:\.\d+|\.\*)?(?:[hlL])?[sdiouxXeEfFgGcra%]/;case "javascript":return/%(?:[1-9]\d*\$)?\+?(?:0|'[^$])?-?\d*(?:\.\d+)?[b-gijostTuvxX%]/;case "auto":return/%(?:\d+\$|\([a-z]+\))?(?:[-+0]?\d*(\.\d+)?[duxoefgaDUXOEFGA]|[@scSC%])/;case p:return e||"%%"}}var e,p="auto";f.init=function(a,e,l){var f,w=!1,A=l||p,u=a.parentNode,z=u.appendChild(E.createElement("div"));k(u).addClass("has-proxy has-ace");n.require("$29","remote.js").load("https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js", +function(l){if(z){if(!l)throw Error("Failed to load code editor");f=l.edit(z);var g=f.session,d=f.renderer;f.$blockScrolling=Infinity;f.setShowInvisibles(w);f.setWrapBehavioursEnabled(!1);f.setBehavioursEnabled(!1);f.setHighlightActiveLine(!1);g.setUseSoftTabs(!1);d.setShowGutter(!0);d.setPadding(10);d.setScrollMargin(8);g.setMode(b(l,A));f.setValue(a.value,-1);g.setUseWrapMode(!0);e?m(f,e):c(f)}},"ace");return{kill:function(){f&&(g(f),f.destroy(),f=null);z&&(u.removeChild(z),k(u).removeClass("has-proxy has-ace"), +z=null);return this},disable:function(){f&&c(f);e=null;return this},enable:function(a){e=a;f&&m(f,a);return this},resize:function(){f&&f.resize();return this},val:function(a){f&&a!==f.getValue()&&f.setValue(a,-1);return this},invs:function(a){a=a||!1;w!==a&&(w=a,f&&f.setShowInvisibles(a));return this},strf:function(a){a=a||p;a!==A&&(A=a,f&&f.session.setMode(b(d.ace,a)));return this},focus:function(){return this}}};f.strf=function(a,b){p=a;e=b;return f};return f}({},r,s));n.register("$48",function(f, +d,E){function m(a,b){function c(){return b.val(a.getContent())}a.on("input",c);a.on("change",c);a.on("focus",function(){return b.focus()});a.on("blur",function(){return b.blur()});a.setMode("design")}function g(a){a.off("input");a.off("change");a.off("focus");a.off("blur")}function c(a){g(a);a.setMode("readonly")}var b=0;f.load=function(a){var b=n.require("$29","remote.js");b.load(b.stat("/lib/tinymce.min.js"),a,"tinymce");return f};f.init=function(a,l){function e(a){D=a;q="

"===a.substr(0,3)&& +"

"===a.substr(-4);return a.replace(/(<\/?)script/ig,"$1loco:script")}function d(a){h=a;a._getContent=a.getContent;a.getContent=function(a){a=this._getContent(a);a=a.replace(/(<\/?)loco:script/ig,"$1script");if(!q&&"

"===a.substr(0,3)&&"

"===a.substr(-4)){var b=a.substr(3,a.length-7);if(b===D||-1===b.indexOf("

"))a=b}return a};a._setContent=a.setContent;a.setContent=function(a,b){return this._setContent(e(a),b)};l?(m(a,l),l.reset()):c(a);k(u).removeClass("loading")}var h,v=!1,D="",q=!1, +w=a.parentNode,A=w.parentNode,u=w.appendChild(E.createElement("div")),z=A.insertBefore(E.createElement("nav"),w);z.id="_tb"+String(++b);k(w).addClass("has-proxy has-mce");k(u).addClass("mce-content-body loading").html(e(a.value));f.load(function(a){if(!a)throw Error("Failed to load HTML editor");u&&a.init({inline:!0,target:u,hidden_input:!1,theme:"modern",skin:!1,plugins:"link lists",browser_spellcheck:!0,menubar:!1,fixed_toolbar_container:"#"+z.id,toolbar:"formatselect | bold italic link unlink | bullist numlist outdent indent", +block_formats:"Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h4;Heading 4=h4;Heading 5=h5;Heading 6=h6;",forced_root_block:"p",relative_urls:!1,convert_urls:!1,remove_script_host:!1,document_base_url:"",allow_script_urls:!1,formats:{alignleft:{classes:"alignleft"},alignright:{selector:"p,h1,h2,h3,h4,span,strong,em,a",classes:"alignright"},aligncenter:{selector:"p,h1,h2,h3,h4,span,strong,em,a",classes:"aligncenter"},strikethrough:{inline:"del"}},fix_list_elements:!0,extended_valid_elements:"span,b,i,u,loco:script", +entities:"38,amp,60,lt,62,gt,160,nbsp",entity_encoding:"named",keep_styles:!1,init_instance_callback:d})});return{val:function(b){b=e(b);null==h?(a.value=b,k(u).html(b)):h.getContent()!==b&&h.setContent(b);l&&l.val(b);return this},kill:function(){h&&(l&&l.val(h.getContent()),g(h),h.destroy(),h=null);u&&(w.removeChild(u),k(w).removeClass("has-proxy has-mce"),u=null);z&&(A.removeChild(z),z=null);return this},enable:function(a){l=a;h&&m(h,a);return this},disable:function(){h&&c(h);l=null;return this}, +focus:function(){h&&l&&h.focus();return this},invs:function(a){a=a||!1;v!==a&&(v=a,k(w)[a?"addClass":"removeClass"]("show-invs"));return this}}};return f}({},r,s));n.register("$44",function(f,d,E){function m(b){function a(){d&&(f.off("input",l),d=!1)}function l(){var a=b.value;a!==w&&(f.trigger("changing",[a,w]),w=a)}function e(){l();d&&A!==w&&f.trigger("changed",[w])}function g(){c=b;A=w;d||(f.on("input",l),d=!0);f.trigger("editFocus");q.addClass("has-focus");return!0}function h(){c===b&&(c=null); +f.trigger("editBlur");q.removeClass("has-focus");d&&(e(),a());return!0}var d=!1,f=k(b),q=k(b.parentNode),w=b.value,A;f.blur(h).focus(g);return{val:function(a){w!==a&&(b.value=a,f.triggerHandler("input"),w=a);return!0},kill:function(){a();f.off("blur",h).off("focus",g)},fire:function(){w=null;l()},ping:e,blur:h,focus:g,reset:function(){A=w=b.value}}}function g(b){this.e=b}var c;f._new=function(b){return new g(b)};f.init=function(b){var a=new g(b);b.disabled?(b.removeAttribute("disabled"),a.disable()): +b.readOnly?a.disable():a.enable();return a};TextAreaPrototype=g.prototype;TextAreaPrototype.destroy=function(){this.unlisten();var b=this.p;b&&(b.kill(),this.p=null);this.e=null};TextAreaPrototype.reload=function(b,a){var c=this.l;c&&!a&&(this.disable(),c=null);this.val(b||"");a&&!c&&this.enable();return this};TextAreaPrototype.val=function(b){var a=this.e;if(null==b)return a.value;var c=this.l,e=this.p;e&&e.val(b);c&&c.val(b);c||a.value===b||(a.value=b,k(a).triggerHandler("input"));return this}; +TextAreaPrototype.fire=function(){this.l&&this.l.fire();return this};TextAreaPrototype.ping=function(){this.l&&this.l.ping();return this};TextAreaPrototype.focus=function(){var b=this.p;b?b.focus():k(this.e).focus()};TextAreaPrototype.focused=function(){return c&&c===this.el};TextAreaPrototype.parent=function(){return this.e.parentNode};TextAreaPrototype.attr=function(b,a){var c=this.e;if(1===arguments.length)return c.getAttribute(b);null==a?c.removeAttribute(b):c.setAttribute(b,a);return this};TextAreaPrototype.editable= +function(){return!!this.l};TextAreaPrototype.enable=function(){var b=this.p;this.e.removeAttribute("readonly");this.listen();b&&b.enable&&b.enable(this.l);return this};TextAreaPrototype.disable=function(){var b=this.p;this.e.setAttribute("readonly",!0);this.unlisten();b&&b.disable&&b.disable();return this};TextAreaPrototype.listen=function(){var b=this.l;b&&b.kill();this.l=m(this.e);return this};TextAreaPrototype.unlisten=function(){var b=this.l;b&&(b.kill(),this.l=null);return this};TextAreaPrototype.setInvs= +function(b,a){var c=this.i||!1;if(a||c!==b)this._i&&(this._i.kill(),delete this._i),(c=this.p)?c.invs&&c.invs(b):b&&(this._i=n.require("$47","mirror.js").init(this.e)),this.i=b;return this};TextAreaPrototype.getInvs=function(){return this.i||!1};TextAreaPrototype.setMode=function(b){var a=this.p,g=this.i||!1;b!==(this.m||"")&&(this.m=b,a&&a.kill(),this.p=a="code"===b?n.require("$15","ace.js").init(this.e,this.l,this["%"]):"html"===b?n.require("$48","mce.js").init(this.e,this.l):null,this.setInvs(g, +!0),c&&this.focus());return this};TextAreaPrototype.setStrf=function(b){this["%"]=b;"code"===this.m&&this.p.strf(b);return this};TextAreaPrototype.name=function(b){this.e.setAttribute("name",b);return this};TextAreaPrototype.placeholder=function(b){this.e.setAttribute("placeholder",b);return this};TextAreaPrototype.redraw=function(){var b=this.p;b&&b.resize&&b.resize()};TextAreaPrototype=null;return f}({},r,s));n.register("$45",function(f,d,n){function m(a){var b=d.console;b&&b.error&&b.error(a)} +function g(a){var b=n.createElement("div");a&&b.setAttribute("class",a);return b}function c(a){return function(){a.resize();return this}}function b(a){return function(b){for(var c=b.target,e=c.$index;null==e&&"DIV"!==c.nodeName&&(c=c.parentElement);)e=c.$index;null!=e&&(b.stopImmediatePropagation(),a.select(e));return!0}}function a(a){return function(){a.redrawDirty()&&a.redraw();return!0}}function l(a){return function(b){var c;c=b.keyCode;if(40===c)c=1;else if(38===c)c=-1;else return!0;if(b.shiftKey|| +b.ctrlKey||b.metaKey||b.altKey)return!0;a.selectNext(c);b.stopPropagation();b.preventDefault();return!1}}function e(a,b,c){function e(a){m("row["+a+"] disappeared");return{cellVal:function(){return""}}}return function(h){var g=b||0,d=c?-1:1,l=a.rows||[];h.sort(function(a,b){return d*(l[a]||e(a)).cellVal(g).localeCompare((l[b]||e(b)).cellVal(g))})}}function p(a){this.w=a}function h(a){this.t=a;this.length=0}function v(a,b,c){var e=n.createElement("div");e.className=c||"";this._=e;this.d=b||[];this.i= +a||0;this.length=b.length}function D(a){this.live=a;this.rows=[]}f.create=function(a){return new p(a)};var q=p.prototype;q.init=function(e){var h=this.w,d=h.id,p=h.splity(d+"-thead",d+"-tbody"),f=p[0],p=p[1],C=[],q=[],m=[],B=[];if(e)this.ds=e,this.idxs=q,this._idxs=null;else if(!(e=this.ds))throw Error("No datasource");f.css.push("wg-thead");p.css.push("wg-tbody");e.eachCol(function(a,b,c){m[a]=d+"-col-"+b;B[a]=c||b});for(var I=g(),L=-1,D=m.length,n=g("wg-cols"),J=f.splitx.apply(f,m);++Lg);)d=f[b],a+=d.height(),al)for(b=l;be;b--)d=f[b], +d.rendered&&d.sleep();this.mx=e}};q.selected=function(){return this.r};q.thead=function(){return this.w.cells[0]};q.tbody=function(){return this.w.cells[1]};q.tr=function(a){return(a=this.row(a))?a.cells():[]};q.row=function(a){return this.rows[a]};q.td=function(a,b){return this.tr(a)[b]};q.next=function(a,b,c){null==c&&(c=this.r||0);var e=this.idxs,h=e.length,d=(this.idxr||{})[c];for(c=d;c!==(d+=a)&&!(0<=d&&h>d);)if(b&&h)d=1===a?-1:h,b=!1;else return null;c=e[d];return null==c||null==this.rows[c]? +(m("Bad next: ["+d+"] does not map to data row"),null):c};q.selectNext=function(a,b,c){a=this.next(a,b);null!=a&&this.r!==a&&this.select(a,c);return this};q.deselect=function(a){var b=this.r;null!=b&&(this.r=null,k(this.tr(b)).removeClass("selected"),this.w.fire("wgRowDeselect",[b,a]));return this};q.selectRow=function(a,b){return this.select(this.idxs[a])};q.select=function(a,b){var c=this.rows[a],e=c&&c.page;if(!e)return this.deselect(!1),m("Row is filtered out"),this;this.deselect(!0);var d,h= +this.w.cells[1];e.rendered||(d=e.top(),h.scrollY(d),this.redrawDirty()&&this.redraw());if(!c.rendered)return e.rendered||m("Failed to render page"),m("Row ["+c.i+"] not rendered"),this;e=c.cells();k(e).addClass("selected");this.r=a;b||(d=h.scrollY(),k(this.root).focus(),d!==h.scrollY()&&h.scrollY(d));h.scrollTo(e[0],!0);this.w.fire("wgRowSelect",[a,c.data()]);return this};q.unfilter=function(){this._idxs&&(this.idxs=this._sort(this._idxs),this._idxs=null,this.clear().render());return this};q.filter= +function(a){this._idxs||(this._idxs=this.idxs);this.idxs=this._sort(a);return this.clear().render()};q.each=function(a){for(var b,c=-1,e=this.rows||[],d=this.idxs||[],h=d.length;++cg?0:g-l;this._h!==g&&(this._h=g,c.style.height=String(g)+"px",d=e);this._w!==h&&(this._w=h,d=e);d&&d.redraw()}c=this.length;h=1;g=this.nav;for(l=2===this.dir?"height":"width";0!==c--;)e=this.cells[c],g?d=1:(e.fixed&& +(e.pos=e.fixed/k(b)[l]()),d=h-e.pos,h=e.pos),e.el.style[l]=String(100*d)+"%",e.redraw(a);return this};d.contents=function(a,b){var c=this.el,e=this.body;if(null==a)return e.innerHTML;this.length?this.clear():e&&(c.removeChild(e),e=null);e||(this.body=e=c.appendChild(h.el("",b||"wg-content")),this._h=null,(c=this.lang)&&this._locale(c,this.rtl,!0));"string"===typeof a?k(e)._html(a):a&&this.append(a);this.redraw();return this};d.textarea=function(a,b){var c=this.field;if(c){var e=c.editable();c.reload(a, +b);e!==b&&this.restyle()}else this.length&&this.clear(),e=h.el("textarea"),e.setAttribute("wrap","virtual"),e.value=a,this.contents(e),c=n.require("$44","field.js")._new(e)[b?"enable":"disable"](),l(this,e),this.field=c,this.restyle();this.lang||this.locale("en");return c};d.locale=function(a){a=n.require("$36","locale.js").cast(a);return this._locale(String(a),a.isRTL())};d._locale=function(a,b,c){var e=this.body;if(c||a!==this.lang)this.lang=a,e&&e.setAttribute("lang",a);if(c||b!==this.rtl)this.rtl= +b,e&&e.setAttribute("dir",b?"RTL":"LTR");return this};d.editable=function(){var a=this.field;if(a)return a.editable()?a:null;var b=this.cells,c=b.length,e=this.navigated();if(null!=e)return b[e].editable();for(;++ed)c=d;else{var h= +e.clientHeight,d=d+k(a).outerHeight();if(h+c').data("idx",c).text(a[c]).appendTo(v);b.pos=0;k(b.el).hide()});e(g[c]?c:0);d.lock();d.redraw();return d};d.navigated=function(){var a=this.nav;if(a)return k(a).data("idx")};d=null;return f}({},r,s));n.register("$23",function(f,d,s){function m(a){var b=[];a&&(a.saved()||b.push("po-unsaved"),a.fuzzy()?b.push("po-fuzzy"):a.flagged()&&b.push("po-flagged"),a.translation()|| +b.push("po-empty"),a.comment()&&b.push("po-comment"));return b.join(" ")}function g(a,b,c){b=k(a.title(b).parentNode);var e=b.find("span.lang");c?(c=n.require("$36","locale.js").cast(c),e.length||(e=k("").prependTo(b)),e.attr("lang",c.lang).attr("class",c.getIcon()||"lang region region-"+(c.region||"zz").toLowerCase())):(e.remove(),c="en");a.locale(c);return b}function c(a,b,c){b.click(function(b){var e=a.fire(c,[b.target]);e||b.preventDefault();return e})}function b(){this.dirty=0}n.require("$3", +"number.js");var a="poUpdate",l="changing",e="changed",p=0,h=1,v=2,D=3,q=4,w=5,A=/^\s+/,u,z,r=n.require("$35","string.js").html,C=n.require("$5","string.js").sprintf;f.extend=function(a){return a.prototype=new b};f.localise=function(a){z=a;return f};var F=function(){var a=s.createElement("p");return function(b){a.innerHTML=b.replace("src=","x=");return a.textContent}}(),x=b.prototype=n.require("$37","abstract.js").init(["getListColumns","getListHeadings","getListEntry"],["editable","t"]);x.init=function(){this.localise(); +this.editable={source:!0,target:!0};this.mode="";this.html=!1;return this};x.localise=function(a){a||(a=z||n.require("$1","t.js").init());var b=[];b[p]=a._x("Source text","Editor")+":";b[D]=a._x("%s translation","Editor")+":";b[q]=a._x("Context","Editor")+":";b[w]=a._x("Comments","Editor")+":";b[h]=a._x("Single","Editor")+":";b[v]=a._x("Plural","Editor")+":";b[6]=a._x("Untranslated","Editor");b[7]=a._x("Translated","Editor");b[8]=a._x("Toggle Fuzzy","Editor");b[9]=a._x("Suggest translation","Editor"); +this.labels=b;this.t=a;return this};x.setRootCell=function(a){function b(a){c.redraw(!0,a);return!0}var c=n.require("$38","wingrid.js").init(a);k(d).on("resize",b);this.redraw=b;k(a).on("wgFocus wgBlur",function(a,b){a.stopPropagation();u=b});this.destroy=function(){c.destroy();k(d).off("resize",b)};this.rootDiv=a;return c};x.$=function(){return k(this.rootDiv)};x.setListCell=function(a){var b=this;b.listCell=a;a.on("wgRowSelect",function(a,c){b.loadMessage(b.po.row(c));return!0}).on("wgRowDeselect", +function(a,c,e){e||b.loadNothing();return!0})};x.setSourceCell=function(a){this.sourceCell=a};x.setTargetCell=function(a){this.targetCell=a};x.next=function(a,b,c){for(var e=this.listTable,d=e.selected(),h=d,g,l=this.po;null!=(d=e.next(a,c,d));){if(h===d){d=null;break}if(b&&(g=l.row(d),g.translated(0)))continue;break}null!=d&&e.select(d,!0);return d};x.current=function(a){var b=this.active;if(null==a)return b;a?a.is(b)?this.reloadMessage(a):this.loadMessage(a):this.unloadActive();return this};x.getTargetOffset= +function(){if(this.active)return this.targetCell&&this.targetCell.navigated()||0};x.getTargetEditable=function(){return this.editable.target&&this.targetCell&&this.targetCell.editable()};x.getSourceEditable=function(){return this.editable.source&&this.sourceCell&&this.sourceCell.editable()};x.getContextEditable=function(){return this.editable.context&&this.contextCell&&this.contextCell.editable()};x.getFirstEditable=function(){return this.getTargetEditable()||this.getSourceEditable()||this.getContextEditable()}; +x.searchable=function(a){a&&(this.dict=a,this.po&&this.rebuildSearch());return this.dict&&!0};x.rebuildSearch=function(){var a=-1,b=this.po.rows,c=b.length,e=this.dict;for(e.clear();++a"+r(l[q])+""), +p.push(""+r(d)+"");if(v&&this.getTag)for(p.push("Tagged:");0<=--v;)(d=this.getTag(f[v]))&&p.push(''+r(d.mod_name)+"");p.length&&e.push(p.join(" "));if(this.getMono()&&(d=a.refs())&&(f=d.split(/\s/),v=f.length)){for(p=[];0<=--v;)d=f[v],p.push(""+r(d)+"");e.push('

'+p.join(" ")+"

")}(d=a.notes())&&e.push('

'+r(d,!0)+"

");e.length?(g||(g=b.find("div.meta"),g.length||(g=k('
').insertAfter(b.header())), +c(this,g,"poMeta"),this.$smeta=g),g.html(e.join("\n")).show(),h=!0):g&&g.text()&&(g.text("").hide(),h=!0);return h};x.setTrgMeta=function(a,b,c){var e=[],d=!1,h=this.$tmeta;b=(a=a.errors(b))&&a.length;var g;if(b)for(g=0;g'+r(a[g],!0)+".

");e.length?(h||(h=c.find("div.meta"),h.length||(h=k('
').insertAfter(c.header())),this.$tmeta=h),h.html(e.join("\n")).show(),d=!0):h&&h.text()&&(h.text("").hide(),d=!0);return d};x.loadMessage= +function(b){function c(a,b){var e=b?a.split(" "):a.split(" ",1);a=e[0];"="===a.charAt(0)&&(a=a.substr(1),a=["zero","one","two"][Number(a)]||a);e[0]=a.charAt(0).toUpperCase()+a.substr(1).toLowerCase();return e.join(" ")}function d(a,e){var l=R,k=N[p];a.off();a.titled()!==k&&g(a,k,e||"en");k=!1;y.setSrcMeta(b,a)&&(k=!0);if(b.plural()){var k=-1,q=[],m=[],n=a.id+"-",D=b.sourceForms()||e&&e.plurals||["One","Other"],w=D.length;if(2!==w||"="===D[0].charAt(0)&&"=1"!==D[0])for(;++k');n.require("$11","tooltip.js").init(a);return a}function c(a){return g("cloud").attr("title",a.labels[8]+" (Ctrl-U)").click(function(b){b.preventDefault();a.focus().fuzzy(!a.fuzzy())})}function b(a){return g("robot").attr("title",a.labels[9]+" (Ctrl-J)").click(function(b){b.preventDefault();a.fire("poHint")})}d=n.require("$23", +"base.js");f.init=function(a){var b=new m;a=b.setRootCell(a);var c=a.splity("po-list","po-edit"),d=c[0],h=c[1],c=h.splitx("po-trans","po-comment"),g=c[0],f=c[1].header("Loading.."),c=g.splity("po-source","po-target"),g=c[0].header("Loading.."),c=c[1].header("Loading..");a.distribute([0.34]);h.distribute([0.8]);b.setListCell(d);b.setSourceCell(g);b.setTargetCell(c);b.commentCell=f;b.editable.source=!1;return b};d=m.prototype=d.extend(m);d.getListHeadings=function(){var a=this.t||{_x:function(a){return a}}, +b=[a._x("Source text","Editor")];this.targetLocale&&(b[1]=a._x("Translation","Editor"));return b};d.getListColumns=function(){var a={source:0};this.targetLocale&&(a.target=1);return a};d.getListEntry=function(a){var b=this.cellText,c=[function(){var c,e=b(a.source()||""),d=a.context();return d?(c=s.createElement("p"),c.appendChild(s.createElement("mark")).innerText=d,c.appendChild(s.createTextNode("\u00a0"+e)),c):e}];this.targetLocale&&(c[1]=function(){return b(a.translation()||"")});return c};d.stats= +function(){var a=this.po,b=a.length,c=0,d=0,h=0;a.each(function(a,b){b.fuzzy()?h++:b.translated()?c++:d++});return{t:b,p:c.percent(b)+"%",f:h,u:d}};d.unlock=function(){var a=this.targetLocale;this._unlocked||(this.editable={source:!0,context:!0,target:!1},this.po&&this.po.unlock(),this.contextCell=this.targetCell,delete this.targetCell,a&&(this._unlocked=a,delete this.targetLocale,this.reload(),this.fire("poLock",[!1])),this.active&&this.loadMessage(this.active))};d.lock=function(){var a=this._unlocked; +a&&(this.targetLocale=a,delete this._unlocked,this.po&&this.po.lock(a),this.editable={source:!1,context:!1,target:!0},this.targetCell=this.contextCell,delete this.contextCell,this.reload(),this.fire("poLock",[!0,a]),this.active&&this.loadMessage(this.active))};d.locked=function(){return!this._unlocked};d.setStatus=function(a){var d=this.$tnav;if(null==a)d&&(d.remove(),this.$tnav=null);else{d||(this.$tnav=d=k("").append(c(this)).append(b(this)).appendTo(this.targetCell.header()));var e= +[];a.translated()?a.fuzzy()&&e.push("po-fuzzy"):e.push("po-empty");d.attr("class",e.join(" "))}};d.getSorter=function(){function a(a,c){var e=a.weight(),d=c.weight();return e===d?b(a,c):e>d?-1:1}function b(a,c){return a.hash().localeCompare(c.hash())}var c=this;return function(d){var h=c.po,g=c.locked()?a:b;d.sort(function(a,b){return g(h.row(a),h.row(b))})}};return f}({},r,s));n.register("$13",function(f,d,n){var m={copy:66,clear:75,save:83,fuzzy:85,next:40,prev:38,enter:13,invis:73,hint:74},g={38:!0, +40:!0,73:!0},c={66:function(b,a){var c=a.current();c&&(c.normalize(),a.focus().pasteMessage(c))},75:function(b,a){var c=a.current();c&&(c.untranslate(),a.focus().pasteMessage(c))},85:function(b,a){a.focus().fuzzy(!a.fuzzy())},13:function(b,a){a.getFirstEditable()&&a.next(1,!0,!0)},40:function(b,a){var c=b.shiftKey;a.next(1,c,c)},38:function(b,a){var c=b.shiftKey;a.next(-1,c,c)},73:function(b,a){if(!b.shiftKey)return!1;a.setInvs(!a.getInvs())}};f.init=function(b,a){function l(a){if(a.isDefaultPrevented()|| +!a.metaKey&&!a.ctrlKey)return!0;var d=a.which;if(!e[d])return!0;var l=c[d];if(!l)throw Error("command undefined #"+d);if(a.altKey||a.shiftKey&&!g[d]||!1===l(a,b))return!0;a.stopPropagation();a.preventDefault();return!1}var e={};k(a||d).on("keydown",l);return{add:function(a,b){c[m[a]]=b;return this},enable:function(){var a,b;for(b in arguments)a=m[arguments[b]],e[a]=!0;return this},disable:function(){k(a||d).off("keydown",l);b=a=e=null}}};return f}({},r,s));n.register("$24",function(f,d,k){function m(){this.reIndex([])} +f.init=function(){return new m};d=m.prototype;d.reIndex=function(d){for(var c={},b=-1,a=d.length;++bd;){h=b.exec(c)||a.exec(c);if(null==h)break;h=h[0];e.push(h);h=h.length;f-=h;c=c.substr(h)}0!==f&&e.push(c);return e}}f.create=function(d){function c(a){return h[a]||"\\"+a}var b, +a,l=/(?:\r\n|[\r\n\v\f\u2028\u2029])/g,e=/[ \r\n]+/g,f=/[\t\v\f\x07\x08\\\"]/g,h={"\t":"\\t","\v":"\\v","\f":"\\f","\u0007":"\\a","\b":"\\b"};if(null==d||isNaN(d=Number(d)))d=79;0"));return{pair:function(b,e){if(!e)return b+' ""';e=e.replace(f,c);var h=0;e=e.replace(l,function(){h++;return"\\n\n"});if(!(h||d&&d]*>/i.test(a)||/&(#\d+|#x[0-9a-f]|[a-z]+);/i.test(a)?k("

").html(a).text():a}function c(a){return a.replace(/%(?:\d+\$)?(?:'.|[-+0 ])*\d*(?:\.\d+)?[suxXbcdeEfFgGo]/g, +"%s")}function b(a){return a.replace(/[^\sa-z0-9]+/ig," ")}function a(a){return a.trim().replace(/\s+/g," ")}function f(e){return a(b(d(c(e).toLowerCase())))}var e={},p={};return{add:function(a){var b=f(a.source());(e[b]||(e[b]=[])).push(a);p[a.hash()]=a},match:function(h){var k=f(h.source()),k=e[k],m;if(m=k){m=k.length;var q=k[0];if(1!==m)for(var n=7,A,u=h.source(),s=h.context(),r;0<=--m;)if(h=0,A=k[m],!(A.context()!==s&&++h>=n)){r=A.source();if(u!==r){if(++h>=n)continue;u=u.toLowerCase();r=r.toLowerCase(); +if(u!==r){if(++h>=n)continue;u=c(u);r=c(r);if(u!==r){if(++h>=n)continue;u=d(u);r=d(r);if(u!==r){if(++h>=n)continue;u=b(u);r=b(r);if(u!==r){if(++h>=n)continue;u=a(u);r=a(r);if(u!==r&&++h>=n)continue}}}}}n=h;q=A;if(0===h)break}delete p[q.hash()];m=q.copy()}return m},unmatched:function(){var a,b,c=[];for(a in p)b=p[a],c.push(b);return c}}}f.merge=function(f,c){var b=f.rows,a=c.rows,l=[],e=[],p=[],h=m();b.each(function(b,c){a.has(b)||(c.translated()?h.add(c):p.push(c))});f.clear();a.each(function(a,c){try{var p= +b.get(a),k;p?(k=p.flagged(0),p.merge(c),p.flagged(0)!==k&&e.push(p)):(p=h.match(c))?(p.merge(c),e.push(p)):(p=c.copy(),l.push(p));f.add(p,"")}catch(m){d.console&&console.error(String(m))}});f.header("POT-Creation-Date",c.header("POT-Creation-Date")||f.now());return{add:l,fuz:e,del:p.concat(h.unmatched())}};return f}({},r,s));n.register("$28",function(f,d,k){function m(c,b,a){if(null==a)return c[b]||"";c[b]=a||"";return c}function g(){this._id=this.id=""}f.extend=function(c){return c.prototype=new g}; +d=g.prototype;d.flag=function(c,b){var a=this.flg||(this.flg=[]);if(null!=b)a[b]=c;else for(var d=Math.max(a.length,this.src.length,this.msg.length);0!==d--;)a[d]=c;return this};d.flagged=function(c){var b=this.flg||[];if(null!=c)return b[c]||0;for(c=b.length;0!==c--;)if(b[c])return!0;return!1};d.flags=function(){for(var c,b={},a=[],d=this.flg||[],e=d.length;0!==e--;)c=d[e],b[c]||(b[c]=!0,a.push(c));return a};d.flaggedAs=function(c,b){var a=this.flg||[];if(null!=b)return c===a[b]||0;for(var d=a.length;0!== +d--;)if(a[d]===c)return!0;return!1};d.fuzzy=function(c,b){var a=this.flaggedAs(4,c);null!=b&&this.flag(b?4:0,c);return a};d.source=function(c,b){if(null==c)return this.src[b||0]||"";this.src[b||0]=c;return this};d.plural=function(c,b){if(null==c)return this.src[b||1]||"";this.src[b||1]=c||"";return this};d.sourceForms=function(){return this.srcF};d.targetForms=function(){return this.msgF};d.each=function(c){for(var b=-1,a=this.src,d=this.msg,e=Math.max(a.length,d.length);++b=u||(d.flag&&m.flag(d.flag,n),m.translate(d.target||"",n),d.format&&!m.format()&& +m.format(d.format))}catch(s){c(s)}return this};k.merge=function(a){return n.require("$27","merge.js").merge(this,a)};k.wrap=function(a){this.fmtr=b(a);return this};k.toString=function(){var a,c=this.locale(),d=[],f=[],g=this.headers(),k=!c,m=c&&c.nplurals||2,n=this.fmtr||b();g[c?"PO-Revision-Date":"POT-Creation-Date"]=this.now();for(a in g)f.push(a+": "+g[a]);f=new l("",f.join("\n"));f.comment(this.headcmt||"");k&&f.fuzzy(0,!0);d.push(f.toString());d.push("");this.rows.each(function(a,b){a&&(d.push(b.cat(n, +k,m)),d.push(""))});return d.join("\n")};k=n.require("$28","message.js").extend(l);k.hash=function(){return g(this.source(),this.context())};k.toString=function(){return this.cat(b())};k.cat=function(a,b,c){var d,f=[],l;(l=this.cmt)&&f.push(a.prefix(l,"# "));(l=this.xcmt)&&f.push(a.prefix(l,"#. "));d=this.rf;if(l=this._id)d+=(d?" ":"")+"loco:"+l;d&&/\S/.test(d)&&f.push(a.refs(d));!b&&this.fuzzy()&&f.push("#, fuzzy");(l=this.fmt)&&f.push("#, "+l+"-format");(l=this._ctx)&&f.push(a.prefix(a.pair("msgctxt", +l),"#| "));if(l=this._src)l[0]&&f.push(a.prefix(a.pair("msgid",l[0]),"#| ")),l[1]&&f.push(a.prefix(a.pair("msgid_plural",l[1]),"#| "));(l=this.ctx)&&f.push(a.pair("msgctxt",l));f.push(a.pair("msgid",this.src[0]));if(null==this.src[1])f.push(a.pair("msgstr",b?"":this.msg[0]));else for(d=-1,f.push(a.pair("msgid_plural",this.src[1])),l=this.msg||["",""],c=c||l.length;++d +d)return 1;if(cd)return-1}return 0};k.merge=function(a){var b=!1;this.rf=a.rf;this.fmt=a.fmt;this.cmt=a.cmt;this.xcmt=a.xcmt;a.src.join("\x00")!==this.src.join("\x00")&&(this._src=this.src,this.src=a.src.concat(),this.msg=(this.msg||["",""]).slice(0,this.src.length),b=!0);a.ctx!==this.ctx&&(this._ctx=this.ctx,this.ctx=a.ctx,b=!0);b&&this.translated()&&this.fuzzy(0,!0)};k.copy=function(){var a=new l,b,c;for(b in this)this.hasOwnProperty(b)&& +((c=this[b])&&c.concat&&(c=c.concat()),a[b]=c);return a};k=k=null;return f}({},r,s));n.register("$16",function(f,d,n){f.init=function(d,f){function c(){return e||(e=k('
').dialog({dialogClass:"loco-modal loco-modal-wide",modal:!0,autoOpen:!1,closeOnEscape:!0,resizable:!1,height:500}))}function b(a,b,d){a=k("

").text(d);c().dialog("close").html("").dialog("option","title","Error").append(a).dialog("open")}function a(a){var b=a&&a.code;if(b){for(var d=-1,e=b.length, +f=k("
    ").attr("class",a.type);++d").html(b[d]).appendTo(f);f.find("li").eq(a.line-1).attr("class","highlighted");c().dialog("close").html("").dialog("option","title",a.path+":"+a.line).append(f).dialog("open")}}function l(a){a=a.target;var b=k(a).find("li.highlighted")[0],b=Math.max(0,(b&&b.offsetTop||0)-Math.floor(a.clientHeight/2));a.scrollTop=b}var e;return{load:function(e){c().html('
    ').dialog("option","title","Loading..").off("dialogopen").dialog("open").on("dialogopen", +l);e=k.extend({ref:e,path:f.popath},f.project||{});d.ajax.post("fsReference",e,a,b)}}};return f}({},r,s));n.register("$30",function(f,d,k){function m(d){this.api=d;this.chars=0}f.create=function(d){return new m(d)};d=m.prototype;d.init=function(d,c){function b(a){var b={length:0,html:a.html,sources:[]};q.push(b);return w[a.html?1:0]=b}function a(a,d){var g=a.source(null,d);if(g&&(a.untranslated(d)||c)){var q=n[g];if(q)q.push(a);else{var q=g.length,r=f.isHtml(g),r=w[r?1:0],s=r.sources;if(r.length+ +q>m||s.length===h)r=b(r),s=r.sources;s.push(g);n[g]=[a];r.length+=q;e+=q;k+=1}}}var f=this.api,e=0,k=0,h=50,m=5E3,n={},q=[],w=[];b({html:!1});b({html:!0});d.each(function(b,c){a(c,0);a(c,1)});w=null;this.map=n;this.chars=e;this.length=k;this.batches=q;this.locale=d.locale()};d.abort=function(){this.state="abort";return this};d.dispatch=function(){function d(a,b){function e(c,d,l){b!==l&&(a===d||1').dialog({dialogClass:"request-filesystem-credentials-dialog loco-modal",minWidth:580,modal:!0,autoOpen:!1,closeOnEscape:!0}).on("change",'input[name="connection_type"]',function(){this.checked&&k("#ssh-keys").toggleClass("hidden","ssh"!==k(this).val())}));return M} +function c(){G&&(b(k(u)),G=!1);if(C&&K){var a=K,c=k(Q);c.find("span.loco-msg").text(a);J||(c.removeClass("jshide").hide().fadeIn(500),J=!0)}else J&&(b(k(Q)),J=!1)}function b(a){a.slideUp(250).fadeOut(250,function(){k(this).addClass("jshide")})}function a(){if(C)return M&&M.dialog("close"),c(),k(f).find('button[type="submit"]').attr("disabled",!1),k(d).triggerHandler("resize"),A&&A(!0),!0;x&&M?(G||(k(u).removeClass("jshide").hide().fadeIn(500),G=!0),J&&(b(k(Q)),J=!1)):c();k(f).find('input[type="submit"]').attr("disabled", +!0);A&&A(!1);return!1}function l(a){var b,c,d=w||{};for(b in d)d.hasOwnProperty(b)&&(c=d[b],a[b]?a[b].value=c:k('').attr("name",b).appendTo(a).val(c))}function e(a){a.preventDefault();a=k(a.target).serializeArray();q(a);H=!0;return!1}function p(a){a.preventDefault();M.dialog("close");return!1}function h(a){a.preventDefault();M.dialog("open").find('input[name="connection_type"]').change();return!1}function r(b){C=b.authed;z=b.method;k(u).find("span.loco-msg").text(b.message|| +"Something went wrong.");K=b.warning||"";b.notice&&F.notices.info(b.notice);if(C)"direct"!==z&&(w=b.creds,l(f),H&&b.success&&F.notices.success(b.success)),a();else if(b.reason)F.notices.info(b.reason);else if(b=b.prompt){var c=g();c.html(b).find("form").submit(e);c.dialog("option","title",c.find("h2").remove().text());c.find("button.cancel-button").show().click(p);c.find('input[type="submit"]').addClass("button-primary");a();k(d).triggerHandler("resize")}else F.notices.error("Server didn't return credentials, nor a prompt for credentials")} +function s(){a()}function q(a){H=!1;F.ajax.setNonce("fsConnect",I).post("fsConnect",a,r,s);return a}var w,A,u=f,z=null,H=!1,C=!1,F=d.locoScope,x=f.path.value,B=f.auth.value,I=f["loco-nonce"].value,L=k(u).find("button.button-primary"),Q=n.getElementById(u.id+"-warn"),G=!1,J=!1,K="",M;F.notices.convert(Q).stick();f.connection_type?(w={},w.connection_type=f.connection_type.value,C=!0):x&&B&&q({path:x,auth:B});a();return{applyCreds:function(a){if(a.nodeType)l(a);else{var b,c=w||{};for(b in c)c.hasOwnProperty(b)&& +(a[b]=c[b])}return this},setForm:function(b){f=b;a();l(b);return this},connect:function(){x=f.path.value;B=f.auth.value;q(k(f).serializeArray());return this},listen:function(a){A=a;C&&a(!0);return this}}};return f}({},r,s));n.register("$19",function(f,d,r){function m(d,e,f,h){e="n"===f?c(e):b(e);h&&(e=a(e));return g([].sort,[e])(d)}function g(a,b){return function(c){a.apply(c,b);return c}}function c(a){return function(b,c){var d=b&&b[a]||0,f=c&&c[a]||0;return d===f?0:d>f?1:-1}}function b(a){return function(b, +c){return(b&&b[a]||"").localeCompare(c&&c[a]||"")}}function a(a){return function(b,c){return-1*a(b,c)}}f.init=function(a){function b(a){var c=-1,d=a.length;for(k("tr",u).remove();++c div"),e=n.eq(0).clone(),o=n.length,t="["+o+"]";function i(n,e){var o=e.name.replace("[0]",t);c(e).attr("name",o).val("")}e.attr("id","loco-conf-"+o),e.find("input").each(i),e.find("textarea").each(i),e.find("h2").eq(0).html("New set (untitled)"),e.insertBefore("#loco-form-foot"),f(e.find("a.icon-del"),o),e.hide().slideDown(500),c("html, body").animate({scrollTop:function(n,e){for(var o=n.offsetTop;(n=n.offsetParent)&&n!==e;)o+=n.offsetTop;return o}(e[0])},500)}function f(n,e){return n.click(function(n){return n.preventDefault(),function(n){var e=c("#loco-conf-"+n);e.find('input[name="conf['+n+'][removed]"]').val("1"),e.slideUp(500,function(){c(this).hide().find("table").remove()})}(e),!1})}c("#loco-conf > div").each(function(n,e){f(c(e).find("a.icon-del"),n)}),c("#loco-add-butt").attr("disabled",!1).click(function(n){return n.preventDefault(),o(),!1})}(window,document,jQuery); \ No newline at end of file diff --git a/vendor/loco-translate/pub/js/min/debug.js b/vendor/loco-translate/pub/js/min/debug.js new file mode 100644 index 0000000..150a68a --- /dev/null +++ b/vendor/loco-translate/pub/js/min/debug.js @@ -0,0 +1 @@ +!function(n,o,t){var a=t("#loco-utf8-check")[0].textContent;function c(o,a,e){"success"!==a&&(e=n.ajax.parse(n.ajax.strip(o.responseText))),t("#loco-ajax-check").text("FAILED: "+e).addClass("loco-danger")}1===a.length&&10003===a.charCodeAt(0)||n.notices.warn("This page has a problem rendering UTF-8").stick(),window.ajaxurl&&t("#loco-ajax-url").text(window.ajaxurl),n.ajax.post("ping",{echo:"ΟΚ ✓"},function(o,a,e){o&&o.ping?t("#loco-ajax-check").text(o.ping):c(e,a,o&&o.error&&o.error.message)},c);var e,r=o.apis,i=r.length,s=-1,l=n.locale.parse("fr");function d(o,a){return t("#loco-api-"+o).text(a)}function p(o){var e=o.getId();o.key()?o.translate("OK",l,function(o,a){a?d(e,"OK ✓"):d(e,"FAILED").addClass("loco-danger")}):d(e,"No API key")}for(;++s').attr("tabindex",String(++d)).text(c._("Use this translation")).on("click",function(e,a){return function(t){t.preventDefault(),t.stopPropagation(),p();var n=C.current(),o=C.getTargetOffset();n&&n.source(null,o)===e?(n.translate(a,o),C.focus().reloadMessage(n)):D.notices.warn("Source changed since suggestion")}}(t,n));l&&l.replaceWith(S('
    ').append(S('').attr("href",i).text(r)).append(S("
    ").text(n||"FAILED")).append(s)),f.dialog("option","position",{my:"center",at:"center",of:w}),++y===v&&f&&f.dialog("option","title",c._("Suggested translations")+" — "+o.label),1===y&&s.focus(),s.attr("accesskey",String(y))}function p(t){f&&null==t&&f.dialog("close"),m=f=null,S(w).off("keydown",e)}function i(e){return function(t,n,o){a(t,b[e.getId()]=n,o,e)}}var f=(_=_||S('
    ').dialog({dialogClass:"loco-modal",modal:!0,autoOpen:!1,closeOnEscape:!0,resizable:!1,minHeight:400})).html("").append(S('

    Source text:

    ').append(S('
    ').text(o))).dialog("option","title",c._("Loading suggestions")+"...").off("dialogclose").on("dialogclose",p).dialog("open"),r=t.translation(n);r&&S('

    Current translation:

    ').append(S("
    ").text(r)).append(S('').attr("tabindex",String(++d)).text(c._("Keep this translation")).on("click",function(t){t.preventDefault(),p()})).appendTo(f);var l,s,g=j(),v=g.length,h=-1,b=I[o]||(I[o]={}),m={},y=0;for(;++h').text("Calling "+x+" ..."),m[x.getId()]=k)),s=l.getId(),b[s]?a(o,b[s],T,l):l.translate(o,T,i(l));var x,k;S(w).on("keydown",e)}():E()}function k(t){return t.preventDefault(),h.length?function(){var e,a,i,r=0,l=z,n=!1,s=M().dialog("open"),t=s.find("form"),c=t.find("button.button-primary"),o=S("#loco-job-progress");function u(){c[0].disabled=!0}function d(){c.removeClass("loco-loading")}function p(t){o.text(t)}function f(t){var n=function(t){for(var n,o=j(),e=o.length,a=-1;++a

    ').text(e).appendTo(v(""))}function y(e,t){var n,a=t.getElementsByTagName("tr"),r=a.length,i=t.getAttribute("data-diff").split(/\D+/),o=i[0],s=i[1],d=i[2],l=i[3];function f(e,t,n){t<=n&&u("").text(String(t)).prependTo(e)}for(e=0;e":e:"";t.find("code.path span").each(function(t,e){e.textContent=a}),t.find("span.lang").each(function(t,e){!function(t,e){e&&"zxx"!==e.lang?(t.setAttribute("lang",e.lang),t.setAttribute("class",e.getIcon())):(t.setAttribute("lang",""),t.setAttribute("class","lang nolang"))}(e,n)})}function B(t){var e=t&&t.redirect;e&&location.assign(e)}c(d).change(I).submit(function(t){return t.preventDefault(),v.applyCreds(d),s.ajax.submit(t.target,B),!1}),j(g.val())}(window,document,jQuery); \ No newline at end of file diff --git a/vendor/loco-translate/pub/js/min/potinit.js b/vendor/loco-translate/pub/js/min/potinit.js new file mode 100644 index 0000000..aaa5fea --- /dev/null +++ b/vendor/loco-translate/pub/js/min/potinit.js @@ -0,0 +1 @@ +!function(t,e,n){var o=t.locoScope,i=e.getElementById("loco-fs"),c=e.getElementById("loco-potinit");function r(t){var e=t&&t.redirect;e&&location.assign(e)}n(c).submit(function(t){return t.preventDefault(),o.ajax.submit(t.target,r),!1}),i&&o.fs.init(i).setForm(c)}(window,document,jQuery); \ No newline at end of file diff --git a/vendor/loco-translate/pub/js/min/poview.js b/vendor/loco-translate/pub/js/min/poview.js new file mode 100644 index 0000000..a624672 --- /dev/null +++ b/vendor/loco-translate/pub/js/min/poview.js @@ -0,0 +1 @@ +!function(n,o,f){var a,c,i,l,r,p,e,s,u,t=n.locoConf,d=n.locoScope,h=d.po.ref.init(d,t),v=o.getElementById("loco-po");function g(){r.length&&(p.push([i,l]),c.push(r),r=[]),i=null}function m(t){return f('
      ').attr("start",t).appendTo(a)}function x(t){e!==t&&(f("#loco-content")[t?"removeClass":"addClass"]("loco-invalid"),e=t)}a=v,c=d.fulltext.init(),r=[],p=[],s=!(e=!0),(u=f(a).find("li")).each(function(t,e){var n,o=f(e);o.find("span.po-none").length?g():(l=t,null==i&&(i=t),(n=o.find(".po-text").text())&&(r=r.concat(n.replace(/\\[ntvfab\\"]/g," ").split(" "))))}),g(),d.watchtext(f(a.parentNode).find("form.loco-filter")[0].q,function(t){t?function(t){var e,n,o,i=c.find(t),l=-1,r=i.length;if(f("ol",a).remove(),r){for(;++l").text(d.l10n._("Nothing matches the text filter")));s=!0,b()}(t):s&&(x(!0),s=!1,f("ol",a).remove(),m(1).append(u),b())}),f(v).removeClass("loco-loading");var C,y,b=(y=v.clientHeight-2,function(){var t=function(t,e){for(var n=t.offsetTop||0;(t=t.offsetParent)&&t!==e;)n+=t.offsetTop||0;return n}(v,o.body),e=n.innerHeight-t-20;C!==e&&(v.style.height=e").attr("value",o).text(n))},cache:!0})}(window,document,jQuery); \ No newline at end of file diff --git a/vendor/loco-translate/readme.txt b/vendor/loco-translate/readme.txt new file mode 100644 index 0000000..d65b350 --- /dev/null +++ b/vendor/loco-translate/readme.txt @@ -0,0 +1,367 @@ +=== Loco Translate === +Contributors: timwhitlock +Tags: translation, translators, localization, localisation, l10n, i18n, Gettext, PO, MO, productivity, multilingual, internationalization +Requires at least: 4.1 +Requires PHP: 5.2.4 +Tested up to: 5.4.1 +Stable tag: 2.4.0 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Translate WordPress plugins and themes directly in your browser + + +== Description == + +Loco Translate provides in-browser editing of WordPress translation files. + +It also provides localization tools for developers, such as extracting strings and generating templates. + +Features include: + +* Built-in translation editor within WordPress admin +* Integration with automatic translation APIs +* Create and update language files directly in your theme or plugin +* Extraction of translatable strings from your source code +* Native MO file compilation without the need for Gettext on your system +* Support for PO features including comments, references and plural forms +* PO source view with clickable source code references +* Protected language directory for saving custom translations +* Configurable PO file backups with diff and restore capability +* Built-in WordPress locale codes + + +Official [Loco](https://localise.biz/) WordPress plugin by Tim Whitlock. +For more information please visit our [plugin page](https://localise.biz/wordpress/plugin). + + +== Installation == + += Basic usage: = + +Translators: To translate a theme into your language, follow these steps: + +1. Create the protected languages directory at `wp-content/languages/loco/themes` +2. Ensure this directory writeable by the web server +3. Find your theme in the list at *Loco Translate > Themes* +4. Click `+ New language` and follow the on-screen prompts. + + +Developers: To translate your own theme or plugin for distribution, follow these steps: + +1. Create a `languages` subdirectory in your bundle’s root directory +2. Ensure this directory writeable by the web server +3. Find the bundle at either *Loco Translate > Themes* or *Loco Translate > Plugins* +4. Click `+ Create template` and follow the on-screen prompts to extract your strings. +5. Click `+ New language` and follow the on-screen prompts to add your own translations. + + += Installing manually: = + +1. Unzip all files to the `wp-content/plugins/loco-translate` directory +2. Log into WordPress admin and activate the 'Loco Translate' plugin through the 'Plugins' menu +3. Go to *Loco Translate > Home* in the left-hand menu to start translating + + +More information on using the plugin is [available here](https://localise.biz/wordpress/plugin). + + +== Frequently Asked Questions == + +Please visit the [FAQs page](https://localise.biz/wordpress/plugin/faqs) on our website for the most common issues. + += How do I use Loco Translate? = + +Try our [Guides and Tutorials](https://localise.biz/wordpress/plugin#guides). + += How do I get more help? = + +If you have a problem using Loco Translate, please try our [help pages](https://localise.biz/wordpress/plugin). +There's a lot of information there to help you understand how it works and the most common pitfalls to avoid. + +To report a bug please start a new topic in the [support forum](https://wordpress.org/support/plugin/loco-translate), +but please check the [FAQs](https://localise.biz/wordpress/plugin/faqs) for similar issues first. +If you decide to submit a bug report please post enough [relevant detail](https://localise.biz/wordpress/plugin/faqs/debug-info) for us to reproduce your issue. + += Is my data protected? = + +We don't collect your data or snoop on you. See the [plugin privacy notice](https://localise.biz/wordpress/plugin/privacy). + + +== Screenshots == + +1. Translating strings in the browser with the Loco PO Editor +2. Showing translation progress for theme language files +3. PO source view with text filter and clickable file references +4. Restore tab showing PO diff view with revert function +5. Showing access to translations by installed language + + + +== Changelog == + += 2.4.0 +* Added support for third party translation APIs +* Added file references to editor source pane in code view +* Added fuzzy matching during editor Sync operation +* Style changes including rearrangement of editor buttons +* Elevated warnings when scripts are tampered with +* Removed remnants of legacy version 1.x + += 2.3.4 = +* Updated translatable strings +* Added missing template recommendation +* Alerting in debug mode when scripts are tampered with +* Fix for Hello Dolly being installed into a folder +* Removed translation column in POT edit mode +* Added setting to prevent 'translating' of POT files +* Enabled some linkable translations using wp_kses +* Bumped WordPress version to 5.4.1 + += 2.3.3 = +* Fixed fatal error when class not found + += 2.3.2 = +* Removed login/email from default Last-Translator credit +* Bumped WP compatibility to 5.4 +* Fixed PHP 7.4 deprecations + += 2.3.1 = +* Default POT getter now looks in "lang" directory +* Not calling deprecated magic quotes functions under PHP 7.4 +* Fixed issue with conflicting page hooks +* Ajax file uploads now enabled by default +* Removed legacy option migrations from 1.x branch +* Bumped WP compatibility to 5.2.4 + += 2.3.0 = +* Added experimental support for multipart uploads +* Added relocation tab for moving translation sets +* Creation of missing directories when writing new files +* Fixed duplicate file addition when iterating over symlink +* Bumped WP compatibility to 5.2.1 + += 2.2.2 = +* Security fixes for reading sensitive files +* Fixed old PHP version error in data files +* Bumped WP compatibility to 5.1.1 + += 2.2.1 = +* Fixed bug where plural tabs not displaying RTL +* Various improvements to PO parser incl. better charset handling +* Excluding node_modules and vendor directories by default +* Transients now have maximum lifespan of 10 days, refreshed after 24h +* Symlink fix for followed theme paths detected outside theme +* Deprecated config repository lookup +* Bumped WP compatibility to 5.1 + += 2.2.0 = +* Fix for empty language code when getting plural rules +* Added X-Loco-Version header to generated Gettext files +* Added sanity check for mbstring.func_overload madness +* Added "Assign template" link on missing template page +* Added JavaScript string extraction (experimental) +* Editor supports sprintf-js when javascript-format tag present +* Fix for duplicate comments when end punctuation differs +* Marking msgctxt more clearly in editor views +* Added `loco_admin_shutdown` action hook +* Bumped WP compatibility to 5.0 (beta) + += 2.1.5 = +* Updated locale data +* Minor fix to file reference resolution +* Fixed windows paths with trailing backslash +* Fixed ssh-keys toggling issue +* Rejigged buffer handling during Ajax +* Bumped WP compatibility to 4.9.8 + += 2.1.4 = +* Bumped WP compatibility to 4.9.6 +* Hooked in privacy policy suggestion + += 2.1.3 = +* Added loco_locale_name filter and updated locale data +* Fixed editor column sorting to update as values change +* Supporting RTL text in editor preview rows +* Minor refactor of debug mode routing check +* Minor PO parser improvements +* Bumped WP compatibility to 4.9.5 + += 2.1.2 = +* Fixed undeclared property in admin hook +* Fixed incompatibility with older WordPress +* Fixed incorrect millisecond reporting in footer +* Removed locale progress column for en_US locale +* Tweaks to debugging and error logging + += 2.1.1 = +* Setting `Project-Id-Version` on new POT files +* Added source view to quick links in file tables +* Supporting only WordPress style locale codes +* Editor screen tolerates missing PO headers +* Ajax debugging improvements for issue reporting +* Added loco_parse_locale action callback + += 2.1.0 = +* Add `fs_protect` setting to avoid overwriting system files +* Fixed bug in connect dialogue where errors not redisplayed +* Minor improvements to inline notices +* Removed downgrade notice under version tab +* Fixed extraction bug where file header confused with comment +* Resolved some inconsistencies between PHP and JS utilities +* Added Restore tab with diff display +* Added `loco_settings` hook +* Prevented editor from changing PO document order +* Added default string sorting to extracted strings +* Added "Languages" section for grouping files by locale +* Fixed bug where translations loaded before user profile language set +* Added loco_locale_plurals filter for customising plural rules +* Allowing PO files to enforce their own Plural-Forms rules +* Added `loco_allow_remote` filter for debugging remote problems +* Updated plural forms from Unicode CLDR +* PHP extractor avoids repeated comments +* Bumped WP compatibility to 4.9.4 + += 2.0.17 = +* Unofficial languages showing in “Installed” dropdown +* Fixed extraction bug where comment confused with file header +* Fixed issue where src attributes requested from server during HTML strip +* Added loco_admin_init hook into ajax router for consistency +* Added warning on file info page when file is managed by WordPress +* Minor help link and layout tweaks +* Bumped WP compatibility to 4.9.1 + += 2.0.16 = +* File writer observes wp_is_file_mod_allowed +* Fixed progress bug in editor for locales with nplurals=1 +* Made plural form categories translatable for editor UI +* Sync-from-source raises warning when files are skipped +* Added hack for extracting from .twig as per .php +* Added warning when child themes declare parent text domain +* Added option to control PO line wrapping +* Bumped WP compatibility to 4.8.2 + += 2.0.15 = +* Permanently removed legacy version 1.x +* Fixed bug where editor code view was not redrawn on resize +* Fixed bug where fuzzy flag caused format flag to be ignored +* Fixed bug where autoloader responded to very long class names +* Purging WP object cache when active plugin list changes +* Added experimental source word count into POT info tab +* Bumped WP compatibility to 4.8.1 + += 2.0.14 = +* Editor improvements inc. column sorting +* Added warnings that legacy version will be removed +* Added PO source view text filtering +* Added _fs_nonce for 4.7.5 compatibility +* Migrated to canonical text domain +* Removed wp class autoloading + += 2.0.13 = +* CSS conflict fixes +* Added option for UTF-8 byte order mark +* Printf highlighting observes no-php-format flag +* Fixed issue with translator role losing “read” permission + += 2.0.12 = +* Minor fix for root path configs +* Added alternative PHP extensions setting +* Bumped WP version to 4.7.3 +* LoadHelper fix for core files +* Allow revoking of permissions from translator role +* Allow network admins to deny access to site admins + += 2.0.11 = +* Extra debug logging and error diagnostics +* Forcefully clear output buffers before Ajax flush +* Bumped WordPress version to 4.7 +* Experimental wildcard text domain support + += 2.0.10 = +* Allows missing domain argument in plugin_locale filter +* Reverted editor changes that disabled readonly text +* Added invisibles and coding editor switches +* Added table filtering via text query +* Added Last-Translator user preference + += 2.0.9 = +* Bumped minimum WordPress version to 4.1 +* Some optimisation of transient caching +* Fixed hash table settings bug + += 2.0.8 = +* Source refs fix for files in unknown subsets +* Downgrades PO formatting exceptions to PHP warnings +* Renamed function prefixes to avoid PHP 7 warnings +* Better support for php-format and no-php-format flag +* PO source and editor UI tweaks +* Localised strings and implemented in js + += 2.0.7 = +* Fixed prototype.js conflict +* More Windows file path fixes +* Added loco_current_translator filter +* Fixed false positive in extra files test + += 2.0.6 = +* PO wrapping bugfix +* Downgraded source code bugfix +* Tolerating headerless POT files +* Core bundle metadata tweaks + += 2.0.5 = +* Deferred missing tokenizer warning +* Allows editing of files in unconfigured sets +* Added maximum PHP file size for string extraction +* Display of PHP fatal errors during Ajax + += 2.0.4 = +* Reduced session failures to debug notices +* Added wp_roles support for WP < 4.3 +* Fixed domain listener bugs + += 2.0.3 = +* Added support for Windows servers +* Removed incomplete config warning on bundle overview + += 2.0.2 = +* Fixed bug when absolute path used to get plugins +* Added loco_plugins_data filter +* Added theme Template Name header extraction +* Minor copy amends + += 2.0.1 = +* Added help link in settings page +* Fixed opendir warnings in legacy code +* Catching session errors during init +* Removing meta row link when plugin not found + += 2.0.0 = +* First release of completely rebuilt version 2 + + +== Upgrade Notice == + += 2.4.0 = +* Various improvements including automatic translation support + + + +== Keyboard shortcuts == + +The PO file editor supports the following keyboard shortcuts for faster translating: + +* Done and Next: `Ctrl ↵` +* Next string: `Ctrl ↓` +* Previous string: `Ctrl ↑` +* Next untranslated: `Shift Ctrl ↓` +* Previous untranslated: `Shift Ctrl ↑` +* Copy from source text: `Ctrl B` +* Clear translation: `Ctrl K` +* Toggle Fuzzy: `Ctrl U` +* Save PO / compile MO: `Ctrl S` +* Toggle invisibles: `Shift Ctrl I` +* Suggest translation: `Ctrl J` + +Mac users can use ⌘ Cmd instead of Ctrl. diff --git a/vendor/loco-translate/src/Locale.php b/vendor/loco-translate/src/Locale.php new file mode 100644 index 0000000..ea587b6 --- /dev/null +++ b/vendor/loco-translate/src/Locale.php @@ -0,0 +1,473 @@ +setSubtags( loco_parse_wp_locale($tag) ); + } + catch( Exception $e ){ + // isValid should return false + } + do_action( 'loco_parse_locale', $locale, $tag ); + return $locale; + } + + + + /** + * Construct from subtags NOT from composite tag. See self::parse + * Note that this skips normalization and validation steps + * @param string + * @param string + * @param string + */ + public function __construct( $lang = '', $region = '', $variant = '' ){ + $this->tag = compact('lang','region','variant'); + } + + + + /** + * @internal + * Allow read access to subtags + */ + public function __get( $t ){ + return isset($this->tag[$t]) ? $this->tag[$t] : ''; + } + + + /** + * @internal + * Allow write access to subtags + */ + public function __set( $t, $s ){ + if( isset($this->tag[$t]) ){ + $this->tag[$t] = $s; + $this->setSubtags( $this->tag ); + } + } + + + /** + * Set subtags as produced from loco_parse_wp_locale + * @return Loco_Locale + */ + public function setSubtags( array $tag ){ + $this->valid = false; + $default = array( 'lang' => '', 'region' => '', 'variant' => '' ); + // disallow setting of unsupported tags + if( $bad = array_diff_key($tag, $default) ){ + throw new Loco_error_LocaleException('Unsupported subtags: '.implode(',',$bad) ); + } + $tag += $default; + // language tag is minimum requirement + if( ! $tag['lang'] ){ + throw new Loco_error_LocaleException('Locale must have a language'); + } + // no UN codes in Wordpress + if( is_numeric($tag['region']) ){ + throw new Loco_error_LocaleException('Numeric regions not supported'); + } + // single, scalar variant. Only using for Formal german currently. + if( is_array($tag['variant']) ){ + $tag['variant'] = implode('_',$tag['variant']); + } + // normalize case + $tag['lang'] = strtolower($tag['lang']); + $tag['region'] = strtoupper($tag['region']); + $tag['variant'] = strtolower($tag['variant']); + // set subtags and invalidate cache of language tag + $this->tag = $tag; + $this->_tag = null; + $this->icon = null; + $this->valid = true; + + return $this; + } + + + /** + * @return Loco_Locale + */ + public function normalize(){ + try { + $this->setSubtags( $this->tag ); + } + catch( Loco_error_LocaleException $e ){ + $this->_tag = ''; + $this->icon = null; + $this->name = 'Invalid locale'; + $this->_name = null; + } + return $this; + } + + + /** + * @return string + */ + public function __toString(){ + $str = $this->_tag; + if( is_null($str) ){ + $str = implode('_',array_filter($this->tag)); + $this->_tag = $str; + } + return $str; + } + + + /** + * Get stored name in current display language. + * Note that no dynamic translation of English name is performed, but can be altered with loco_parse_locale filter + * @return string | null + */ + public function getName(){ + if( $name = $this->name ){ + // use canonical native name only when current language matches + // deliberately not matching whole tag such that fr_CA would show native name of fr_FR + if( $_name = $this->getNativeName() ){ + $locale = self::parse( function_exists('get_user_locale') ? get_user_locale() : get_locale() ); + if( $this->lang === $locale->lang ){ + $name = $_name; + } + } + return $name; + } + } + + + /** + * Get canonical native name as defined by WordPress + * @return string | null + */ + public function getNativeName(){ + if( $name = $this->_name ){ + return $name; + } + } + + + /** + * @return string + */ + public function getIcon(){ + $icon = $this->icon; + if( is_null($icon) ){ + $tag = array(); + if( ! $this->tag['lang'] ){ + $tag[] = 'lang lang-zxx'; + } + foreach( $this->tag as $class => $code ){ + if( $code ){ + $tag[] = $class.' '.$class.'-'.$code; + } + } + $icon = strtolower( implode(' ',$tag) ); + $this->icon = $icon; + } + return $icon; + } + + + /** + * @return Loco_Locale + */ + public function setIcon( $css ){ + if( $css ){ + $this->icon = (string) $css; + } + else { + $this->icon = null; + } + return $this; + } + + + /** + * @return Loco_Locale + */ + public function setName( $english_name, $native_name = '' ){ + $this->name = apply_filters('loco_locale_name', $english_name, $native_name ); + $this->_name = (string) $native_name; + return $this; + } + + + /** + * Test whether locale is valid + */ + public function isValid(){ + if( is_null($this->valid) ){ + $this->normalize(); + } + return $this->valid; + } + + + /** + * Resolve this locale's "official" name from WordPress's translation api + * @return string English name currently set + */ + public function fetchName( Loco_api_WordPressTranslations $api ){ + $tag = (string) $this; + // pull from WordPress translations API if network allowed + if( $locale = $api->getLocale($tag) ){ + $this->setName( $locale->getName(), $locale->getNativeName() ); + } + return $this->getName(); + } + + + /** + * Resolve this locale's name from compiled Loco data + * @return string English name currently set + */ + public function buildName(){ + $names = array(); + // should at least have a language or not valid + if( $this->isValid() ){ + $code = $this->tag['lang']; + $db = Loco_data_CompiledData::get('languages'); + if( $name = $db[$code] ){ + // if variant is present add only that in brackets (no lookup required) + if( $code = $this->tag['variant'] ){ + $name .= ' ('.ucfirst($code).')'; + } + // else add region in brackets if present + else if( $code = $this->tag['region'] ){ + $db = Loco_data_CompiledData::get('regions'); + if( $extra = $db[$code] ){ + $name .= ' ('.$extra.')'; + } + else { + $name .= ' ('.$code.')'; + } + } + $this->setName( $name ); + } + } + else { + $this->setName( __('Invalid locale','loco-translate') ); + } + return $this->getName(); + } + + + /** + * Ensure locale has a label, even if it has to fall back to language code or error + * @return string + */ + public function ensureName( Loco_api_WordPressTranslations $api ){ + $name = $this->getName(); + if( ! $name ){ + $name = $this->fetchName($api); + // failing that, build own own name from components + if( ! $name ){ + $name = $this->buildName(); + // last resort, use tag as name + if( ! $name ){ + $name = (string) $this; + $this->setName( $name ); + } + } + } + return $name; + } + + + /** + * @return array + */ + public function jsonSerialize(){ + $a = $this->tag; + $a['label'] = $this->getName(); + // plural data expected by editor + $p = $this->getPluralData(); + $a['pluraleq'] = $p[0]; + $a['plurals'] = $p[1]; + $a['nplurals'] = count($p[1]); + + return $a; + } + + + /** + * Get plural data with translated forms + * @internal + * @return array [ (string) equation, (array) forms ] + */ + public function getPluralData(){ + $cache = $this->plurals; + if( ! $cache ){ + $lc = $this->lang; + $db = Loco_data_CompiledData::get('plurals'); + $id = $lc && isset($db[$lc]) ? $db[$lc] : 0; + $cache = $this->setPlurals( $db[''][$id] ); + } + return $cache; + } + + + /** + * @return int + */ + public function getPluralCount(){ + $raw = $this->getPluralData(); + return count( $raw[1] ); + } + + + + /** + * @return array + */ + private function setPlurals( array $raw ){ + $raw = apply_filters( 'loco_locale_plurals', $raw, $this ); + // handle languages with no plural forms, where n is always 0 + if( ! isset($raw[1][1]) ){ + // Translators: Plural category for languages that have no plurals + $raw[1] = array( _x('All forms','Plural category','loco-translate') ); + $raw[0] = '0'; + } + // else translate all implemented plural forms + // for meaning of categories, see http://cldr.unicode.org/index/cldr-spec/plural-rules + else { + $forms = array( + // Translators: Plural category for zero quantity + 'zero' => _x('Zero','Plural category','loco-translate'), + // Translators: Plural category for singular quantity + 'one' => _x('One','Plural category','loco-translate'), + // Translators: Plural category used in some multi-plural languages + 'two' => _x('Two','Plural category','loco-translate'), + // Translators: Plural category used in some multi-plural languages + 'few' => _x('Few','Plural category','loco-translate'), + // Translators: Plural category used in some multi-plural languages + 'many' => _x('Many','Plural category','loco-translate'), + // Translators: General plural category not covered by other forms + 'other' => _x('Other','Plural category','loco-translate'), + ); + foreach( $raw[1] as $k => $v ){ + if( isset($forms[$v]) ){ + $raw[1][$k] = $forms[$v]; + } + } + } + $this->plurals = $raw; + return $raw; + } + + + + /** + * Get PO style Plural-Forms header value comprising number of forms and integer equation for n + * @return string + */ + public function getPluralFormsHeader(){ + list( $equation, $forms ) = $this->getPluralData(); + return sprintf('nplurals=%u; plural=%s;', count($forms), $equation ); + } + + + + /** + * Apply PO style Plural-Forms header. + * @param string e.g. "nplurals=2; plural=n != 1;" + * @return Loco_Locale + */ + public function setPluralFormsHeader( $str ){ + if( ! preg_match('/^nplurals=(\\d);\s*plural=([ +\\-\\/*%!=<>|&?:()n0-9]+);?$/', $str, $match ) ){ + throw new InvalidArgumentException('Invalid Plural-Forms header, '.json_encode($str) ); + } + $cache = $this->getPluralData(); + $exprn = $match[2]; + // always alter if equation differs + if( $cache[0] !== $exprn ){ + $this->plurals[0] = $exprn; + // alter number of forms if changed + $nplurals = max( 1, (int) $match[1] ); + if( $nplurals !== count($cache[1]) ){ + // named forms must also change, but Plural-Forms cannot contain this information + // as a cheat, we'll assume first form always "one" and last always "other" + for( $i = 1; $i < $nplurals; $i++ ){ + $name = 1 === $i ? 'one' : sprintf('Plural %u',$i); + $forms[] = $name; + } + $forms[] = 'other'; + $this->setPlurals( array($exprn,$forms) ); + } + } + return $this; + } + + + + /** + * @return string + */ + public function exportJson(){ + return json_encode( $this->jsonSerialize() ); + } + +} + + + +// Depends on compiled library +if( ! function_exists('loco_parse_wp_locale') ){ + loco_include('lib/compiled/locales.php'); +} + diff --git a/vendor/loco-translate/src/admin/DebugController.php b/vendor/loco-translate/src/admin/DebugController.php new file mode 100644 index 0000000..ad5aca9 --- /dev/null +++ b/vendor/loco-translate/src/admin/DebugController.php @@ -0,0 +1,78 @@ +set('title','DEBUG'); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + // debug package listener + $themes = array(); + /* @var $bundle Loco_package_Bundle */ + foreach( Loco_package_Listener::singleton()->getThemes() as $bundle ){ + $themes[] = array ( + 'id' => $bundle->getId(), + 'name' => $bundle->getName(), + 'default' => $bundle->getDefaultProject()->getSlug(), + 'count' => count($bundle), + ); + } + $this->set('themes', $themes ); + + $plugins = array(); + /* @var $bundle Loco_package_Bundle */ + foreach( Loco_package_Listener::singleton()->getPlugins() as $bundle ){ + $plugins[] = array ( + 'id' => $bundle->getId(), + 'name' => $bundle->getName(), + 'default' => $bundle->getDefaultProject()->getSlug(), + 'count' => count($bundle), + ); + } + + + // $this->set( 'plugins', Loco_package_Plugin::get_plugins() ); + // $this->set('installed', wp_get_installed_translations('plugins') ); + // $this->set('active', get_option( 'active_plugins', array() ) ); + // $this->set('langs',get_available_languages()); + + /*$plugins = get_plugins(); + $plugin_info = get_site_transient( 'update_plugins' ); + foreach( $plugins as $plugin_file => $plugin_data ){ + if ( isset( $plugin_info->response[$plugin_file] ) ) { + $plugins[$plugin_file]['____'] = $plugin_info->response[$plugin_file]; + } + }*/ + + /*/ inspect session and test flash messages + $session = Loco_data_Session::get(); + $session->flash( 'success', microtime() ); + $this->set('session', $session->getArrayCopy() ); + Loco_data_Session::close();*/ + + // try some notices + Loco_error_AdminNotices::add( new Loco_error_Success('This is a sample success message') ); + Loco_error_AdminNotices::add( new Loco_error_Warning('This is a sample warning') ); + Loco_error_AdminNotices::add( new Loco_error_Exception('This is a sample error') ); + Loco_error_AdminNotices::add( new Loco_error_Debug('This is a sample debug message') ); + //*/ + + return $this->view('admin/debug'); + + } + +} + + diff --git a/vendor/loco-translate/src/admin/ErrorController.php b/vendor/loco-translate/src/admin/ErrorController.php new file mode 100644 index 0000000..22691b1 --- /dev/null +++ b/vendor/loco-translate/src/admin/ErrorController.php @@ -0,0 +1,42 @@ +set('error', Loco_error_Exception::convert($e) ); + return $this->render(); + } + + + public function render(){ + $e = $this->get('error'); + if( $e ){ + /* @var Loco_error_Exception $e */ + $file = Loco_mvc_FileParams::create( new Loco_fs_File( $e->getRealFile() ) ); + $file['line'] = $e->getRealLine(); + $this->set('file', $file ); + if( loco_debugging() ){ + $trace = array(); + foreach( $e->getRealTrace() as $raw ) { + $frame = new Loco_mvc_ViewParams($raw); + if( $frame->has('file') ){ + $frame['file'] = Loco_mvc_FileParams::create( new Loco_fs_File($frame['file']) )->relpath; + } + $trace[] = $frame; + } + $this->set('trace',$trace); + } + } + else { + $e = new Loco_error_Exception('Unknown error'); + $this->set('error', $e ); + } + return $this->view( $e->getTemplate() ); + } + +} + + diff --git a/vendor/loco-translate/src/admin/Navigation.php b/vendor/loco-translate/src/admin/Navigation.php new file mode 100644 index 0000000..d6682b3 --- /dev/null +++ b/vendor/loco-translate/src/admin/Navigation.php @@ -0,0 +1,72 @@ +add( $name, $href ); + }*/ + + + + /** + * Create a breadcrumb trail for a given view below a bundle + * @return Loco_admin_Navigation + */ + public static function createBreadcrumb( Loco_package_Bundle $bundle ){ + $nav = new Loco_admin_Navigation; + + // root link depends on bundle type + $type = strtolower( $bundle->getType() ); + if( 'core' !== $type ){ + $link = new Loco_mvc_ViewParams( array( + 'href' => Loco_mvc_AdminRouter::generate($type), + ) ); + if( 'theme' === $type ){ + $link['name'] = __('Themes','loco-translate'); + } + else { + $link['name'] = __('Plugins','loco-translate'); + } + $nav[] = $link; + } + + // Add actual bundle page, href may be unset to show as current page if needed + $nav->add ( + $bundle->getName(), + Loco_mvc_AdminRouter::generate( $type.'-view', array( 'bundle' => $bundle->getHandle() ) ) + ); + + // client code will add current page + return $nav; + } + + + + /** + * @return Loco_mvc_ViewParams + * + public function getSecondLast(){ + $i = count($this); + if( $i > 1 ){ + return $this[ $i-2 ]; + } + }*/ + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/RedirectController.php b/vendor/loco-translate/src/admin/RedirectController.php new file mode 100644 index 0000000..fdaa535 --- /dev/null +++ b/vendor/loco-translate/src/admin/RedirectController.php @@ -0,0 +1,35 @@ +getLocation(); + if( $location && wp_redirect($location) ){ + // @codeCoverageIgnoreStart + exit; + } + } + + + + /** + * @internal + */ + public function render(){ + return 'Failed to redirect'; + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/RootController.php b/vendor/loco-translate/src/admin/RootController.php new file mode 100644 index 0000000..b6dd201 --- /dev/null +++ b/vendor/loco-translate/src/admin/RootController.php @@ -0,0 +1,90 @@ + $this->viewSnippet('tab-home'), + ); + } + + + /** + * Render main entry home screen + */ + public function render(){ + + // translators: home screen title where %s is the version number + $this->set('title', sprintf( __('Loco Translate %s','loco-translate'), loco_plugin_version() ) ); + + // Show currently active theme on home page + $theme = Loco_package_Theme::create(null); + $this->set('theme', $this->bundleParam($theme) ); + + // Show plugins that have currently loaded translations + $bundles = array(); + foreach( Loco_package_Listener::singleton()->getPlugins() as $bundle ){ + try { + $bundles[] = $this->bundleParam($bundle); + } + catch( Exception $e ){ + // bundle should exist if we heard it. reduce to debug notice + Loco_error_AdminNotices::debug( $e->getMessage() ); + } + } + $this->set('plugins', $bundles ); + + + // Show recently "used' bundles + $bundles = array(); + $recent = Loco_data_RecentItems::get(); + // filter in lieu of plugin setting + $maxlen = apply_filters('loco_num_recent_bundles', 10 ); + foreach( $recent->getBundles(0,$maxlen) as $id ){ + try { + $bundle = Loco_package_Bundle::fromId($id); + $bundles[] = $this->bundleParam($bundle); + } + catch( Exception $e ){ + // possible that bundle ID changed since being saved in recent items list + } + } + $this->set('recent', $bundles ); + + + // current locale and related links + $locale = Loco_Locale::parse( get_locale() ); + $api = new Loco_api_WordPressTranslations; + $tag = (string) $locale; + $this->set( 'siteLocale', new Loco_mvc_ViewParams( array( + 'code' => $tag, + 'name' => ( $name = $locale->ensureName($api) ), + 'attr' => 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"', + 'link' => ''.esc_html($name).'', + //'opts' => admin_url('options-general.php').'#WPLANG', + ) ) ); + + // user's "admin" language may differ and is worth showing + if( function_exists('get_user_locale') ){ + $locale = Loco_Locale::parse( get_user_locale() ); + $alt = (string) $locale; + if( $tag !== $alt ){ + $this->set( 'adminLocale', new Loco_mvc_ViewParams( array( + 'name' => ( $name = $locale->ensureName($api) ), + 'link' => ''.esc_html($name).'', + ) ) ); + } + } + + $this->set('title', __('Welcome to Loco Translate','loco-translate') ); + + return $this->view('admin/root'); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/bundle/BaseController.php b/vendor/loco-translate/src/admin/bundle/BaseController.php new file mode 100644 index 0000000..e49d747 --- /dev/null +++ b/vendor/loco-translate/src/admin/bundle/BaseController.php @@ -0,0 +1,161 @@ +bundle ){ + $type = $this->get('type'); + $handle = $this->get('bundle'); + $this->bundle = Loco_package_Bundle::createType( $type, $handle ); + } + return $this->bundle; + } + + + /** + * Commit bundle config to database + * @return Loco_admin_bundle_BaseController + */ + protected function saveBundle(){ + $custom = new Loco_config_CustomSaved; + if( $custom->setBundle($this->bundle)->persist() ){ + Loco_error_AdminNotices::success( __('Configuration saved','loco-translate') ); + } + // invalidate bundle in memory so next fetch is re-configured from DB + $this->bundle = null; + return $this; + } + + + /** + * Remove bundle config from database + * @return Loco_admin_bundle_BaseController + */ + protected function resetBundle(){ + $option = $this->bundle->getCustomConfig(); + if( $option && $option->remove() ){ + Loco_error_AdminNotices::success( __('Configuration reset','loco-translate') ); + // invalidate bundle in memory so next fetch falls back to auto-config + $this->bundle = null; + } + return $this; + } + + + /** + * @return Loco_package_Project + */ + public function getProject(){ + if( ! $this->project ){ + $bundle = $this->getBundle(); + $domain = $this->get('domain'); + if( ! $domain ){ + throw new Loco_error_Exception( sprintf('Translation set not known in %s', $bundle ) ); + } + $this->project = $bundle->getProjectById($domain); + if( ! $this->project ){ + throw new Loco_error_Exception( sprintf('Unknown translation set: %s not in %s', json_encode($domain), $bundle ) ); + } + } + + return $this->project; + } + + + /** + * @return Loco_admin_Navigation + */ + protected function prepareNavigation(){ + $bundle = $this->getBundle(); + + // navigate up to bundle listing page + $breadcrumb = Loco_admin_Navigation::createBreadcrumb( $bundle ); + $this->set( 'breadcrumb', $breadcrumb ); + + // navigate between bundle view siblings + $tabs = new Loco_admin_Navigation; + $this->set( 'tabs', $tabs ); + $actions = array ( + 'view' => __('Overview','loco-translate'), + 'setup' => __('Setup','loco-translate'), + 'conf' => __('Advanced','loco-translate'), + ); + if( loco_debugging() ){ + $actions['debug'] = __('Debug','loco-translate'); + } + $suffix = $this->get('action'); + $prefix = strtolower( $this->get('type') ); + $getarg = array_intersect_key( $_GET, array('bundle'=>'') ); + foreach( $actions as $action => $name ){ + $href = Loco_mvc_AdminRouter::generate( $prefix.'-'.$action, $getarg ); + $tabs->add( $name, $href, $action === $suffix ); + } + + return $breadcrumb; + } + + + + /** + * Prepare file system connect + * @param string "create", "update", "delete" + * @param string path relative to wp-content + * @return Loco_mvc_HiddenFields + */ + protected function prepareFsConnect( $type, $relpath ){ + + $fields = new Loco_mvc_HiddenFields( array( + 'auth' => $type, + 'path' => $relpath, + 'loco-nonce' => wp_create_nonce('fsConnect'), + '_fs_nonce' => wp_create_nonce('filesystem-credentials'), // <- WP 4.7.5 added security fix + ) ) ; + $this->set('fsFields', $fields ); + + // may have fs credentials saved in session + try { + if( Loco_data_Settings::get()->fs_persist ){ + $session = Loco_data_Session::get(); + if( isset($session['loco-fs']) ){ + $fields['connection_type'] = $session['loco-fs']['connection_type']; + } + } + } + catch( Exception $e ){ + Loco_error_AdminNotices::debug( $e->getMessage() ); + } + + // Run pre-checks that may determine file should not be written + if( $relpath ){ + $file = new Loco_fs_File( $relpath ); + $file->normalize( loco_constant('WP_CONTENT_DIR') ); + // total file system block makes connection type irrelevant + try { + $api = new Loco_api_WordPressFileSystem; + $api->preAuthorize($file); + } + catch( Loco_error_WriteException $e ){ + $this->set('fsLocked', $e->getMessage() ); + } + } + + return $fields; + } + +} diff --git a/vendor/loco-translate/src/admin/bundle/ConfController.php b/vendor/loco-translate/src/admin/bundle/ConfController.php new file mode 100644 index 0000000..d466a1e --- /dev/null +++ b/vendor/loco-translate/src/admin/bundle/ConfController.php @@ -0,0 +1,145 @@ +enqueueStyle('config'); + $this->enqueueScript('config'); + $bundle = $this->getBundle(); + // translators: where %s is a plugin or theme + $this->set( 'title', sprintf( __('Configure %s','loco-translate'),$bundle->getName() ) ); + + $post = Loco_mvc_PostParams::get(); + // always set a nonce for current bundle + $nonce = $this->setNonce( $this->get('_route').'-'.$this->get('bundle') ); + $this->set('nonce', $nonce ); + try { + // Save configuration if posted + if( $post->has('conf') ){ + if( ! $post->name ){ + $post->name = $bundle->getName(); + } + $this->checkNonce( $nonce->action ); + $model = new Loco_config_FormModel; + $model->loadForm( $post ); + // configure bundle from model in full + $bundle->clear(); + $reader = new Loco_config_BundleReader( $bundle ); + $reader->loadModel( $model ); + $this->saveBundle(); + } + // Delete configuration if posted + else if( $post->has('unconf') ){ + $this->resetBundle(); + } + } + catch( Exception $e ){ + Loco_error_AdminNotices::warn( $e->getMessage() ); + } + + } + + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Advanced tab','loco-translate') => $this->viewSnippet('tab-bundle-conf'), + ); + } + + + /** + * {@inheritdoc} + */ + public function render() { + + $parent = null; + $bundle = $this->getBundle(); + $default = $bundle->getDefaultProject(); + $base = $bundle->getDirectoryPath(); + + + // parent themes are inherited into bundle, we don't want them in the child theme config + if( $bundle->isTheme() && ( $parent = $bundle->getParent() ) ){ + $this->set( 'parent', new Loco_mvc_ViewParams( array( + 'name' => $parent->getName(), + 'href' => Loco_mvc_AdminRouter::generate('theme-conf', array( 'bundle' => $parent->getSlug() ) + $_GET ), + ) ) ); + } + + // render postdata straight back to form if sent + $data = Loco_mvc_PostParams::get(); + // else build initial data from current bundle state + if( ! $data->has('conf') ){ + // create single default set for totally unconfigured bundles + if( 0 === count($bundle) ){ + $bundle->createDefault(''); + } + $writer = new Loco_config_BundleWriter($bundle); + $data = $writer->toForm(); + // removed parent bundle from config form, as they are inherited + /* @var Loco_package_Project $project */ + foreach( $bundle as $i => $project ){ + if( $parent && $parent->hasProject($project) ){ + // warn if child theme uses parent theme's text domain (but allowing to render so we don't get an empty form. + if( $project === $default ){ + Loco_error_AdminNotices::warn( __("Child theme declares the same Text Domain as the parent theme",'loco-translate') ); + } + // else safe to remove parent theme configuration as it should be held in its own bundle + else { + $data['conf'][$i]['removed'] = true; + } + } + } + } + + // build config blocks for form + $i = 0; + $conf = array(); + foreach( $data['conf'] as $raw ){ + if( empty($raw['removed']) ){ + $slug = $raw['slug']; + $domain = $raw['domain'] or $domain = 'untitled'; + $raw['prefix'] = sprintf('conf[%u]', $i++ ); + $raw['short'] = ! $slug || ( $slug === $domain ) ? $domain : $domain.'→'.$slug; + $conf[] = new Loco_mvc_ViewParams( $raw ); + } + } + + // bundle level configs + $name = $bundle->getName(); + $excl = $data['exclude']; + + + // access to type of configuration that's currently saved + $this->set('saved', $bundle->isConfigured() ); + + // link to author if there are config problems + $info = $bundle->getHeaderInfo(); + $this->set('author', $info->getAuthorLink() ); + + // link for downloading current configuration XML file + $args = array ( + 'path' => 'loco.xml', + 'action' => 'loco_download', + 'bundle' => $bundle->getHandle(), + 'type' => $bundle->getType() + ); + $this->set( 'xmlUrl', Loco_mvc_AjaxRouter::generate( 'DownloadConf', $args ) ); + $this->set( 'manUrl', apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/bundle-config') ); + + $this->prepareNavigation()->add( __('Advanced configuration','loco-translate') ); + return $this->view('admin/bundle/conf', compact('conf','base','name','excl') ); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/bundle/DebugController.php b/vendor/loco-translate/src/admin/bundle/DebugController.php new file mode 100644 index 0000000..ecf0bb7 --- /dev/null +++ b/vendor/loco-translate/src/admin/bundle/DebugController.php @@ -0,0 +1,52 @@ +getBundle(); + $this->set('title', 'Debug: '.$bundle ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + $this->prepareNavigation()->add( __('Bundle diagnostics','loco-translate') ); + + $bundle = $this->getBundle(); + $debugger = new Loco_package_Debugger($bundle); + $this->set('notices', $notices = new Loco_mvc_ViewParams ); + /* @var $notice Loco_error_Exception */ + foreach( $debugger as $notice ){ + $notices[] = new Loco_mvc_ViewParams( array( + 'style' => 'notice inline notice-'.$notice->getType(), + 'title' => $notice->getTitle(), + 'body' => $notice->getMessage(), + ) ); + } + + $meta = $bundle->getHeaderInfo(); + $this->set('meta', new Loco_mvc_ViewParams( array( + 'vendor' => $meta->getVendorHost(), + 'author' => $meta->getAuthorCredit(), + ) ) ); + + if( count($bundle) ){ + $writer = new Loco_config_BundleWriter( $bundle ); + $this->set( 'xml', $writer->toXml() ); + } + + return $this->view('admin/bundle/debug'); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/bundle/LocaleController.php b/vendor/loco-translate/src/admin/bundle/LocaleController.php new file mode 100644 index 0000000..14b10c5 --- /dev/null +++ b/vendor/loco-translate/src/admin/bundle/LocaleController.php @@ -0,0 +1,162 @@ +get('locale'); + $locale = Loco_Locale::parse($tag); + if( $locale->isValid() ){ + $api = new Loco_api_WordPressTranslations; + $this->set('title', $locale->ensureName($api) ); + $this->locale = $locale; + $this->enqueueStyle('locale')->enqueueStyle('fileinfo'); + } + } + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-locale-view'), + ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + // locale already parsed during init (for page title) + $locale = $this->locale; + if( ! $locale || ! $locale->isValid() ){ + throw new Loco_error_Exception('Invalid locale argument'); + } + + // language may not be "installed" but we still want to inspect available files + $api = new Loco_api_WordPressTranslations; + $installed = $api->isInstalled($locale); + + $tag = (string) $locale; + $package = new Loco_package_Locale( $locale ); + + // Get PO files for this locale + $files = $package->findLocaleFiles(); + $translations = array(); + $modified = 0; + $npofiles = 0; + $nfiles = 0; + + // source locale means we want to see POT instead of translations + if( 'en_US' === $tag ){ + $files = $package->findTemplateFiles()->augment($files); + } + + /* @var Loco_fs_File */ + foreach( $files as $file ){ + $nfiles++; + if( 'pot' !== $file->extension() ){ + $npofiles++; + } + $modified = max( $modified, $file->modified() ); + $project = $package->getProject($file); + // do similarly to Loco_admin_bundle_ViewController::createFileParams + $meta = Loco_gettext_Metadata::load($file); + $dir = new Loco_fs_LocaleDirectory( $file->dirname() ); + // arguments for deep link into project + $slug = $project->getSlug(); + $domain = $project->getDomain()->getName(); + $bundle = $project->getBundle(); + $type = strtolower( $bundle->getType() ); + $args = array( + // 'locale' => $tag, + 'bundle' => $bundle->getHandle(), + 'domain' => $project->getId(), + 'path' => $meta->getPath(false), + ); + // append data required for PO table row, except use bundle data instead of locale data + $translations[$type][] = new Loco_mvc_ViewParams( array ( + // bundle info + 'title' => $project->getName(), + 'domain' => $domain, + 'short' => ! $slug || $project->isDomainDefault() ? $domain : $domain.'→'.$slug, + // file info + 'meta' => $meta, + 'name' => $file->basename(), + 'time' => $file->modified(), + 'type' => strtoupper( $file->extension() ), + 'todo' => $meta->countIncomplete(), + 'total' => $meta->getTotal(), + // author / system / custom / other + 'store' => $dir->getTypeLabel( $dir->getTypeId() ), + // links + 'view' => Loco_mvc_AdminRouter::generate( $type.'-file-view', $args ), + 'info' => Loco_mvc_AdminRouter::generate( $type.'-file-info', $args ), + 'edit' => Loco_mvc_AdminRouter::generate( $type.'-file-edit', $args ), + 'move' => Loco_mvc_AdminRouter::generate( $type.'-file-move', $args ), + 'delete' => Loco_mvc_AdminRouter::generate( $type.'-file-delete', $args ), + 'copy' => Loco_mvc_AdminRouter::generate( $type.'-msginit', $args ), + ) ); + } + + $title = __( 'Installed languages', 'loco-translate' ); + $breadcrumb = new Loco_admin_Navigation; + $breadcrumb->add( $title, Loco_mvc_AdminRouter::generate('lang') ); + //$breadcrumb->add( $locale->getName() ); + $breadcrumb->add( $tag ); + + // It's unlikely that an "installed" language would have no files, but could happen if only MO on disk + if( 0 === $nfiles ){ + return $this->view('admin/errors/no-locale', compact('breadcrumb','locale') ); + } + + // files may be available for language even if not installed (i.e. no core files on disk) + if( ! $installed || ! isset($translations['core']) && 'en_US' !== $tag ){ + Loco_error_AdminNotices::warn( __('No core translation files are installed for this language','loco-translate') ) + ->addLink('https://codex.wordpress.org/Installing_WordPress_in_Your_Language', __('Documentation','loco-translate') ); + } + + // Translated type labels and "See all " links + $types = array( + 'core' => new Loco_mvc_ViewParams( array( + 'name' => __('WordPress Core','loco-translate'), + 'text' => __('See all core translations','loco-translate'), + 'href' => Loco_mvc_AdminRouter::generate('core') + ) ), + 'theme' => new Loco_mvc_ViewParams( array( + 'name' => __('Themes','loco-translate'), + 'text' => __('See all themes','loco-translate'), + 'href' => Loco_mvc_AdminRouter::generate('theme') + ) ), + 'plugin' => new Loco_mvc_ViewParams( array( + 'name' => __('Plugins','loco-translate'), + 'text' => __('See all plugins','loco-translate'), + 'href' => Loco_mvc_AdminRouter::generate('plugin') + ) ), + ); + + $this->set( 'locale', new Loco_mvc_ViewParams( array( + 'code' => $tag, + 'name' => $locale->getName(), + 'attr' => 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"', + ) ) ); + + return $this->view( 'admin/bundle/locale', compact('breadcrumb','translations','types','npofiles','modified') ); + } + + +} diff --git a/vendor/loco-translate/src/admin/bundle/SetupController.php b/vendor/loco-translate/src/admin/bundle/SetupController.php new file mode 100644 index 0000000..8c4b626 --- /dev/null +++ b/vendor/loco-translate/src/admin/bundle/SetupController.php @@ -0,0 +1,193 @@ +getBundle(); + + // translators: where %s is a plugin or theme + $this->set( 'title', sprintf( __('Set up %s','loco-translate'),$bundle->getName() ) ); + } + + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Setup tab','loco-translate') => $this->viewSnippet('tab-bundle-setup'), + ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + $this->prepareNavigation()->add( __('Bundle setup','loco-translate') ); + $bundle = $this->getBundle(); + $action = 'setup:'.$bundle->getId(); + + // execute auto-configure if posted + $post = Loco_mvc_PostParams::get(); + if( $post->has('auto-setup') && $this->checkNonce( 'auto-'.$action) ){ + if( 0 === count($bundle) ){ + $bundle->createDefault(); + } + foreach( $bundle as $project ){ + if( ! $project->getPot() && ( $file = $project->guessPot() ) ){ + $project->setPot( $file ); + } + } + // forcefully add every additional project into bundle + foreach( $bundle->invert() as $project ){ + if( ! $project->getPot() && ( $file = $project->guessPot() ) ){ + $project->setPot( $file ); + } + $bundle[] = $project; + } + $this->saveBundle(); + $bundle = $this->getBundle(); + $this->set('auto', null ); + } + // execute XML-based config if posted + else if( $post->has('xml-setup') && $this->checkNonce( 'xml-'.$action) ){ + $bundle->clear(); + $model = new Loco_config_XMLModel; + $model->loadXml( trim( $post['xml-content'] ) ); + $reader = new Loco_config_BundleReader($bundle); + $reader->loadModel( $model ); + $this->saveBundle(); + $bundle = $this->getBundle(); + $this->set('xml', null ); + } + // execute JSON-based config if posted + else if( $post->has('json-setup') && $this->checkNonce( 'json-'.$action) ){ + $bundle->clear(); + $model = new Loco_config_ArrayModel; + $model->loadJson( trim( $post['json-content'] ) ); + $reader = new Loco_config_BundleReader($bundle); + $reader->loadModel( $model ); + $this->saveBundle(); + $bundle = $this->getBundle(); + $this->set('json', null ); + } + // execute reset if posted + else if( $post->has('reset-setup') && $this->checkNonce( 'reset-'.$action) ){ + $this->resetBundle(); + $bundle = $this->getBundle(); + } + + // bundle author links + $info = $bundle->getHeaderInfo(); + $this->set( 'credit', $info->getAuthorCredit() ); + + // render according to current configuration method (save type) + $configured = $this->get('force') or $configured = $bundle->isConfigured(); + + $notices = new ArrayIterator; + $this->set('notices', $notices ); + + // collect configuration warnings + foreach( $bundle as $project ){ + $potfile = $project->getPot(); + if( ! $potfile ){ + $notices[] = sprintf('No translation template for the "%s" text domain', $project->getSlug() ); + } + } + // if extra files found consider incomplete + if( $bundle->isTheme() || ( $bundle->isPlugin() && ! $bundle->isSingleFile() ) ){ + $unknown = Loco_package_Inverter::export($bundle); + $n = 0; + foreach( $unknown as $ext => $files ){ + $n += count($files); + } + if( $n ){ + $notices[] = sprintf( _n("One file can't be matched to a known set of strings","%s files can't be matched to a known set of strings",$n,'loco-translate'), number_format($n) ); + } + } + + // display setup options if at least one option specified + $doconf = false; + + // enable form to invoke auto-configuration + if( $this->get('auto') ){ + $fields = new Loco_mvc_HiddenFields(); + $fields->setNonce( 'auto-'.$action ); + $this->set('autoFields', $fields ); + $doconf = true; + } + + // enable form to paste XML config + if( $this->get('xml') ){ + $fields = new Loco_mvc_HiddenFields(); + $fields->setNonce( 'xml-'.$action ); + $this->set('xmlFields', $fields ); + $doconf = true; + } + + // enable form to paste JSON config (via remote lookup) + if( $this->get('json') ){ + $fields = new Loco_mvc_HiddenFields( array( + 'json-content' => '', + 'version' => $info->Version, + ) ); + $fields->setNonce( 'json-'.$action ); + $this->set('jsonFields', $fields ); + + // other information for looking up bundle via api + $this->set('vendorSlug', $bundle->getSlug() ); + + // remote config is done via JavaScript + $this->enqueueScript('setup'); + $apiBase = apply_filters( 'loco_api_url', 'https://localise.biz/api' ); + $this->set('js', new Loco_mvc_ViewParams( array( + 'apiUrl' => $apiBase.'/wp/'.strtolower( $bundle->getType() ), + ) ) ); + $doconf = true; + } + + // display configurator if configurating + if( $doconf ){ + return $this->view( 'admin/bundle/setup/conf' ); + } + // else set configurator links back to self with required option + // ... + + + if( ! $configured || ! count($bundle) ){ + return $this->view( 'admin/bundle/setup/none' ); + } + + if( 'db' === $configured ){ + // form for resetting config + $fields = new Loco_mvc_HiddenFields(); + $fields->setNonce( 'reset-'.$action ); + $this->set( 'reset', $fields ); + return $this->view('admin/bundle/setup/saved'); + } + + if( 'internal' === $configured ){ + return $this->view('admin/bundle/setup/core'); + } + + if( 'file' === $configured ){ + return $this->view('admin/bundle/setup/author'); + } + + if( count($notices) ){ + return $this->view('admin/bundle/setup/partial'); + } + + return $this->view('admin/bundle/setup/meta'); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/bundle/ViewController.php b/vendor/loco-translate/src/admin/bundle/ViewController.php new file mode 100644 index 0000000..6c85c7c --- /dev/null +++ b/vendor/loco-translate/src/admin/bundle/ViewController.php @@ -0,0 +1,324 @@ +getBundle(); + $this->set('title', $bundle->getName() ); + $this->enqueueStyle('bundle'); + } + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-bundle-view'), + ); + } + + + /** + * Generate a link for a specific file resource within a project + * @return string + */ + private function getResourceLink( $page, Loco_package_Project $project, Loco_gettext_Metadata $meta, array $args = array() ){ + $args['path'] = $meta->getPath(false); + return $this->getProjectLink( $page, $project, $args ); + } + + + /** + * Generate a link for a project, but without being for a specific file + * @return string + */ + private function getProjectLink( $page, Loco_package_Project $project, array $args = array() ){ + $args['bundle'] = $this->get('bundle'); + $args['domain'] = $project->getId(); + $route = strtolower( $this->get('type') ).'-'.$page; + return Loco_mvc_AdminRouter::generate( $route, $args ); + } + + + /** + * Initialize view parameters for a project + * @param Loco_package_Project + * @return Loco_mvc_ViewParams + */ + private function createProjectParams( Loco_package_Project $project ){ + $name = $project->getName(); + $domain = $project->getDomain()->getName(); + $slug = $project->getSlug(); + $p = new Loco_mvc_ViewParams( array ( + 'id' => $project->getId(), + 'name' => $name, + 'slug' => $slug, + 'domain' => $domain, + 'short' => ! $slug || $project->isDomainDefault() ? $domain : $domain.'→'.$slug, + ) ); + + // POT template file + $file = $project->getPot(); + if( $file && $file->exists() ){ + $meta = Loco_gettext_Metadata::load($file); + $p['pot'] = new Loco_mvc_ViewParams( array( + // POT info + 'name' => $file->basename(), + 'time' => $file->modified(), + // POT links + 'info' => $this->getResourceLink('file-info', $project, $meta ), + 'edit' => $this->getResourceLink('file-edit', $project, $meta ), + ) ); + } + + // PO/MO files + $po = $project->findLocaleFiles('po'); + $mo = $project->findLocaleFiles('mo'); + $p['po'] = $this->createProjectPairs( $project, $po, $mo ); + + // also pull invalid files so everything is available to the UI + $mo = $project->findNotLocaleFiles('mo'); + $po = $project->findNotLocaleFiles('po')->augment( $project->findNotLocaleFiles('pot') ); + $p['_po'] = $this->createProjectPairs( $project, $po, $mo ); + + // always offer msginit even if we find out later we can't extract any strings + $p['nav'][] = new Loco_mvc_ViewParams( array( + 'href' => $this->getProjectLink('msginit', $project ), + 'name' => __('New language','loco-translate'), + 'icon' => 'add', + ) ); + + $pot = $project->getPot(); + + // prevent editing of POT when config prohibits + if( $project->isPotLocked() || 1 < Loco_data_Settings::get()->pot_protect ) { + if( $pot && $pot->exists() ){ + $meta = Loco_gettext_Metadata::load($pot); + $p['nav'][] = new Loco_mvc_ViewParams( array( + 'href' => $this->getResourceLink('file-view', $project, $meta ), + 'name' => __('View template','loco-translate'), + 'icon' => 'file', + ) ); + } + } + // offer template editing if permitted + else if( $pot && $pot->exists() ){ + $p['pot'] = $pot; + $meta = Loco_gettext_Metadata::load($pot); + $p['nav'][] = new Loco_mvc_ViewParams( array( + 'href' => $this->getResourceLink('file-edit', $project, $meta ), + 'name' => __('Edit template','loco-translate'), + 'icon' => 'pencil', + ) ); + } + // else offer creation of new Template + else { + $p['nav'][] = new Loco_mvc_ViewParams( array( + 'href' => $this->getProjectLink('xgettext', $project ), + 'name' => __('Create template','loco-translate'), + 'icon' => 'add', + ) ); + } + + return $p; + } + + + /** + * Collect PO/MO pairings, ignoring any PO that is in use as a template + */ + private function createPairs( Loco_fs_FileList $po, Loco_fs_FileList $mo, Loco_fs_File $pot = null ){ + $pairs = array(); + /* @var $pofile Loco_fs_LocaleFile */ + foreach( $po as $pofile ){ + if( $pot && $pofile->equal($pot) ){ + continue; + } + $pair = array( $pofile, null ); + $mofile = $pofile->cloneExtension('mo'); + if( $mofile->exists() ){ + $pair[1] = $mofile; + } + $pairs[] = $pair; + } + /* @var $mofile Loco_fs_LocaleFile */ + foreach( $mo as $mofile ){ + $pofile = $mofile->cloneExtension('po'); + if( $pot && $pofile->equal($pot) ){ + continue; + } + if( ! $pofile->exists() ){ + $pairs[] = array( null, $mofile ); + } + } + return $pairs; + } + + + /** + * Initialize view parameters for each row representing a localized resource pair + * @return array collection of entries corresponding to available PO/MO pair. + */ + private function createProjectPairs( Loco_package_Project $project, Loco_fs_LocaleFileList $po, Loco_fs_LocaleFileList $mo ){ + // populate official locale names for all found, or default to our own + if( $locales = $po->getLocales() + $mo->getLocales() ){ + $api = new Loco_api_WordPressTranslations; + /* @var $locale Loco_Locale */ + foreach( $locales as $tag => $locale ){ + $locale->ensureName($api); + } + } + // collate as unique [PO,MO] pairs ensuring canonical template excluded + $pairs = $this->createPairs( $po, $mo, $project->getPot() ); + $rows = array(); + foreach( $pairs as $pair ){ + // favour PO file if it exists + list( $pofile, $mofile ) = $pair; + $file = $pofile or $file = $mofile; + // establish locale, or assume invalid + $locale = null; + /* @var Loco_fs_LocaleFile $file */ + if( 'pot' !== $file->extension() ){ + $tag = $file->getSuffix(); + if( isset($locales[$tag]) ){ + $locale = $locales[$tag]; + } + } + $rows[] = $this->createFileParams( $project, $file, $locale ); + } + + return $rows; + } + + + /** + * @param Loco_package_Project + * @param Loco_fs_File + * @param Loco_Locale + * @return Loco_mvc_ViewParams + */ + private function createFileParams( Loco_package_Project $project, Loco_fs_File $file, Loco_Locale $locale = null ){ + // Pull Gettext meta data from cache if possible + $meta = Loco_gettext_Metadata::load($file); + $dir = new Loco_fs_LocaleDirectory( $file->dirname() ); + // routing arguments + $args = array ( + 'path' => $meta->getPath(false), + ); + // Return data required for PO table row + return new Loco_mvc_ViewParams( array ( + // locale info + 'lcode' => $locale ? (string) $locale : '', + 'lname' => $locale ? $locale->getName() : '', + 'lattr' => $locale ? 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"' : '', + // file info + 'meta' => $meta, + 'name' => $file->basename(), + 'time' => $file->modified(), + 'type' => strtoupper( $file->extension() ), + 'todo' => $meta->countIncomplete(), + 'total' => $meta->getTotal(), + // author / system / custom / other + 'store' => $dir->getTypeLabel( $dir->getTypeId() ), + // links + 'view' => $this->getProjectLink('file-view', $project, $args ), + 'info' => $this->getProjectLink('file-info', $project, $args ), + 'edit' => $this->getProjectLink('file-edit', $project, $args ), + 'move' => $this->getProjectLink('file-move', $project, $args ), + 'delete' => $this->getProjectLink('file-delete', $project, $args ), + 'copy' => $this->getProjectLink('msginit', $project, $args ), + ) ); + } + + + /** + * Prepare view parameters for all projects in a bundle + * @param Loco_package_Bundle + * @return array + */ + private function createBundleListing( Loco_package_Bundle $bundle ){ + $projects = array(); + /* @var $project Loco_package_Project */ + foreach( $bundle as $project ){ + $projects[] = $this->createProjectParams($project); + } + return $projects; + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + $this->prepareNavigation(); + + $bundle = $this->getBundle(); + $this->set('name', $bundle->getName() ); + + // bundle may not be fully configured + $configured = $bundle->isConfigured(); + + // Hello Dolly is an exception. don't show unless configured deliberately + if( 'Hello Dolly' === $bundle->getName() && 'hello.php' === basename($bundle->getHandle()) ){ + if( ! $configured || 'meta' === $configured ){ + $this->set( 'redirect', Loco_mvc_AdminRouter::generate('core-view') ); + return $this->view('admin/bundle/alias'); + } + } + + // Collect all configured projects + $projects = $this->createBundleListing( $bundle ); + $unknown = array(); + + // sniff additional unknown files if bundle is a theme or directory-based plugin that's been auto-detected + if( 'file' === $configured || 'internal' === $configured ){ + // presumed complete + } + else if( $bundle->isTheme() || ( $bundle->isPlugin() && ! $bundle->isSingleFile() ) ){ + // TODO This needs abstracting into the Loco_package_Inverter class + $prefixes = array(); + $po = new Loco_fs_LocaleFileList; + $mo = new Loco_fs_LocaleFileList; + foreach( Loco_package_Inverter::export($bundle) as $ext => $files ){ + $list = 'mo' === $ext ? $mo : $po; + foreach( $files as $file ){ + $file = new Loco_fs_LocaleFile($file); + $list->addLocalized( $file ); + // Only look in system locations if locale is valid and domain/prefix available + $locale = $file->getLocale(); + if( $locale->isValid() && ( $domain = $file->getPrefix() ) ){ + $prefixes[$domain] = true; + } + } + } + // pick up given files in system locations only + foreach( $prefixes as $domain => $_bool ){ + $dummy = new Loco_package_Project( $bundle, new Loco_package_TextDomain($domain), '' ); + $bundle->addProject( $dummy ); // <- required to configure locations + $dummy->excludeTargetPath( $bundle->getDirectoryPath() ); + $po->augment( $dummy->findLocaleFiles('po') ); + $mo->augment( $dummy->findLocaleFiles('mo') ); + } + // a fake project is required to disable functions that require a configured project + $dummy = new Loco_package_Project( $bundle, new Loco_package_TextDomain(''), '' ); + $unknown = $this->createProjectPairs( $dummy, $po, $mo ); + } + + $this->set('projects', $projects ); + $this->set('unknown', $unknown ); + + return $this->view( 'admin/bundle/view' ); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/config/ApisController.php b/vendor/loco-translate/src/admin/config/ApisController.php new file mode 100644 index 0000000..99cc0af --- /dev/null +++ b/vendor/loco-translate/src/admin/config/ApisController.php @@ -0,0 +1,66 @@ +set( 'title', __('API keys','loco-translate') ); + + // collect support API keys + $apis = array(); + foreach( Loco_api_Providers::builtin() as $api ){ + $apis[ $api['id'] ] = new Loco_mvc_ViewParams($api); + } + $this->set('apis',$apis); + + // handle save action + $nonce = $this->setNonce('save-apis'); + try { + if( $this->checkNonce($nonce->action) ){ + $post = Loco_mvc_PostParams::get(); + if( $post->has('api') ){ + // Save only options in post. Avoids overwrite of missing site options + $data = array(); + $filter = array(); + foreach( $apis as $id => $api ){ + $fields = $post->api[$id]; + if( is_array($fields) ){ + foreach( $fields as $prop => $value ){ + $apis[$id][$prop] = $value; + $prop = $id.'_api_'.$prop; + $data[$prop] = $value; + $filter[] = $prop; + } + } + } + if( $filter ){ + Loco_data_Settings::get()->populate($data,$filter)->persistIfDirty(); + Loco_error_AdminNotices::success( __('Settings saved','loco-translate') ); + } + } + } + } + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::add($e); + } + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + $title = __('Plugin settings','loco-translate'); + $breadcrumb = new Loco_admin_Navigation; + $breadcrumb->add( $title ); + + return $this->view('admin/config/apis', compact('breadcrumb') ); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/config/BaseController.php b/vendor/loco-translate/src/admin/config/BaseController.php new file mode 100644 index 0000000..3165b34 --- /dev/null +++ b/vendor/loco-translate/src/admin/config/BaseController.php @@ -0,0 +1,47 @@ +set( 'tabs', $tabs ); + $actions = array ( + '' => __('Site options','loco-translate'), + 'user' => __('User options','loco-translate'), + 'apis' => __('API keys','loco-translate'), + 'version' => __('Version','loco-translate'), + ); + if( loco_debugging() ){ + $actions['debug'] = __('Debug','loco-translate'); + } + $suffix = (string) $this->get('action'); + foreach( $actions as $action => $name ){ + $href = Loco_mvc_AdminRouter::generate( 'config-'.$action, $_GET ); + $tabs->add( $name, $href, $action === $suffix ); + } + } + } + + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-config'), + __('API keys','loco-translate') => $this->viewSnippet('tab-config-apis'), + ); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/config/DebugController.php b/vendor/loco-translate/src/admin/config/DebugController.php new file mode 100644 index 0000000..adc30d6 --- /dev/null +++ b/vendor/loco-translate/src/admin/config/DebugController.php @@ -0,0 +1,168 @@ +set( 'title', __('Debug','loco-translate') ); + } + + + /** + * @param string + * @return int + */ + private function memory_size( $raw ){ + $bytes = wp_convert_hr_to_bytes($raw); + return Loco_mvc_FileParams::renderBytes($bytes); + } + + + /** + * @param string + * @return string + */ + private function rel_path( $path ){ + if( is_string($path) && $path && '/' === $path[0] ){ + $file = new Loco_fs_File( $path ); + $path = $file->getRelativePath(ABSPATH); + } + else if( ! $path ){ + $path = '(none)'; + } + return $path; + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + $title = __('System diagnostics','loco-translate'); + $breadcrumb = new Loco_admin_Navigation; + $breadcrumb->add( $title ); + + // extensions that are normally enabled in PHP by default + loco_check_extension('json'); + loco_check_extension('ctype'); + + // product versions: + $versions = new Loco_mvc_ViewParams( array ( + 'Loco Translate' => loco_plugin_version(), + 'WordPress' => $GLOBALS['wp_version'], + 'PHP' => phpversion().' ('.PHP_SAPI.')', + 'Server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ( function_exists('apache_get_version') ? apache_get_version() : '' ), + ) ); + // we want to know about modules in case there are security mods installed known to break functionality + if( function_exists('apache_get_modules') && ( $mods = preg_grep('/^mod_/',apache_get_modules() ) ) ){ + $versions['Server'] .= ' + '.implode(', ',$mods); + } + + // byte code cache (currently only checking for Zend OPcache) + if( function_exists('opcache_get_configuration') && ini_get('opcache.enable') ){ + $info = opcache_get_configuration(); + $vers = $info['version']; + $versions[ $vers['opcache_product_name'] ] = ' '.$vers['version']; + } + + // utf8 / encoding: + $encoding = new Loco_mvc_ViewParams( array ( + 'OK' => "\xCE\x9F\xCE\x9A", + 'tick' => "\xE2\x9C\x93", + 'json' => json_decode('"\\u039f\\u039a \\u2713"'), + 'mbstring' => loco_check_extension('mbstring') ? "\xCE\x9F\xCE\x9A \xE2\x9C\x93" : 'No', + ) ); + + // Sanity check mbstring.func_overload + if( 2 !== strlen("\xC2\xA3") ){ + $encoding->mbstring = 'Error, disable mbstring.func_overload'; + } + + // PHP / env memory settings: + $memory = new Loco_mvc_PostParams( array( + 'WP_MEMORY_LIMIT' => $this->memory_size( loco_constant('WP_MEMORY_LIMIT') ), + 'WP_MAX_MEMORY_LIMIT' => $this->memory_size( loco_constant('WP_MAX_MEMORY_LIMIT') ), + 'PHP memory_limit' => $this->memory_size( ini_get('memory_limit') ), + 'PHP post_max_size' => $this->memory_size( ini_get('post_max_size') ), + //'PHP upload_max_filesize' => $this->memory_size( ini_get('upload_max_filesize') ), + 'PHP max_execution_time' => (string) ini_get('max_execution_time'), + ) ); + + // Check if raising memory limit works (wp>=4.6) + if( function_exists('wp_is_ini_value_changeable') && wp_is_ini_value_changeable('memory_limit') ){ + $memory['PHP memory_limit'] .= ' (changeable)'; + } + + // Ajaxing: + $this->enqueueScript('debug'); + $this->set( 'js', new Loco_mvc_ViewParams( array ( + 'nonces' => array( 'ping' => wp_create_nonce('ping'), 'apis' => wp_create_nonce('apis') ), + ) ) ); + + // Third party API integrations: + $apis = array(); + $jsapis = array(); + foreach( Loco_api_Providers::export() as $api ){ + $apis[] = new Loco_mvc_ViewParams($api); + $jsapis[] = $api; + } + if( $apis ){ + $this->set('apis',$apis); + $jsconf = $this->get('js'); + $jsconf['apis'] = $jsapis; + } + + // File system access + $dir = new Loco_fs_Directory( loco_constant('LOCO_LANG_DIR') ) ; + $ctx = new Loco_fs_FileWriter( $dir ); + $fsp = Loco_data_Settings::get()->fs_protect; + $fs = new Loco_mvc_PostParams( array( + 'langdir' => $this->rel_path( $dir->getPath() ), + 'writable' => $ctx->writable(), + 'disabled' => $ctx->disabled(), + 'fs_protect' => 1 === $fsp ? 'Warn' : ( $fsp ? 'Block' : 'Off' ), + ) ); + + // Debug and error log settings + $debug = new Loco_mvc_ViewParams( array( + 'WP_DEBUG' => loco_constant('WP_DEBUG') ? 'On' : 'Off', + 'WP_DEBUG_LOG' => loco_constant('WP_DEBUG_LOG') ? 'On' : 'Off', + 'WP_DEBUG_DISPLAY' => loco_constant('WP_DEBUG_DISPLAY') ? 'On' : 'Off', + 'PHP display_errors' => ini_get('display_errors') ? 'On' : 'Off', + 'PHP log_errors' => ini_get('log_errors') ? 'On' : 'Off', + 'PHP error_log' => $this->rel_path( ini_get('error_log') ), + ) ); + + /* Output buffering settings + $this->set('ob', new Loco_mvc_ViewParams( array( + 'output_handler' => ini_get('output_handler'), + 'zlib.output_compression' => ini_get('zlib.output_compression'), + 'zlib.output_compression_level' => ini_get('zlib.output_compression_level'), + 'zlib.output_handler' => ini_get('zlib.output_handler'), + ) ) );*/ + + // alert to known system setting problems: + if( version_compare(PHP_VERSION,'7.4','<') ){ + if( get_magic_quotes_gpc() ){ + Loco_error_AdminNotices::add( new Loco_error_Debug('You have "magic_quotes_gpc" enabled. We recommend you disable this in PHP') ); + } + if( get_magic_quotes_runtime() ){ + Loco_error_AdminNotices::add( new Loco_error_Debug('You have "magic_quotes_runtime" enabled. We recommend you disable this in PHP') ); + } + } + + // alert to third party plugins known to interfere with functioning of this plugin + if( class_exists('\\LocoAutoTranslateAddon\\LocoAutoTranslate',false) ){ + Loco_error_AdminNotices::add( new Loco_error_Warning('Unoffical add-ons for Loco Translate may affect functionality. We cannot provide support when third party products are installed.') ); + } + + return $this->view('admin/config/debug', compact('breadcrumb','versions','encoding','memory','fs','debug') ); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/config/PrefsController.php b/vendor/loco-translate/src/admin/config/PrefsController.php new file mode 100644 index 0000000..98b0fbb --- /dev/null +++ b/vendor/loco-translate/src/admin/config/PrefsController.php @@ -0,0 +1,49 @@ +set( 'title', __('User options','loco-translate') ); + + // user preference options + $opts = Loco_data_Preferences::get(); + $this->set( 'opts', $opts ); + + // handle save action + $nonce = $this->setNonce('save-prefs'); + try { + if( $this->checkNonce($nonce->action) ){ + $post = Loco_mvc_PostParams::get(); + if( $post->has('opts') ){ + $opts->populate( $post->opts )->persist(); + Loco_error_AdminNotices::success( __('Settings saved','loco-translate') ); + } + } + } + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::add($e); + } + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $title = __('Plugin settings','loco-translate'); + $breadcrumb = new Loco_admin_Navigation; + $breadcrumb->add( $title ); + + return $this->view('admin/config/prefs', compact('breadcrumb') ); + } + +} diff --git a/vendor/loco-translate/src/admin/config/SettingsController.php b/vendor/loco-translate/src/admin/config/SettingsController.php new file mode 100644 index 0000000..ef45882 --- /dev/null +++ b/vendor/loco-translate/src/admin/config/SettingsController.php @@ -0,0 +1,86 @@ +set( 'opts', $opts ); + $this->set( 'dflt', Loco_data_Settings::create() ); + + // roles and capabilities + $perms = new Loco_data_Permissions; + + // handle save action + $nonce = $this->setNonce('save-config'); + try { + if( $this->checkNonce($nonce->action) ){ + $post = Loco_mvc_PostParams::get(); + if( $post->has('opts') ){ + $opts->populate( $post->opts )->persist(); + $perms->populate( $post->has('caps') ? $post->caps : array() ); + // done update + Loco_error_AdminNotices::success( __('Settings saved','loco-translate') ); + // remove saved params from session if persistent options unset + if( ! $opts['fs_persist'] ){ + $session = Loco_data_Session::get(); + if( isset($session['loco-fs']) ){ + unset( $session['loco-fs'] ); + $session->persist(); + } + } + } + } + } + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::add($e); + } + + $this->set('caps', $caps = new Loco_mvc_ViewParams ); + // there is no distinct role for network admin, so we'll fake it for UI + if( is_multisite() ){ + $caps[''] = new Loco_mvc_ViewParams( array( + 'label' => __('Super Admin','default'), + 'name' => 'dummy-admin-cap', + 'attrs' => 'checked disabled' + ) ); + } + foreach( $perms->getRoles() as $id => $role ){ + $caps[$id] = new Loco_mvc_ViewParams( array( + 'value' => '1', + 'label' => $perms->getRoleName($id), + 'name' => 'caps['.$id.'][loco_admin]', + 'attrs' => $perms->isProtectedRole($role) ? 'checked disabled ' : ( $role->has_cap('loco_admin') ? 'checked ' : '' ), + ) ); + } + // allow/deny warning levels + $this->set('verbose', new Loco_mvc_ViewParams( array( + 0 => __('Allow','loco-translate'), + 1 => __('Allow (with warning)','loco-translate'), + 2 => __('Disallow','loco-translate'), + ) ) ); + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $title = __('Plugin settings','loco-translate'); + $breadcrumb = new Loco_admin_Navigation; + $breadcrumb->add( $title ); + + return $this->view('admin/config/settings', compact('breadcrumb') ); + } + +} diff --git a/vendor/loco-translate/src/admin/config/VersionController.php b/vendor/loco-translate/src/admin/config/VersionController.php new file mode 100644 index 0000000..93c195d --- /dev/null +++ b/vendor/loco-translate/src/admin/config/VersionController.php @@ -0,0 +1,65 @@ +set( 'title', __('Version','loco-translate') ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + $title = __('Plugin settings','loco-translate'); + $breadcrumb = new Loco_admin_Navigation; + $breadcrumb->add( $title ); + + // current plugin version + $version = loco_plugin_version(); + + // check for auto-update availability + if( $updates = get_site_transient('update_plugins') ){ + $key = loco_plugin_self(); + if( isset($updates->response[$key]) ){ + $latest = $updates->response[$key]->new_version; + // if current version is lower than latest, prompt update + if( version_compare($version,$latest,'<') ){ + $this->setUpdate($latest); + } + } + } + + // notify if running a development snapshot, but only if ahead of latest stable + if( '-dev' === substr($version,-4) ){ + $this->set( 'devel', true ); + } + + // $this->setUpdate('2.0.1-debug'); + return $this->view('admin/config/version', compact('breadcrumb','version') ); + } + + + + /** + * @param string version + * @return void + */ + private function setUpdate( $version ){ + $action = 'upgrade-plugin_'.loco_plugin_self(); + $link = admin_url( 'update.php?action=upgrade-plugin&plugin='.rawurlencode(loco_plugin_self()) ); + + $this->set('update', $version ); + $this->set('update_href', wp_nonce_url( $link, $action ) ); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/file/BaseController.php b/vendor/loco-translate/src/admin/file/BaseController.php new file mode 100644 index 0000000..e37db0e --- /dev/null +++ b/vendor/loco-translate/src/admin/file/BaseController.php @@ -0,0 +1,167 @@ + List > Bundle > Resource + */ +abstract class Loco_admin_file_BaseController extends Loco_admin_bundle_BaseController { + + /** + * @var Loco_Locale + */ + private $locale; + + + /** + * @return Loco_Locale + */ + protected function getLocale(){ + return $this->locale; + } + + + /** + * Check file is valid or return error + * @param Loco_fs_File + * @return string rendered error + */ + protected function getFileError( Loco_fs_File $file = null ){ + // file must exist for editing + if( is_null($file) || ! $file->exists() ){ + return $this->view( 'admin/errors/file-missing', array() ); + } + if( $file->isDirectory() ){ + $this->set('info', Loco_mvc_FileParams::create($file) ); + return $this->view( 'admin/errors/file-isdir', array() ); + } + // security validations + try { + Loco_gettext_Data::ext( $file ); + // TODO also need to block access to files outside content directory + // this is more difficult as can symlink into and out of the tree. + } + catch( Exception $e ){ + return $this->view( 'admin/errors/file-sec', array( 'reason' => $e->getMessage() ) ); + } + + return ''; + } + + + + /** + * {@inheritdoc} + */ + public function init(){ + parent::init(); + + // views at this level are always related to a file + // file is permitted to be missing during this execution. + $path = $this->get('path'); + if( ! $path ){ + throw new Loco_error_Exception('path argument required'); + } + $file = new Loco_fs_LocaleFile( $path ); + $file->normalize( loco_constant('WP_CONTENT_DIR') ); + $ext = strtolower( $file->extension() ); + // POT file has no locale + if( 'pot' === $ext ){ + $locale = null; + $localised = false; + } + // else file may have a locale suffix (unless invalid, such as "default.po") + else { + $locale = $file->getLocale(); + $localised = $locale->isValid(); + } + + if( $localised ){ + $this->locale = $locale; + $code = (string) $locale; + $this->set( 'locale', new Loco_mvc_ViewParams( array( + 'code' => $code, + 'lang' => $locale->lang, + 'icon' => $locale->getIcon(), + 'name' => $locale->ensureName( new Loco_api_WordPressTranslations ), + 'href' => Loco_mvc_AdminRouter::generate('lang-view', array('locale'=>$code) ), + ) ) ); + } + else { + $this->set( 'locale', null ); + } + + $this->set('file', $file ); + $this->set('filetype', strtoupper($ext) ); + $this->set('title', $file->basename() ); + + // navigate up to root from this bundle sub view + $bundle = $this->getBundle(); + $breadcrumb = Loco_admin_Navigation::createBreadcrumb( $bundle ); + $this->set( 'breadcrumb', $breadcrumb ); + + // navigate between sub view siblings for this resource + $tabs = new Loco_admin_Navigation; + $this->set( 'tabs', $tabs ); + $actions = array ( + 'file-edit' => __('Editor','loco-translate'), + 'file-view' => __('Source','loco-translate'), + 'file-info' => __('File info','loco-translate'), + 'file-diff' => __('Restore','loco-translate'), + 'file-move' => $localised ? __('Relocate','loco-translate') : null, + 'file-delete' => __('Delete','loco-translate'), + ); + + $suffix = $this->get('action'); + $prefix = $this->get('type'); + $args = array_intersect_key($_GET,array('path'=>1,'bundle'=>1,'domain'=>1)); + foreach( $actions as $action => $name ){ + if( is_string($name) ){ + $href = Loco_mvc_AdminRouter::generate( $prefix.'-'.$action, $args ); + $tabs->add( $name, $href, $action === $suffix ); + } + } + + // Provide common language creation link if project scope is is valid + try { + $project = $this->getProject(); + $args = array( 'bundle' => $bundle->getHandle(), 'domain' => $project->getId() ); + $this->set( 'msginit', new Loco_mvc_ViewParams( array ( + 'href' => Loco_mvc_AdminRouter::generate( $prefix.'-msginit', $args ), + 'text' => __('New language','loco-translate'), + ) ) ); + } + catch( Exception $e ){ + + } + } + + + + /** + * {@inheritdoc} + */ + public function view( $tpl, array $args = array() ){ + + if( $breadcrumb = $this->get('breadcrumb') ){ + + // Add project name into breadcrumb if not the same as bundle name + try { + $project = $this->getProject(); + if( $project->getName() !== $this->getBundle()->getName() ){ + $breadcrumb->add( $project->getName() ); + } + } + catch( Loco_error_Exception $e ){ + // ignore missing project in breadcrumb + } + + // Always add page title as final breadcrumb element + $title = $this->get('title') or $title = 'Untitled'; + $breadcrumb->add( $title ); + } + + return parent::view( $tpl, $args ); + } + + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/file/DeleteController.php b/vendor/loco-translate/src/admin/file/DeleteController.php new file mode 100644 index 0000000..9d8435e --- /dev/null +++ b/vendor/loco-translate/src/admin/file/DeleteController.php @@ -0,0 +1,113 @@ +extension(); + throw new Loco_error_Exception( sprintf('Refusing to delete a %s file', strtoupper($ext) ) ); + } + return $siblings->expand(); + } + + + + /** + * {@inheritdoc} + */ + public function init(){ + parent::init(); + $file = $this->get('file'); + + // set up form for delete confirmation + if( $file->exists() && ! $file->isDirectory() ){ + // nonce action will be specific to file for extra security + // TODO could also add file MD5 to avoid deletion after changes made. + $path = $file->getPath(); + $action = 'delete:'.$path; + // set up view now in case of late failure + $fields = new Loco_mvc_HiddenFields( array() ); + $fields->setNonce( $action ); + $this->set( 'hidden', $fields ); + // attempt delete if valid nonce posted back + if( $this->checkNonce($action) ){ + $api = new Loco_api_WordPressFileSystem; + // delete dependant files first, so master still exists if others fail + $files = array_reverse( $this->expandFiles($file) ); + try { + /* @var $trash Loco_fs_File */ + foreach( $files as $trash ){ + $api->authorizeDelete($trash); + $trash->unlink(); + } + // flash message for display after redirect + try { + $n = count( $files ); + Loco_data_Session::get()->flash('success', sprintf( _n('File deleted','%u files deleted',$n,'loco-translate'),$n) ); + Loco_data_Session::close(); + } + catch( Exception $e ){ + // tolerate session failure + } + // redirect to bundle overview + $href = Loco_mvc_AdminRouter::generate( $this->get('type').'-view', array( 'bundle' => $this->get('bundle') ) ); + if( wp_redirect($href) ){ + exit; + } + } + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::add( $e ); + } + } + } + // set page title before render sets inline title + $bundle = $this->getBundle(); + $this->set('title', sprintf( __('Delete %s','loco-translate'), $file->basename() ).' ‹ '.$bundle->getName() ); + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $file = $this->get('file'); + if( $fail = $this->getFileError($file) ){ + return $fail; + } + + $files = $this->expandFiles( $file ); + $info = Loco_mvc_FileParams::create($file); + $this->set( 'info', $info ); + $this->set( 'title', sprintf( __('Delete %s','loco-translate'), $info->name ) ); + + // warn about additional files that will be deleted along with this + if( $deps = array_slice($files,1) ){ + $count = count($deps); + $this->set('warn', sprintf( _n( 'One dependent file will also be deleted', '%u dependent files will also be deleted', $count, 'loco-translate' ), $count ) ); + $infos = array(); + foreach( $deps as $depfile ){ + $infos[] = Loco_mvc_FileParams::create( $depfile ); + } + $this->set('deps', $infos ); + } + + $this->prepareFsConnect( 'delete', $this->get('path') ); + + $this->enqueueScript('delete'); + return $this->view('admin/file/delete'); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/file/DiffController.php b/vendor/loco-translate/src/admin/file/DiffController.php new file mode 100644 index 0000000..ce3c596 --- /dev/null +++ b/vendor/loco-translate/src/admin/file/DiffController.php @@ -0,0 +1,156 @@ +enqueueStyle('podiff'); + + $pofile = $this->get('file'); + if( $pofile->exists() && ! $pofile->isDirectory() ){ + $path = $pofile->getPath(); + $action = 'restore:'.$path; + // set up view now in case of late failure + $fields = new Loco_mvc_HiddenFields( array() ); + $fields->setNonce( $action ); + $this->set( 'hidden', $fields ); + // attempt rollback if valid nonce posted back with backup path + if( $this->checkNonce($action) ){ + try { + $post = Loco_mvc_PostParams::get(); + $api = new Loco_api_WordPressFileSystem; + // Restore + if( $path = $post->backup ){ + $target = new Loco_fs_File( $path ); + $target->normalize( loco_constant('WP_CONTENT_DIR') ); + // parse PO. we'll need it for MO compile anyway + $source = $target->getContents(); + $data = Loco_gettext_Data::fromSource( $source ); + // backup current master before restoring + $backups = new Loco_fs_Revisions($pofile); + if( $num_backups = Loco_data_Settings::get()->num_backups ){ + $api->authorizeCopy($pofile); + $backups->create(); + } + // authorize master for file modification + $api->authorizeUpdate($pofile); + // recompile binary if it exists + $mofile = $pofile->cloneExtension('mo'); + if( $mofile->exists() ){ + $mofile->putContents( $data->msgfmt() ); + } + // replacing source file last in case of failures + $pofile->putContents( $source ); + Loco_error_AdminNotices::success( __('File restored','loco-translate') ); + // prune to configured level after success + $backups->prune( $num_backups ); + $backups = null; + } + // Delete + else if( $path = $post->delete ){ + $target = new Loco_fs_File( $path ); + $target->normalize( loco_constant('WP_CONTENT_DIR') ); + $api->authorizeDelete( $target ); + $target->unlink(); + Loco_error_AdminNotices::success( __('File deleted','loco-translate') ); + } + else { + throw new Loco_error_Exception('Nothing selected'); + } + } + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::add( $e ); + } + } + } + + $bundle = $this->getBundle(); + $this->set('title', sprintf( __('Restore %s','loco-translate'), $pofile->basename() ).' ‹ '.$bundle->getName() ); + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $file = $this->get('file'); + if( $fail = $this->getFileError($file) ){ + return $fail; + } + + $info = Loco_mvc_FileParams::create($file); + $info['mtime'] = $file->modified(); + $this->set( 'master', $info ); + $this->set( 'title', sprintf( __('Restore %s','loco-translate'), $info->name ) ); + + $enabled = Loco_data_Settings::get()->num_backups; + $this->set( 'enabled', $enabled ); + + $files = array(); + $wp_content = loco_constant('WP_CONTENT_DIR'); + $paths = array( $file->getRelativePath($wp_content) ); + + $podate = 'pot' === $file->extension() ? 'POT-Creation-Date' : 'PO-Revision-Date'; + $backups = new Loco_fs_Revisions($file); + + foreach( $backups->getPaths() as $path ){ + $tmp = new Loco_fs_File( $path ); + $info = Loco_mvc_FileParams::create($tmp); + // time file was snapshotted is actually the time the next version was updated + // $info['mtime'] = $backups->getTimestamp($path); + // pull "real" update time, meaning when the revision was last updated as current version + try { + $head = Loco_gettext_Data::head($tmp)->getHeaders(); + if( $value = $head->trimmed($podate) ){ + $info['potime'] = Loco_gettext_Data::parseDate($value); + } + else { + throw new Loco_error_Exception('Backup has no '.$podate.' field'); + } + } + catch( Exception $e ){ + Loco_error_AdminNotices::debug( $e->getMessage() ); + continue; + } + $paths[] = $tmp->getRelativePath($wp_content); + $files[] = $info; + } + + // no backups = no restore + if( ! $files ){ + return $this->view('admin/errors/no-backups'); + } + + /*/ warn if current backup settings aren't enough to restore without losing older revisions + $min = count($files) + 1; + if( $enabled < $min ){ + $notice = Loco_error_AdminNotices::info('We recommend enabling more backups before restoring'); + $notice->addLink( apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/settings#po'), __('Documentation','loco-translate') ) + ->addLink( Loco_mvc_AdminRouter::generate('config').'#loco--num-backups', __('Settings') ); + }*/ + + // restore permissions required are create and delete on current location + $this->prepareFsConnect( 'update', $this->get('path') ); + + // prepare revision arguments for JavaScript + $this->set( 'js', new Loco_mvc_ViewParams( array( + 'paths' => $paths, + 'nonces' => array ( + 'diff' => wp_create_nonce('diff'), + ) + ) ) ); + + $this->enqueueScript('podiff'); + return $this->view('admin/file/diff', compact('files','backups') ); + } + + +} diff --git a/vendor/loco-translate/src/admin/file/EditController.php b/vendor/loco-translate/src/admin/file/EditController.php new file mode 100644 index 0000000..55fb85c --- /dev/null +++ b/vendor/loco-translate/src/admin/file/EditController.php @@ -0,0 +1,245 @@ +enqueueStyle('editor'); + // + $file = $this->get('file'); + $bundle = $this->getBundle(); + // translators: %1$s is the file name, %2$s is the bundle name + $this->set('title', sprintf( __('Editing %1$s in %2$s','loco-translate'), $file->basename(), $bundle ) ); + } + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-file-edit'), + ); + } + + + /** + * @param bool whether po files is in read-only mode + * @return array + */ + private function getNonces( $readonly ){ + $nonces = array(); + foreach( $readonly ? array('fsReference') : array('sync','save','fsReference','apis') as $name ){ + $nonces[$name] = wp_create_nonce($name); + } + return $nonces; + } + + + /** + * @param bool whether po files is in read-only mode + * @return array + */ + private function getApiProviders( $readonly ){ + return $readonly ? null : array_values( array_filter(Loco_api_Providers::export(),array(__CLASS__,'filterApiProvider') ) ); + } + + + /** + * @internal + * @param string[] + * @return bool + */ + private static function filterApiProvider( array $api ){ + return (bool) $api['key']; + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + // file must exist for editing + $file = $this->get('file'); + if( $fail = $this->getFileError($file) ){ + return $fail; + } + + // editor will be rendered + $this->enqueueScript('editor'); + + // Parse file data into JavaScript for editor + try { + $this->set('modified', $file->modified() ); + $data = Loco_gettext_Data::load( $file ); + } + catch( Exception $e ){ + Loco_error_AdminNotices::add( Loco_error_Exception::convert($e) ); + $data = Loco_gettext_Data::dummy(); + } + + $head = $data->getHeaders(); + + // default is to permit editing of any file + $readonly = false; + + // Establish if file belongs to a configured project + try { + $bundle = $this->getBundle(); + $project = $this->getProject(); + } + // Fine if not, this just means sync isn't possible. + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::add( $e ); + Loco_error_AdminNotices::debug( sprintf("Sync is disabled because this file doesn't relate to a known set of translations", $bundle ) ); + $project = null; + } + + // Establish PO/POT edit mode + $potfile = null; + $locale = $this->getLocale(); + if( $locale instanceof Loco_Locale ){ + // alternative POT file may be forced by PO headers + if( $value = $head['X-Loco-Template'] ){ + $potfile = new Loco_fs_File($value); + $potfile->normalize( $bundle->getDirectoryPath() ); + } + // else use project-configured template, assuming there is one + // no way to get configured POT if invalid project + else if( $project ){ + $potfile = $project->getPot(); + // Handle situation where project defines a localised file as the official template + if( $potfile && $potfile->equal($file) ){ + $locale = null; + $potfile = null; + } + } + if( $potfile ){ + // Validate template file as long as it exists + if( $potfile->exists() ){ + try { + $potdata = Loco_gettext_Data::load( $potfile ); + if( ! $potdata->equalSource($data) ){ + Loco_error_AdminNotices::debug( sprintf( __("Translations don't match template. Run sync to update from %s",'loco-translate'), $potfile->basename() ) ); + } + } + catch( Exception $e ){ + // translators: Where %s is the name of the invalid POT file + Loco_error_AdminNotices::warn( sprintf( __('Translation template is invalid (%s)','loco-translate'), $potfile->basename() ) ); + $potfile = null; + } + } + // else template doesn't exist, so sync will be done to source code + else { + // Loco_error_AdminNotices::debug( sprintf( __('Template file not found (%s)','loco-translate'), $potfile->basename() ) ); + $potfile = null; + } + } + if( $locale ){ + // allow PO file to dictate its own Plural-Forms + try { + $locale->setPluralFormsHeader( $head['Plural-Forms'] ); + } + catch( InvalidArgumentException $e ){ + // ignore invalid Plural-Forms + } + // fill in missing PO headers now locale is fully resolved + $data->localize($locale); + + // If MO file will be compiled, check for library/config problems + if ( 2 !== strlen( "\xC2\xA3" ) ) { + Loco_error_AdminNotices::warn('Your mbstring configuration will result in corrupt MO files. Please ensure mbstring.func_overload is disabled'); + } + } + } + + $settings = Loco_data_Settings::get(); + + if( is_null($locale) ){ + // notify if template is locked (save and sync will be disabled) + if( $project && $project->isPotLocked() ){ + $this->set('fsDenied', true ); + $readonly = true; + } + // translators: Warning when POT file is opened in the file editor. It can be disabled in settings. + else if( 1 === $settings->pot_protect ){ + Loco_error_AdminNotices::warn( __("This is NOT a translation file. Manual editing of source strings is not recommended.",'loco-translate') ) + ->addLink( Loco_mvc_AdminRouter::generate('config').'#loco--pot-protect', __('Settings','loco-translate') ) + ->addLink( apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/templates'), __('Documentation','loco-translate') ); + } + } + + // back end expects paths relative to wp-content + $wp_content = loco_constant('WP_CONTENT_DIR'); + + $this->set( 'js', new Loco_mvc_ViewParams( array( + 'podata' => $data->jsonSerialize(), + 'powrap' => (int) $settings->po_width, + 'multipart' => (bool) $settings->ajax_files, + 'locale' => $locale ? $locale->jsonSerialize() : null, + 'potpath' => $locale && $potfile ? $potfile->getRelativePath($wp_content) : null, + 'popath' => $this->get('path'), + 'readonly' => $readonly, + 'project' => $project ? array ( + 'bundle' => $bundle->getId(), + 'domain' => (string) $project->getId(), + ) : null, + 'nonces' => $this->getNonces($readonly), + 'apis' => $locale ? $this->getApiProviders($readonly) : null, + ) ) ); + $this->set( 'ui', new Loco_mvc_ViewParams( array( + // Translators: button for adding a new string when manually editing a POT file + 'add' => _x('Add','Editor','loco-translate'), + // Translators: button for removing a string when manually editing a POT file + 'del' => _x('Remove','Editor','loco-translate'), + 'help' => __('Help','loco-translate'), + // Translators: Button that saves translations to disk + 'save' => _x('Save','Editor','loco-translate'), + // Translators: Button that runs in-editor sync/operation + 'sync' => _x('Sync','Editor','loco-translate'), + // Translators: Button that reloads current screen + 'revert' => _x('Revert','Editor','loco-translate'), + // Translators: Button that opens window for auto-translating + 'auto' => _x('Auto','Editor','loco-translate'), + // Translators: Button for downloading a PO, MO or POT file + 'download' => _x('Download','Editor','loco-translate'), + // Translators: Placeholder text for text filter above editor + 'filter' => __('Filter translations','loco-translate'), + // Translators: Button that toggles invisible characters + 'invs' => _x('Toggle invisibles','Editor','loco-translate'), + // Translators: Button that toggles between "code" and regular text editing modes + 'code' => _x('Toggle code view','Editor','loco-translate'), + ) ) ); + + // Download form params + $hidden = new Loco_mvc_HiddenFields( array( + 'path' => '', + 'source' => '', + 'route' => 'download', + 'action' => 'loco_download', + ) ); + $this->set( 'dlFields', $hidden->setNonce('download') ); + $this->set( 'dlAction', admin_url('admin-ajax.php','relative') ); + + // Remote file system required if file is not directly writable + $this->prepareFsConnect( 'update', $this->get('path') ); + + // set simpler title for breadcrumb + $this->set('title', $file->basename() ); + + // ok to render editor as either po or pot + $tpl = $locale ? 'po' : 'pot'; + return $this->view( 'admin/file/edit-'.$tpl, array() ); + } + + + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/file/InfoController.php b/vendor/loco-translate/src/admin/file/InfoController.php new file mode 100644 index 0000000..d9e90a5 --- /dev/null +++ b/vendor/loco-translate/src/admin/file/InfoController.php @@ -0,0 +1,201 @@ +enqueueStyle('fileinfo'); + // + $file = $this->get('file'); + $bundle = $this->getBundle(); + $this->set('title', $file->basename().' ‹ '.$bundle->getName() ); + } + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-file-info'), + ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + $file = $this->get('file'); + $name = $file->basename(); + $this->set('title', $name ); + + if( $fail = $this->getFileError($file) ){ + return $fail; + } + + // file info + $ext = strtolower( $file->extension() ); + $finfo = Loco_mvc_FileParams::create( $file ); + $this->set('file', $finfo ); + $finfo['type'] = strtoupper($ext); + if( $file->exists() ){ + $finfo['existent'] = true; + $finfo['writable'] = $file->writable(); + $finfo['deletable'] = $file->deletable(); + $finfo['mtime'] = $file->modified(); + // Notify if file is managed by WordPress + $api = new Loco_api_WordPressFileSystem; + if( $api->isAutoUpdatable($file) ){ + $finfo['autoupdate'] = true; + } + } + + // location info + $dir = new Loco_fs_LocaleDirectory( $file->dirname() ); + $dinfo = Loco_mvc_FileParams::create( $dir ); + $this->set('dir', $dinfo ); + $dinfo['type'] = $dir->getTypeId(); + if( $dir->exists() && $dir->isDirectory() ){ + $dinfo['existent'] = true; + $dinfo['writable'] = $dir->writable(); + } + + // collect note worthy problems with file headers + $debugging = loco_debugging(); + $debug = array(); + + // get the name of the web server for information purposes + $this->set('httpd', Loco_compat_PosixExtension::getHttpdUser() ); + + // unknown file template if required + $locale = null; + $project = null; + $tpl = 'admin/file/info-other'; + + // we should know the project the file belongs to, but permitting orphans for debugging + try { + $project = $this->getProject(); + $template = $project->getPot(); + $isTemplate = $template && $file->equal($template); + $this->set('isTemplate', $isTemplate ); + $this->set('project', $project ); + } + catch( Loco_error_Exception $e ){ + $debug[] = $e->getMessage(); + $isTemplate = false; + $template = null; + } + + // file will be Gettext most likely + if( 'pot' === $ext || 'po' === $ext || 'mo' === $ext ){ + // treat as template until locale verified + $tpl = 'admin/file/info-pot'; + // don't attempt to pull locale of template file + if( 'pot' !== $ext && ! $isTemplate ){ + $locale = $file->getLocale(); + $code = (string) $locale; + if( $locale->isValid() ){ + // find PO/MO counter parts + if( 'po' === $ext ){ + $tpl = 'admin/file/info-po'; + $sibling = $file->cloneExtension('mo'); + } + else { + $tpl = 'admin/file/info-mo'; + $sibling = $file->cloneExtension('po'); + } + $info = Loco_mvc_FileParams::create($sibling); + $this->set( 'sibling', $info ); + if( $sibling->exists() ){ + $info['existent'] = true; + $info['writable'] = $sibling->writable(); + } + } + } + // Do full parse to get stats and headers + try { + $data = Loco_gettext_Data::load($file); + $head = $data->getHeaders(); + $author = $head->trimmed('Last-Translator') or $author = __('Unknown author','loco-translate'); + $this->set( 'author', $author ); + // date headers may not be same as file modification time (files copied to server etc..) + $podate = $head->trimmed( $locale ? 'PO-Revision-Date' : 'POT-Creation-Date' ); + $potime = Loco_gettext_Data::parseDate($podate) or $potime = $file->modified(); + $this->set('potime', $potime ); + // access to meta stats, normally cached on listing pages + $meta = Loco_gettext_Metadata::create($file,$data); + $this->set( 'meta', $meta ); + // allow PO header to specify alternative template for sync + if( $head->has('X-Loco-Template') ){ + $altpot = new Loco_fs_File($head['X-Loco-Template']); + $altpot->normalize( $this->getBundle()->getDirectoryPath() ); + if( $altpot->exists() && ( ! $template || ! $template->equal($altpot) ) ){ + $template = $altpot; + } + } + // establish whether PO is in sync with POT + if( $template && ! $isTemplate && 'po' === $ext && $template->exists() ){ + try { + $this->set('potfile', new Loco_mvc_FileParams( array( + 'synced' => Loco_gettext_Data::load($template)->equalSource($data), + ), $template ) ); + } + catch( Exception $e ){ + // ignore invalid template in this context + } + } + if( $debugging ){ + // missing or invalid headers are tollerated but developers should be notified + if( $debugging && ! count($head) ){ + $debug[] = __('File does not have a valid header','loco-translate'); + } + // Language header sanity checks, raising developer (debug) warnings + if( $locale ){ + if( $value = $head['Language'] ){ + $check = (string) Loco_Locale::parse($value); + if( $check !== $code ){ + $debug[]= sprintf( __('Language header is "%s" but file name contains "%s"','loco-translate'), $value, $code ); + } + } + if( $value = $head['Plural-Forms'] ){ + try { + $locale->setPluralFormsHeader($value); + } + catch( InvalidArgumentException $e ){ + $debug[] = sprintf('Plural-Forms header is invalid, "%s"',$value); + } + } + } + // Other sanity checks + if( $project && ( $value = $head['Project-Id-Version'] ) && $value !== $project->getName() ){ + $debug[] = sprintf('Project-Id-Version header is "%s" but project is "%s"', $value, $project ); + } + } + // Count source text for templates only (assumed English) + if( 'admin/file/info-pot' === $tpl ){ + $counter = new Loco_gettext_WordCount($data); + $this->set('words', $counter->count() ); + } + } + catch( Loco_error_Exception $e ){ + $this->set('error', $e->getMessage() ); + $tpl = 'admin/file/info-other'; + } + } + + if( $debugging && $debug ){ + $this->set( 'debug', new Loco_mvc_ViewParams($debug) ); + } + + return $this->view( $tpl ); + } + +} diff --git a/vendor/loco-translate/src/admin/file/MoveController.php b/vendor/loco-translate/src/admin/file/MoveController.php new file mode 100644 index 0000000..6caa7b8 --- /dev/null +++ b/vendor/loco-translate/src/admin/file/MoveController.php @@ -0,0 +1,185 @@ +get('file'); + /* @var Loco_fs_File $file */ + if( $file->exists() && ! $file->isDirectory() ){ + $files = new Loco_fs_Siblings($file); + // nonce action will be specific to file for extra security + $path = $file->getPath(); + $action = 'move:'.$path; + // set up view now in case of late failure + $fields = new Loco_mvc_HiddenFields( array() ); + $fields->setNonce( $action ); + $fields['auth'] = 'move'; + $fields['path'] = $this->get('path'); + $this->set('hidden',$fields ); + // attempt move if valid nonce posted back + while( $this->checkNonce($action) ){ + // Chosen location should be valid as a posted "dest" parameter + if( ! Loco_mvc_PostParams::get()->has('dest') ){ + Loco_error_AdminNotices::err('No destination posted'); + break; + } + $target = new Loco_fs_LocaleFile( Loco_mvc_PostParams::get()->dest ); + $ext = $target->extension(); + // primary file extension should only be permitted to change between po and pot + if( $ext !== $file->extension() && 'po' !== $ext && 'pot' !== $ext ){ + Loco_error_AdminNotices::err('Invalid file extension, *.po or *.pot only'); + break; + } + $target->normalize( loco_constant('WP_CONTENT_DIR') ); + $target_dir = $target->getParent()->getPath(); + // Primary file gives template remapping, so all files are renamed with same stub. + // this can only be one of three things: (en -> en) or (foo-en -> en) or (en -> foo-en) + // suffix will then consist of file extension, plus any other stuff like backup file date. + $target_base = $target->filename(); + $source_snip = strlen( $file->filename() ); + // buffer all files to move to preempt write failures + $movable = array(); + $api = new Loco_api_WordPressFileSystem; + foreach( $files->expand() as $source ){ + $suffix = substr( $source->basename(), $source_snip ); // <- e.g. "-backup.po~" + $target = new Loco_fs_File( $target_dir.'/'.$target_base.$suffix ); + // permit valid change of file extension on primary source file (po/pot) + if( $source === $files->getSource() && $target->extension() !== $ext ){ + $target = $target->cloneExtension($ext); + } + if( ! $api->authorizeMove($source,$target) ) { + Loco_error_AdminNotices::err('Failed to authorize relocation of '.$source->basename() ); + break 2; + } + $movable[] = array($source,$target); + } + // commit moves. If any fail we'll have separated the files, which is bad + $count = 0; + $total = count($movable); + foreach( $movable as $pair ){ + try { + $pair[0]->move( $pair[1] ); + $count++; + } + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::add($e); + } + } + // flash messages for display after redirect + try { + if( $count ) { + Loco_data_Session::get()->flash( 'success', sprintf( _n( 'File moved', '%u files moved', $total, 'loco-translate' ), $total ) ); + } + if( $total > $count ){ + $diff = $total - $count; + Loco_data_Session::get()->flash( 'error', sprintf( _n( 'One file could not be moved', '%u files could not be moved', $diff, 'loco-translate' ), $diff ) ); + } + Loco_data_Session::close(); + } + catch( Exception $e ){ + // tolerate session failure + } + // redirect to bundle overview + $href = Loco_mvc_AdminRouter::generate( $this->get('type').'-view', array( 'bundle' => $this->get('bundle') ) ); + if( wp_redirect($href) ){ + exit; + } + break; + } + } + // set page title before render sets inline title + $bundle = $this->getBundle(); + $this->set('title', sprintf( __('Move %s','loco-translate'), $file->basename() ).' ‹ '.$bundle->getName() ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + $file = $this->get('file'); + if( $fail = $this->getFileError($file) ){ + return $fail; + } + // relocation requires knowing text domain and locale + try { + $project = $this->getProject(); + } + catch( Loco_error_Exception $e ){ + Loco_error_AdminNotices::warn($e->getMessage()); + $project = null; + } + $files = new Loco_fs_Siblings($file); + $file = new Loco_fs_LocaleFile( $files->getSource() ); + $locale = $file->getLocale(); + // switch between canonical move and custom file path mode + $custom = is_null($project) || $this->get('custom') || 'po' !== $file->extension() || ! $locale->isValid(); + // common page elements: + $this->set('files',$files->expand() ); + $this->set('title', sprintf( __('Move %s','loco-translate'), $file->filename() ) ); + $this->enqueueScript('move'); + // set info for existing file location + $content_dir = loco_constant('WP_CONTENT_DIR'); + $current = $file->getRelativePath($content_dir); + $parent = new Loco_fs_LocaleDirectory( $file->dirname() ); + $typeId = $parent->getTypeId(); + $this->set('current', new Loco_mvc_ViewParams(array( + 'path' => $parent->getRelativePath($content_dir), + 'type' => $parent->getTypeLabel($typeId), + )) ); + // moving files will require deletion permission on current file location + // plus write permission on target location, but we don't know what that is yet. + $fields = $this->prepareFsConnect('move',$current); + $fields['path'] = ''; + $fields['dest'] = ''; + // custom file move template (POT mode) + if( $custom ){ + $this->get('hidden')->offsetSet('custom','1'); + $this->set('file', Loco_mvc_FileParams::create($file) ); + return $this->view('admin/file/move-pot'); + } + // establish valid locations for translation set, which may include current: + $filechoice = $project->initLocaleFiles($locale); + // start with current location so always first in list + $locations = array(); + $locations[$typeId] = new Loco_mvc_ViewParams( array( + 'label' => $parent->getTypeLabel($typeId), + 'paths' => array( new Loco_mvc_ViewParams( array( + 'path' => $current, + 'active' => true, + ) ) ) + ) ); + /* @var Loco_fs_File $pofile */ + foreach( $filechoice as $pofile ){ + $relpath = $pofile->getRelativePath($content_dir); + if( $current === $relpath ){ + continue; + } + // initialize location type (system, etc..) + $parent = new Loco_fs_LocaleDirectory( $pofile->dirname() ); + $typeId = $parent->getTypeId(); + if( ! isset($locations[$typeId]) ){ + $locations[$typeId] = new Loco_mvc_ViewParams( array( + 'label' => $parent->getTypeLabel($typeId), + 'paths' => array(), + ) ); + } + $choice = new Loco_mvc_ViewParams( array( + 'path' => $relpath, + ) ); + $locations[$typeId]['paths'][] = $choice; + } + $this->set('locations', $locations ); + $this->set('advanced', $_SERVER['REQUEST_URI'].'&custom=1' ); + return $this->view('admin/file/move-po'); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/file/ViewController.php b/vendor/loco-translate/src/admin/file/ViewController.php new file mode 100644 index 0000000..b07b5f0 --- /dev/null +++ b/vendor/loco-translate/src/admin/file/ViewController.php @@ -0,0 +1,101 @@ +enqueueStyle('poview'); + // + $file = $this->get('file'); + $bundle = $this->getBundle(); + $this->set( 'title', 'Source of '.$file->basename().' ‹ '.$bundle->getName() ); + } + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-file-view'), + ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + // file must exist for editing + /* @var Loco_fs_File $file */ + $file = $this->get('file'); + $name = $file->basename(); + $type = strtolower( $file->extension() ); + $this->set('title', $name ); + + if( $fail = $this->getFileError($file) ){ + return $fail; + } + + // Establish if file belongs to a configured project + try { + $bundle = $this->getBundle(); + $project = $this->getProject(); + } + catch( Exception $e ){ + $project = null; + } + + // Parse data before rendering, so we know it's a valid Gettext format + try { + $this->set('modified', $file->modified() ); + $data = Loco_gettext_Data::load( $file ); + } + catch( Loco_error_ParseException $e ){ + Loco_error_AdminNotices::add( Loco_error_Exception::convert($e) ); + $data = Loco_gettext_Data::dummy(); + } + + $this->set( 'meta', Loco_gettext_Metadata::create($file, $data) ); + + // binary MO will be hex-formatted in template + if( 'mo' === $type ){ + $this->set('bin', $file->getContents() ); + return $this->view('admin/file/view-mo' ); + } + + // else is a PO or POT file + $this->enqueueScript('poview');//->enqueueScript('min/highlight'); + $lines = preg_split('/(?:\\n|\\r\\n?)/', Loco_gettext_Data::ensureUtf8( $file->getContents() ) ); + $this->set( 'lines', $lines ); + + // ajax parameters required for pulling reference sources + $this->set('js', new Loco_mvc_ViewParams( array ( + 'popath' => $this->get('path'), + 'nonces' => array( + 'fsReference' => wp_create_nonce('fsReference'), + ), + 'project' => $bundle ? array ( + 'bundle' => $bundle->getId(), + 'domain' => $project ? $project->getId() : '', + ) : null, + ) ) ); + + + // treat as PO if file name has locale + if( $this->getLocale() ){ + return $this->view('admin/file/view-po' ); + } + + // else view as POT + return $this->view('admin/file/view-pot' ); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/init/BaseController.php b/vendor/loco-translate/src/admin/init/BaseController.php new file mode 100644 index 0000000..e69de29 diff --git a/vendor/loco-translate/src/admin/init/InitPoController.php b/vendor/loco-translate/src/admin/init/InitPoController.php new file mode 100644 index 0000000..aa2232d --- /dev/null +++ b/vendor/loco-translate/src/admin/init/InitPoController.php @@ -0,0 +1,327 @@ +enqueueStyle('poinit'); + // + $bundle = $this->getBundle(); + $this->set('title', __('New language','loco-translate').' ‹ '.$bundle ); + } + + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-init-po'), + ); + } + + + + /** + * Sort to the left the best option for saving new translation files + * @return Loco_mvc_ViewParams + */ + private function sortPreferred( array $choices ){ + usort( $choices, array(__CLASS__,'_onSortPreferred') ); + $best = current( $choices ); + if( $best && ! $best['disabled'] ){ + return $best; + } + } + + + + /** + * @internal + */ + public static function _onSortPreferred( Loco_mvc_ViewParams $a, Loco_mvc_ViewParams $b ){ + $x = self::scoreFileChoice($a); + $y = self::scoreFileChoice($b); + return $x === $y ? 0 : ( $x > $y ? -1 : 1 ); + } + + + /** + * Score an individual file choice for sorting preferred + * @return int + */ + private static function scoreFileChoice( Loco_mvc_ViewParams $p ){ + $score = 0; + if( $p['writable'] ){ + $score++; + } + if( $p['disabled'] ){ + $score -= 2; + } + if( $p['systype'] ){ + $score--; + } + return $score; + } + + + + /** + * @internal + */ + public static function _onSortLocationKeys( $a, $b ){ + static $order = array('custom' => 4, 'wplang' => 3, 'theme' => 2, 'plugin' => 2, 'other' => 1 ); + $x = $order[$a]; + $y = $order[$b]; + return $x === $y ? 0 : ( $x > $y ? -1 : 1 ); + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $breadcrumb = $this->prepareNavigation(); + // "new" tab is confusing when no project-scope navigation + // $this->get('tabs')->add( __('New PO','loco-translate'), '', true ); + + // bundle mandatory, but project optional + $bundle = $this->getBundle(); + + try { + $project = $this->getProject(); + $slug = $project->getSlug(); + $domain = (string) $project->getDomain(); + $subhead = sprintf( __('Initializing new translations in "%s"','loco-translate'), $slug?$slug:$domain ); + } + catch( Loco_error_Exception $e ){ + $project = null; + $subhead = __('Initializing new translations in unknown set','loco-translate'); + } + + $title = __('New language','loco-translate'); + $this->set('subhead', $subhead ); + + // navigate up to bundle listing page + $breadcrumb->add( $title ); + $this->set( 'breadcrumb', $breadcrumb ); + + // default locale is a placeholder + $locale = new Loco_Locale('zxx'); + $content_dir = untrailingslashit( loco_constant('WP_CONTENT_DIR') ); + $copying = false; + + // Permit using any provided file a template instead of POT + if( $potpath = $this->get('path') ){ + $potfile = new Loco_fs_LocaleFile($potpath); + $potfile->normalize( $content_dir ); + if( ! $potfile->exists() ){ + throw new Loco_error_Exception('Forced template argument must exist'); + } + $copying = true; + // forced source could be a POT (although UI would normally prevent it) + if( $potfile->getSuffix() ){ + $locale = $potfile->getLocale(); + $this->set('sourceLocale', $locale ); + } + } + // else project not configured. UI should prevent this by not offering msginit + else if( ! $project ){ + throw new Loco_error_Exception('Cannot add new language to unconfigured set'); + } + // else POT file may or may not be known, and may or may not exist + else { + $potfile = $project->getPot(); + } + + + $locales = array(); + $installed = array(); + $api = new Loco_api_WordPressTranslations; + // pull installed list first, this will include en_US and any non-standard languages installed + foreach( $api->getInstalledCore() as $tag ){ + $locale = Loco_Locale::parse($tag); + if( $locale->isValid() ){ + $tag = (string) $tag; + // We may not have names for these, so just the language tag will show + $installed[$tag] = new Loco_mvc_ViewParams( array( + 'value' => $tag, + 'icon' => $locale->getIcon(), + 'label' => $locale->ensureName($api), + ) ); + } + } + // pull the same list of "available" languages as used in WordPress settings + /* @var $locale Loco_Locale */ + foreach( $api->getAvailableCore() as $tag => $locale ){ + if( ! array_key_exists($tag,$installed) ){ + $locales[$tag] = new Loco_mvc_ViewParams( array( + 'value' => $tag, + 'icon' => $locale->getIcon(), + 'label' => $locale->ensureName($api), + ) ); + } + } + + // two locale lists built for "installed" and "available" dropdowns + $this->set( 'locales', $locales ); + $this->set( 'installed', $installed ); + + // Critical that user selects the correct save location: + if( $project ){ + $filechoice = $project->initLocaleFiles( $locale ); + } + // without configured project we will only allow save to same location + else { + $filechoice = new Loco_fs_FileList; + } + + + // show information about POT file if we are initializing from template + if( $potfile && $potfile->exists() ){ + $meta = Loco_gettext_Metadata::load($potfile); + $total = $meta->getTotal(); + $summary = sprintf( _n('One string found in %2$s','%s strings found in %s',$total,'loco-translate'), number_format($total), $potfile->basename() ); + $this->set( 'pot', new Loco_mvc_ViewParams( array( + 'name' => $potfile->basename(), + 'path' => $meta->getPath(false), + ) ) ); + // if copying an existing PO file, we can fairly safely establish the correct prefixing + if( $copying ){ + $poname = ( $prefix = $potfile->getPrefix() ) ? sprintf('%s-%s.po',$prefix,$locale) : sprintf('%s.po',$locale); + $pofile = new Loco_fs_LocaleFile( $poname ); + $pofile->normalize( $potfile->dirname() ); + $filechoice->add( $pofile ); + } + /// else if POT is in a folder we don't know about, we may as well add to the choices + // TODO this means another utility function in project for prefixing rules on individual location + } + // else no template exists, so we prompt to extract from source + else { + $this->set( 'ext', new Loco_mvc_ViewParams( array( + 'link' => Loco_mvc_AdminRouter::generate( $this->get('type').'-xgettext', $_GET ), + 'text' => __('Create template','loco-translate'), + ) ) ); + // if forcing source extraction show brief description of source files + if( $this->get('extract') ){ + // Tokenizer required for string extraction + if( ! loco_check_extension('tokenizer') ){ + return $this->view('admin/errors/no-tokenizer'); + } + $nfiles = count( $project->findSourceFiles() ); + $summary = sprintf( _n('1 source file will be scanned for translatable strings','%s source files will be scanned for translatable strings',$nfiles,'loco-translate'), number_format_i18n($nfiles) ); + } + // else prompt for template creation before continuing + else { + $this->set( 'skip', new Loco_mvc_ViewParams( array( + 'link' => Loco_mvc_AdminRouter::generate( $this->get('_route'), $_GET + array( 'extract' => '1' ) ), + 'text' => __('Skip template','loco-translate'), + ) ) ); + // POT could still be defined, it might just not exist yet + if( $potfile ){ + $this->set('pot', Loco_mvc_FileParams::create($potfile) ); + } + // else offer assignment of a new file + else { + $this->set( 'conf', new Loco_mvc_ViewParams( array( + 'link' => Loco_mvc_AdminRouter::generate( $this->get('type').'-conf', array_intersect_key($_GET,array('bundle'=>'')) ), + 'text' => __('Assign template','loco-translate'), + ) ) ); + } + return $this->view('admin/init/init-prompt'); + } + } + $this->set( 'summary', $summary ); + + // group established locations into types (official, etc..) + // there is no point checking whether any of these file exist, because we don't know what language will be chosen yet. + $sortable = array(); + $locations = array(); + $fs_protect = Loco_data_Settings::get()->fs_protect; + $fs_failure = null; + /* @var Loco_fs_File $pofile */ + foreach( $filechoice as $pofile ){ + $parent = new Loco_fs_LocaleDirectory( $pofile->dirname() ); + $systype = $parent->getUpdateType(); + $typeId = $parent->getTypeId(); + if( ! isset($locations[$typeId]) ){ + $locations[$typeId] = new Loco_mvc_ViewParams( array( + 'label' => $parent->getTypeLabel( $typeId ), + 'paths' => array(), + ) ); + } + // folder may be unwritable (requiring connect to create file) or may be denied under security settings + try { + $context = $parent->getWriteContext()->authorize(); + $writable = $context->writable(); + $disabled = false; + } + catch( Loco_error_WriteException $e ){ + $fs_failure = $e->getMessage(); + $writable = false; + $disabled = true; + } + $choice = new Loco_mvc_ViewParams( array ( + 'checked' => '', + 'writable' => $writable, + 'disabled' => $disabled, + 'systype' => $systype, + 'parent' => Loco_mvc_FileParams::create( $parent ), + 'hidden' => $pofile->getRelativePath($content_dir), + 'holder' => str_replace( (string) $locale, '<locale>', $pofile->basename() ), + ) ); + // may need to show system file warnings + if( $systype && $fs_protect ){ + $choice['syswarn'] = true; + } + $sortable[] = $choice; + $locations[$typeId]['paths'][] = $choice; + } + + // display locations in runtime preference order + uksort( $locations, array(__CLASS__,'_onSortLocationKeys') ); + $this->set( 'locations', $locations ); + + // pre-select best (safest/writable) option + if( $preferred = $this->sortPreferred( $sortable ) ){ + $preferred['checked'] = 'checked'; + } + // else show total lock message. probably file mods disallowed + else if( $fs_failure ){ + $this->set('fsLocked', $fs_failure ); + } + + // hidden fields to pass through to Ajax endpoint + $this->set('hidden', new Loco_mvc_HiddenFields( array( + 'action' => 'loco_json', + 'route' => 'msginit', + 'loco-nonce' => $this->setNonce('msginit')->value, + 'type' => $bundle->getType(), + 'bundle' => $bundle->getHandle(), + 'domain' => $project ? $project->getId() : '', + 'source' => $potpath, + ) ) ); + + $this->set('help', new Loco_mvc_ViewParams( array( + 'href' => apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/msginit'), + 'text' => __("What's this?",'loco-translate'), + ) ) ); + + // file system prompts will be handled when paths are selected (i.e. we don't have one yet) + $this->prepareFsConnect( 'create', '' ); + + $this->enqueueScript('poinit'); + return $this->view( 'admin/init/init-po', array() ); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/init/InitPotController.php b/vendor/loco-translate/src/admin/init/InitPotController.php new file mode 100644 index 0000000..0c88b68 --- /dev/null +++ b/vendor/loco-translate/src/admin/init/InitPotController.php @@ -0,0 +1,151 @@ +enqueueStyle('poinit'); + // + $bundle = $this->getBundle(); + $this->set('title', __('New template','loco-translate').' ‹ '.$bundle ); + } + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-init-pot'), + ); + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $breadcrumb = $this->prepareNavigation(); + // "new" tab is confusing when no project-scope navigation + // $this->get('tabs')->add( __('New POT','loco-translate'), '', true ); + + $bundle = $this->getBundle(); + $project = $this->getProject(); + + $slug = $project->getSlug(); + $domain = (string) $project->getDomain(); + $this->set('domain', $domain ); + + // Tokenizer required for string extraction + if( ! loco_check_extension('tokenizer') ){ + return $this->view('admin/errors/no-tokenizer'); + } + + // Establish default POT path whether it exists or not + $pot = $project->getPot(); + while( ! $pot ){ + $name = ( $slug ? $slug : $domain ).'.pot'; + /* @var $dir Loco_fs_Directory */ + foreach( $project->getConfiguredTargets() as $dir ){ + $pot = new Loco_fs_File( $dir->getPath().'/'.$name ); + break 2; + } + // unlikely to have no configured targets, but possible ... so default to standard + $pot = new Loco_fs_File( $bundle->getDirectoryPath().'/languages/'.$name ); + break; + } + + // POT should actually not exist at this stage. It should be edited instead. + if( $pot->exists() ){ + throw new Loco_error_Exception( __('Template file already exists','loco-translate') ); + } + + // Bundle may deliberately lock template to avoid end-user tampering + // it makes little sense to do so when template doesn't exist, but we will honour the setting anyway. + if( $project->isPotLocked() ){ + throw new Loco_error_Exception('Template is protected from updates by the bundle configuration'); + } + + // Just warn if POT writing will fail when saved, but still show screen + $dir = $pot->getParent(); + + // Avoiding full source scan until actioned, but calculate size to manage expectations + $bytes = 0; + $nfiles = 0; + $nskip = 0; + $largest = 0; + $sources = $project->findSourceFiles(); + // skip files larger than configured maximum + $opts = Loco_data_Settings::get(); + $max = wp_convert_hr_to_bytes( $opts->max_php_size ); + /* @var $sourceFile Loco_fs_File */ + foreach( $sources as $sourceFile ){ + $nfiles++; + $fsize = $sourceFile->size(); + $largest = max( $largest, $fsize ); + if( $fsize > $max ){ + $nskip += 1; + // uncomment to log which files are too large to be scanned + // Loco_error_AdminNotices::debug( sprintf('%s is %s',$sourceFile,Loco_mvc_FileParams::renderBytes($fsize)) ); + } + else { + $bytes += $fsize; + } + } + $this->set( 'scan', new Loco_mvc_ViewParams( array ( + 'bytes' => $bytes, + 'count' => $nfiles, + 'skip' => $nskip, + 'size' => Loco_mvc_FileParams::renderBytes($bytes), + 'large' => Loco_mvc_FileParams::renderBytes($max), + 'largest' => Loco_mvc_FileParams::renderBytes($largest), + ) ) ); + + // file metadata + $this->set('pot', Loco_mvc_FileParams::create( $pot ) ); + $this->set('dir', Loco_mvc_FileParams::create( $dir ) ); + + $title = __('New template file','loco-translate'); + $subhead = sprintf( __('New translations template for "%s"','loco-translate'), $project ); + $this->set('subhead', $subhead ); + + // navigate up to bundle listing page + $breadcrumb->add( $title ); + $this->set( 'breadcrumb', $breadcrumb ); + + // ajax service takes the target directory path + $content_dir = loco_constant('WP_CONTENT_DIR'); + $target_path = $pot->getParent()->getRelativePath($content_dir); + + // hidden fields to pass through to Ajax endpoint + $this->set( 'hidden', new Loco_mvc_ViewParams( array( + 'action' => 'loco_json', + 'route' => 'xgettext', + 'loco-nonce' => $this->setNonce('xgettext')->value, + 'type' => $bundle->getType(), + 'bundle' => $bundle->getHandle(), + 'domain' => $project->getId(), + 'path' => $target_path, + 'name' => $pot->basename(), + ) ) ); + + // File system connect required if location not writable + $relpath = $pot->getRelativePath($content_dir); + $this->prepareFsConnect('create', $relpath ); + + $this->enqueueScript('potinit'); + return $this->view( 'admin/init/init-pot' ); + } + + + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/list/BaseController.php b/vendor/loco-translate/src/admin/list/BaseController.php new file mode 100644 index 0000000..cfc2d77 --- /dev/null +++ b/vendor/loco-translate/src/admin/list/BaseController.php @@ -0,0 +1,86 @@ +getHandle(); + // compatibility will be 'ok', 'warn' or 'error' depending on severity + if( $default = $bundle->getDefaultProject() ){ + $compat = $default->getPot() instanceof Loco_fs_File; + } + else { + $compat = false; + } + //$info = $bundle->getHeaderInfo(); + return new Loco_mvc_ViewParams( array ( + 'id' => $bundle->getId(), + 'name' => $bundle->getName(), + 'dflt' => $default ? $default->getDomain() : '--', + 'size' => count( $bundle ), + 'save' => $bundle->isConfigured(), + 'type' => $type = strtolower( $bundle->getType() ), + 'view' => Loco_mvc_AdminRouter::generate( $type.'-view', array( 'bundle' => $handle ) ), + 'time' => $bundle->getLastUpdated(), + ) ); + } + + + /** + * Add bundle to enabled or disabled list, depending on whether it is configured + */ + protected function addBundle( Loco_package_Bundle $bundle ){ + $this->bundles[] = $this->bundleParam($bundle); + } + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-list-bundles'), + ); + } + + + /** + * {@inheritdoc} + */ + public function render(){ + + // breadcrumb is just the root + $here = new Loco_admin_Navigation( array ( + new Loco_mvc_ViewParams( array( 'name' => $this->get('title') ) ), + ) ); + + /*/ tab between the types of bundles + $types = array ( + '' => __('Home','loco-translate'), + 'theme' => __('Themes','loco-translate'), + 'plugin' => __('Plugins','loco-translate'), + ); + $current = $this->get('_route'); + $tabs = new Loco_admin_Navigation; + foreach( $types as $type => $name ){ + $href = Loco_mvc_AdminRouter::generate($type); + $tabs->add( $name, $href, $type === $current ); + } + */ + + return $this->view( 'admin/list/bundles', array ( + 'bundles' => $this->bundles, + 'breadcrumb' => $here, + ) ); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/list/CoreController.php b/vendor/loco-translate/src/admin/list/CoreController.php new file mode 100644 index 0000000..4612754 --- /dev/null +++ b/vendor/loco-translate/src/admin/list/CoreController.php @@ -0,0 +1,16 @@ + loco-core-view + */ +class Loco_admin_list_CoreController extends Loco_admin_RedirectController { + + + /** + * {@inheritdoc} + */ + public function getLocation(){ + return Loco_mvc_AdminRouter::generate('core-view'); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/list/LocalesController.php b/vendor/loco-translate/src/admin/list/LocalesController.php new file mode 100644 index 0000000..2260ff0 --- /dev/null +++ b/vendor/loco-translate/src/admin/list/LocalesController.php @@ -0,0 +1,109 @@ +enqueueStyle('locale'); + } + + + + /** + * {@inheritdoc} + */ + public function getHelpTabs(){ + return array ( + __('Overview','default') => $this->viewSnippet('tab-list-locales'), + ); + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $this->set( 'title', __( 'Installed languages', 'loco-translate' ) ); + + $used = array(); + $locales = array(); + $api = new Loco_api_WordPressTranslations; + + $active = get_locale(); + + // list which sites have each language as their WPLANG setting + if( $multisite = is_multisite() ){ + $this->set('multisite',true); + /* @var WP_Site $site */ + foreach( get_sites() as $site ){ + $id = (int) $site->blog_id; + $tag = get_blog_option( $id, 'WPLANG') or $tag = 'en_US'; + $name = get_blog_option( $id, 'blogname' ); + $used[$tag][] = $name; + } + } + // else single site shows tick instead of site name + else { + $used[$active][] = '✓'; + } + + // add installed languages to file crawler + $finder = new Loco_package_Locale; + + // Pull "installed" languages (including en_US) + foreach( $api->getInstalledCore() as $tag ){ + $locale = Loco_Locale::parse($tag); + if( $locale->isValid() ){ + $tag = (string) $locale; + $finder->addLocale($locale); + $args = array( 'locale' => $tag ); + $locales[$tag] = new Loco_mvc_ViewParams( array( + 'nfiles' => 0, + 'time' => 0, + 'lcode' => $tag, + 'lname' => $locale->ensureName($api), + 'lattr' => 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"', + 'href' => Loco_mvc_AdminRouter::generate('lang-view',$args), + 'used' => isset($used[$tag]) ? implode( ', ', $used[$tag] ) : ( $multisite ? '--' : '' ), + 'active' => $active === $tag, + ) ); + } + } + $this->set('locales', $locales ); + + + // Count up unique PO files + foreach( $finder->findLocaleFiles() as $file ){ + if( preg_match('/(?:^|-)([_a-zA-Z]+).po$/', $file->basename(), $r ) ){ + $locale = Loco_Locale::parse($r[1]); + if( $locale->isValid() ){ + $tag = (string) $locale; + $locales[$tag]['nfiles']++; + $locales[$tag]['time'] = max( $locales[$tag]['time'], $file->modified() ); + } + } + } + + // POT files are in en_US locale + $tag = 'en_US'; + foreach( $finder->findTemplateFiles() as $file ){ + $locales[$tag]['nfiles']++; + $locales[$tag]['time'] = max( $locales[$tag]['time'], $file->modified() ); + } + + + return $this->view( 'admin/list/locales' ); + + } + + +} diff --git a/vendor/loco-translate/src/admin/list/PluginsController.php b/vendor/loco-translate/src/admin/list/PluginsController.php new file mode 100644 index 0000000..12d63da --- /dev/null +++ b/vendor/loco-translate/src/admin/list/PluginsController.php @@ -0,0 +1,31 @@ +set( 'type', 'plugin' ); + $this->set( 'title', __( 'Translate plugins', 'loco-translate' ) ); + + foreach( Loco_package_Plugin::get_plugins() as $handle => $data ){ + try { + $bundle = Loco_package_Plugin::create( $handle ); + $this->addBundle($bundle); + } + // @codeCoverageIgnoreStart + catch( Exception $e ){ + $bundle = new Loco_package_Plugin( $handle, $handle ); + $this->addBundle( $bundle ); + } + // @codeCoverageIgnoreEnd + } + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/admin/list/ThemesController.php b/vendor/loco-translate/src/admin/list/ThemesController.php new file mode 100644 index 0000000..9cf0060 --- /dev/null +++ b/vendor/loco-translate/src/admin/list/ThemesController.php @@ -0,0 +1,26 @@ +set('type', 'theme' ); + $this->set('title', __( 'Translate themes', 'loco-translate' ) ); + + /* @var $theme WP_Theme */ + foreach( wp_get_themes() as $theme ){ + $bundle = Loco_package_Theme::create( $theme->get_stylesheet() ); + $this->addBundle( $bundle ); + } + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/ApisController.php b/vendor/loco-translate/src/ajax/ApisController.php new file mode 100644 index 0000000..7dc3921 --- /dev/null +++ b/vendor/loco-translate/src/ajax/ApisController.php @@ -0,0 +1,67 @@ +validate(); + + // Fire an event so translation apis can register their hooks as lazily as possible + do_action('loco_api_ajax'); + + // API client id should be posted + $hook = (string) $post->hook; + + // API client must be hooked in using loco_api_providers filter + // this normally filters on Loco_api_Providers::export() but should do the same with an empty array. + $config = null; + foreach( apply_filters('loco_api_providers', array() ) as $candidate ){ + if( is_array($candidate) && array_key_exists('id',$candidate) && $candidate['id'] === $hook ){ + $config = $candidate; + break; + } + } + if( is_null($config) ){ + throw new Loco_error_Exception('API not registered: '.$hook ); + } + + // Get input texts to translate via registered hook. shouldn't be posted if empty. + $sources = $post->sources; + if( ! is_array($sources) || ! $sources ){ + throw new Loco_error_Exception('Empty sources posted to '.$hook.' hook'); + } + + // The front end sends translations detected as HTML separately. This is to support common external apis. + // $isHtml = 'html' === $post->type; + + // We need a locale too, which should be valid as it's the same one loaded into the front end. + $locale = Loco_Locale::parse( (string) $post->locale ); + if( ! $locale->isValid() ){ + throw new Loco_error_Exception('Invalid locale'); + } + + // Check if hook is registered, else sources will be returned as-is + $action = 'loco_api_translate_'.$hook; + if( ! has_filter($action) ){ + throw new Loco_error_Exception('API not hooked. Use `add_filter('.var_export($action,1).',...)`'); + } + + // This is effectively a filter whereby the returned array should be a translation of the input array + // TODO might be useful for translation hooks to know the PO file this comes from + $targets = apply_filters( $action, $sources, $locale, $config ); + if( count($targets) !== count($sources) ){ + Loco_error_AdminNotices::warn('Number of translations does not match number of source strings'); + } + + // Response data doesn't need anything except the translations + $this->set('targets',$targets); + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/DiffController.php b/vendor/loco-translate/src/ajax/DiffController.php new file mode 100644 index 0000000..0036e9a --- /dev/null +++ b/vendor/loco-translate/src/ajax/DiffController.php @@ -0,0 +1,58 @@ +validate(); + + // require x2 valid files for diffing + if( ! $post->lhs || ! $post->rhs ){ + throw new InvalidArgumentException('Path parameters required'); + } + + $dir = loco_constant('WP_CONTENT_DIR'); + $lhs = new Loco_fs_File( $post->lhs ); $lhs->normalize($dir); + $rhs = new Loco_fs_File( $post->rhs ); $rhs->normalize($dir); + + // avoid diffing non Gettext source files + $exts = array_flip( array( 'pot', 'pot~', 'po', 'po~' ) ); + + /* @var $file Loco_fs_File */ + foreach( array($lhs,$rhs) as $file ){ + if( ! $file->exists() ){ + throw new InvalidArgumentException('File paths must exist'); + } + if( ! $file->underContentDirectory() ){ + throw new InvalidArgumentException('Files must be under '.basename($dir) ); + } + $ext = $file->extension(); + if( ! isset($exts[$ext]) ){ + throw new InvalidArgumentException('Disallowed file extension'); + } + } + + // OK to diff files as HTML table + $renderer = new Loco_output_DiffRenderer; + $emptysrc = $renderer->_startDiff().$renderer->_endDiff(); + $tablesrc = $renderer->renderFiles( $rhs, $lhs ); + + if( $tablesrc === $emptysrc ){ + // translators: Where %s is a file name + $message = __('Revisions are identical, you can delete %s','loco-translate'); + $this->set( 'error', sprintf( $message, $rhs->basename() ) ); + } + else { + $this->set( 'html', $tablesrc ); + } + + return parent::render(); + } + + +} diff --git a/vendor/loco-translate/src/ajax/DownloadConfController.php b/vendor/loco-translate/src/ajax/DownloadConfController.php new file mode 100644 index 0000000..1b6d9c8 --- /dev/null +++ b/vendor/loco-translate/src/ajax/DownloadConfController.php @@ -0,0 +1,35 @@ +validate(); + $bundle = $this->getBundle(); + + $file = new Loco_fs_File( $this->get('path') ); + // TODO should we download axtual loco.xml file if bundle is configured from it? + //$file->normalize( $bundle->getDirectoryPath() ); + //if( $file->exists() ){} + + $writer = new Loco_config_BundleWriter($bundle); + + switch( $file->extension() ){ + case 'xml': + return $writer->toXml(); + case 'json': + return json_encode( $writer->jsonSerialize() ); + } + + // @codeCoverageIgnoreStart + throw new Loco_error_Exception('Specify either XML or JSON file path'); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/DownloadController.php b/vendor/loco-translate/src/ajax/DownloadController.php new file mode 100644 index 0000000..f4bf538 --- /dev/null +++ b/vendor/loco-translate/src/ajax/DownloadController.php @@ -0,0 +1,59 @@ +validate(); + + // we need a path, but it may not need to exist + $file = new Loco_fs_File( $this->get('path') ); + $file->normalize( loco_constant( 'WP_CONTENT_DIR') ); + $is_binary = 'mo' === strtolower( $file->extension() ); + + // posted source must be clean and must parse as whatever the file extension claims to be + if( $raw = $post->source ){ + // compile source if target is MO + if( $is_binary ) { + $raw = Loco_gettext_Data::fromSource($raw)->msgfmt(); + } + } + // else file can be output directly if it exists. + // note that files on disk will not be parsed or manipulated. they will download strictly as-is + else if( $file->exists() ){ + $raw = $file->getContents(); + } + /*/ else if PO exists but MO doesn't, we can compile it on the fly + else if( ! $is_binary ){ + + }*/ + else { + throw new Loco_error_Exception('File not found and no source posted'); + } + + // Observe UTF-8 BOM setting + if( ! $is_binary ){ + $has_bom = "\xEF\xBB\xBF" === substr($raw,0,3); + $use_bom = (bool) Loco_data_Settings::get()->po_utf8_bom; + // only alter file if valid UTF-8. Deferring detection overhead until required + if( $has_bom !== $use_bom && 'UTF-8' === mb_detect_encoding( $raw, array('UTF-8','ISO-8859-1'), true ) ){ + if( $use_bom ){ + $raw = "\xEF\xBB\xBF".$raw; // prepend + } + else { + $raw = substr($raw,3); // strip bom + } + } + } + + + return $raw; + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/FsConnectController.php b/vendor/loco-translate/src/ajax/FsConnectController.php new file mode 100644 index 0000000..d85abe0 --- /dev/null +++ b/vendor/loco-translate/src/ajax/FsConnectController.php @@ -0,0 +1,151 @@ +expand() as $file ){ + if( ! $this->api->authorizeDelete($file) ){ + return false; + } + } + // else no dependants failed deletable test + return true; + } + + + /** + * @param Loco_fs_File file being moved (must exist) + * @param Loco_fs_File target path (should not exist) + * @return bool + */ + private function authorizeMove( Loco_fs_File $source, Loco_fs_File $target = null ){ + return $this->api->authorizeMove($source,$target); + } + + + /** + * @param Loco_fs_File new file path (should not exist) + * @return bool + */ + private function authorizeCreate( Loco_fs_File $file ){ + return $this->api->authorizeCreate($file); + } + + + /** + * @return bool + */ + private function authorizeUpdate( Loco_fs_File $file ){ + if( ! $this->api->authorizeUpdate($file) ){ + return false; + } + // if backups are enabled, we need to be able to create new files too (i.e. update parent directory) + if( Loco_data_Settings::get()->num_backups && ! $this->api->authorizeCopy($file) ){ + return false; + } + // updating file may also recompile binary, which may or may not exist + $files = new Loco_fs_Siblings( $file ); + if( $file = $files->getBinary() ){ + return $this->api->authorizeSave($file); + } + // else no dependants to update + return true; + } + + + /** + * {@inheritdoc} + */ + public function render(){ + // establish operation being authorized (create,delete,etc..) + $post = $this->validate(); + $type = $post->auth; + $func = 'authorize'.ucfirst($type); + $auth = array( $this, $func ); + if( ! is_callable($auth) ){ + throw new Loco_error_Exception('Unexpected file operation'); + } + // all auth methods require at least one file argument + $file = new Loco_fs_File( $post->path ); + $base = loco_constant('WP_CONTENT_DIR'); + $file->normalize($base); + $args = array($file); + // some auth methods also require a destination/target (move,copy,etc..) + if( $dest = $post->dest ){ + $file = new Loco_fs_File($dest); + $file->normalize($base); + $args[] = $file; + } + // call auth method and respond with status and prompt HTML if connect required + try { + $this->api = new Loco_api_WordPressFileSystem; + if( call_user_func_array($auth,$args) ){ + $this->set( 'authed', true ); + $this->set( 'valid', $this->api->getOutputCredentials() ); + $this->set( 'creds', $this->api->getInputCredentials() ); + $this->set( 'method', $this->api->getFileSystem()->method ); + $this->set( 'success', __('Connected to remote file system','loco-translate') ); + // warning when writing to this location is risky (overwrites during wp update) + if( Loco_data_Settings::get()->fs_protect && $file->getUpdateType() ){ + if( 'create' === $type ){ + $message = __('This file may be overwritten or deleted when you update WordPress','loco-translate'); + } + else if( 'delete' === $type ){ + $message = __('This directory is managed by WordPress, be careful what you delete','loco-translate'); + } + else if( 'move' === $type ){ + $message = __('This directory is managed by WordPress. Removed files may be restored during updates','loco-translate'); + } + else { + $message = __('Changes to this file may be overwritten or deleted when you update WordPress','loco-translate'); + } + $this->set('warning',$message); + } + } + else if( $html = $this->api->getForm() ){ + $this->set( 'authed', false ); + $this->set( 'prompt', $html ); + // supporting text based on file operation type explains why auth is required + if( 'create' === $type ){ + $message = __('Creating this file requires permission','loco-translate'); + } + else if( 'delete' === $type ){ + $message = __('Deleting this file requires permission','loco-translate'); + } + else if( 'move' === $type ){ + $message = __('This move operation requires permission','loco-translate'); + } + else { + $message = __('Saving this file requires permission','loco-translate'); + } + // message is printed before default text, so needs delimiting. + $this->set('message',$message.'.'); + } + else { + throw new Loco_error_Exception('Failed to get credentials form'); + } + } + catch( Loco_error_WriteException $e ){ + $this->set('authed', false ); + $this->set('reason', $e->getMessage() ); + } + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/FsReferenceController.php b/vendor/loco-translate/src/ajax/FsReferenceController.php new file mode 100644 index 0000000..2ae2bb8 --- /dev/null +++ b/vendor/loco-translate/src/ajax/FsReferenceController.php @@ -0,0 +1,198 @@ +exists() ){ + return $srcfile; + } + }*/ + + // reference may be resolvable via referencing PO file's location + $pofile = new Loco_fs_File( $this->get('path') ); + $pofile->normalize( loco_constant('WP_CONTENT_DIR') ); + if( ! $pofile->exists() ){ + throw new InvalidArgumentException('PO/POT file required to resolve reference'); + } + $search = new Loco_gettext_SearchPaths; + $search->init($pofile); + if( $srcfile = $search->match($refpath) ){ + return $srcfile; + } + + // check against PO file location when no search paths or search paths failed + $srcfile = new Loco_fs_File($refpath); + $srcfile->normalize( $pofile->dirname() ); + if( $srcfile->exists() ){ + return $srcfile; + } + + // reference may be resolvable via known project roots + try { + $bundle = $this->getBundle(); + // Loco extractions will always be relative to bundle root + $srcfile = new Loco_fs_File( $refpath ); + $srcfile->normalize( $bundle->getDirectoryPath() ); + if( $srcfile->exists() ){ + return $srcfile; + } + + // check relative to parent theme root + if( $bundle->isTheme() && ( $parent = $bundle->getParent() ) ){ + $srcfile = new Loco_fs_File( $refpath ); + $srcfile->normalize( $parent->getDirectoryPath() ); + if( $srcfile->exists() ){ + return $srcfile; + } + } + + // final attempt - search all project source roots + // TODO is there too large a risk of false positives? especially with files like index.php + /* @var $root Loco_fs_Directory */ + /*foreach( $this->getProject($bundle)->getConfiguredSources() as $root ){ + if( $root->isDirectory() ){ + $srcfile = new Loco_fs_File( $refpath ); + $srcfile->normalize( $root->getPath() ); + if( $srcfile->exists() ){ + return $srcfile; + } + } + }*/ + } + catch( Loco_error_Exception $e ){ + // permitted for there to be no bundle or project when viewing orphaned file + } + + throw new Loco_error_Exception( sprintf('Failed to find source file matching "%s"',$refpath) ); + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + $post = $this->validate(); + + // at the very least we need a reference to examine + if( ! $post->has('ref') ){ + throw new InvalidArgumentException('ref parameter required'); + } + + // reference must parse as : + $ref = $post->ref; + if( ! preg_match('/^(.+):(\\d+)$/', $ref, $r ) ){ + throw new InvalidArgumentException('Invalid file reference, '.$ref ); + } + + // find file or fail + list( , $refpath, $refline ) = $r; + $srcfile = $this->findSourceFile($refpath); + + // deny access to sensitive files + if( 'wp-config.php' === $srcfile->basename() ){ + throw new InvalidArgumentException('File access disallowed'); + } + + // validate allowed source file types + $conf = Loco_data_Settings::get(); + $ext = strtolower( $srcfile->extension() ); + $allow = array_merge( array('php','js'), $conf->php_alias, $conf->jsx_alias ); + if( ! in_array($ext,$allow,true) ){ + throw new InvalidArgumentException('File extension disallowed, '.$ext ); + } + + // get file type from registered file extensions: + $type = $conf->ext2type( $ext ); + + $this->set('type', $type ); + $this->set('line', (int) $refline ); + $this->set('path', $srcfile->getRelativePath( loco_constant('WP_CONTENT_DIR') ) ); + + // source code will be HTML-tokenized into multiple lines + $code = array(); + + // observe the same size limits for source highlighting as for string extraction as tokenizing will use the same amount of juice + $maxbytes = wp_convert_hr_to_bytes( $conf->max_php_size ); + + // tokenizers require gettext utilities, easiest just to ping the extraction library + if( ! class_exists('Loco_gettext_Extraction',true) ){ + throw new RuntimeException('Failed to load tokenizers'); // @codeCoverageIgnore + } + + // PHP is the most likely format. + if( 'php' === $type && ( $srcfile->size() <= $maxbytes ) && loco_check_extension('tokenizer') ) { + $tokens = new LocoPHPTokens( token_get_all( $srcfile->getContents() ) ); + } + else if( 'js' === $type ){ + $tokens = new LocoJsTokens( $srcfile->getContents() ); + } + else { + $tokens = null; + } + + // highlighting on back end because tokenizer provides more control than highlight.js + if( $tokens instanceof LocoTokensInterface ){ + $thisline = 1; + while( $tok = $tokens->advance() ){ + if( is_array($tok) ){ + // line numbers added in PHP 5.2.2 - WordPress minimum is 5.2.4 + list( $t, $str, $startline ) = $tok; + $clss = token_name($t); + // tokens can span multiple lines (whitespace/html/comments) + $lines = preg_split('/\\R/', $str ); + } + else { + // scalar symbol will always start on the line that the previous token ended on + $clss = 'T_NONE'; + $lines = array( $tok ); + $startline = $thisline; + } + // token can span multiple lines, so include only bytes on required line[s] + foreach( $lines as $i => $line ){ + $thisline = $startline + $i; + $html = ''.htmlentities($line,ENT_COMPAT,'UTF-8').''; + // append highlighted token to current line + $j = $thisline - 1; + if( isset($code[$j]) ){ + $code[$j] .= $html; + } + else { + $code[$j] = $html; + } + } + } + } + // permit limited other file types, but without back end highlighting + else if( 'js' === $type || 'twig' === $type || 'php' === $type ){ + foreach( preg_split( '/\\R/u', $srcfile->getContents() ) as $line ){ + $code[] = ''.htmlentities($line,ENT_COMPAT,'UTF-8').''; + } + } + else { + throw new Loco_error_Exception( sprintf('%s source view not supported', $type) ); // @codeCoverageIgnore + } + + if( ! isset($code[$refline-1]) ){ + throw new Loco_error_Exception( sprintf('Line %u not in source file', $refline) ); + } + + $this->set( 'code', $code ); + + return parent::render(); + } + + +} diff --git a/vendor/loco-translate/src/ajax/MsginitController.php b/vendor/loco-translate/src/ajax/MsginitController.php new file mode 100644 index 0000000..b122b58 --- /dev/null +++ b/vendor/loco-translate/src/ajax/MsginitController.php @@ -0,0 +1,132 @@ +get('use-selector') ){ + $tag = $this->get('select-locale'); + } + else { + $tag = $this->get('custom-locale'); + } + $locale = Loco_Locale::parse($tag); + if( ! $locale->isValid() ){ + throw new Loco_error_LocaleException('Invalid locale'); + } + return $locale; + } + + + + /** + * {@inheritdoc} + */ + public function render(){ + + $post = $this->validate(); + $bundle = $this->getBundle(); + $project = $this->getProject( $bundle ); + $domain = (string) $project->getDomain(); + $locale = $this->getLocale(); + $suffix = (string) $locale; + + // The front end posts a template path, so we must replace the actual locale code + $base = loco_constant('WP_CONTENT_DIR'); + $path = $post->path[ $post['select-path'] ]; + // The request_filesystem_credentials function will try to access the "path" field later + $_POST['path'] = $path; + + $pofile = new Loco_fs_LocaleFile( $path ); + if( $suffix !== $pofile->getSuffix() ){ + $pofile = $pofile->cloneLocale( $locale ); + if( $suffix !== $pofile->getSuffix() ){ + throw new Loco_error_Exception('Failed to suffix file path with locale code'); + } + } + + // target PO should not exist yet + $pofile->normalize( $base ); + $api = new Loco_api_WordPressFileSystem; + $api->authorizeCreate( $pofile ); + + // Target MO probably doesn't exist, but we don't want to overwrite it without asking + $mofile = $pofile->cloneExtension('mo'); + if( $mofile->exists() ){ + throw new Loco_error_Exception( __('MO file exists for this language already. Delete it first','loco-translate') ); + } + + /*/ Same for JSON file, but WordPress >= only 5 + $jsfile = function_exists('wp_set_script_translations') ? $pofile->cloneExtension('json') : null; + if( $jsfile && $jsfile->exists() ){ + throw new Loco_error_Exception( __('JSON file exists for this language already. Delete it first','loco-translate') ); + }*/ + + // Permit forcing of any parsable file as strings template + if( $source = $post->source ){ + $potfile = new Loco_fs_File( $source ); + $potfile->normalize( $base ); + $data = Loco_gettext_Data::load($potfile); + // Remove target strings when copying PO + if( $post->strip ){ + $data->strip(); + } + } + // else parse POT file if project defines one that exists + else if( ( $potfile = $project->getPot() ) && $potfile->exists() ){ + $data = Loco_gettext_Data::load($potfile); + } + // else extract directly from source code, assuming domain passed though from front end + else { + $extr = new Loco_gettext_Extraction( $bundle ); + $data = $extr->addProject($project)->includeMeta()->getTemplate($domain); + $potfile = null; + } + + // Let template define Project-Id-Version, else set header to current project name + $headers = array(); + $vers = $data->getHeaders()->{'Project-Id-Version'}; + if( ! $vers || 'PACKAGE VERSION' === $vers ){ + $headers['Project-Id-Version'] = $project->getName(); + } + // relative path from bundle root to the template/source this file was created from + if( $potfile && $post->link ){ + $headers['X-Loco-Template'] = $potfile->getRelativePath( $bundle->getDirectoryPath() ); + } + + $data->localize( $locale, $headers ); + + $posize = $pofile->putContents( $data->msgcat() ); + $mosize = $mofile->putContents( $data->msgfmt() ); + //$jssize = $jsfile && ( $sub = $data->splitJs() ) ? $jsfile->putContents($data->jedize($domain,$sub)) : 0; + + // set debug response data + $this->set( 'debug', array ( + 'poname' => $pofile->basename(), + 'posize' => $posize, + 'mosize' => $mosize, + //'jssize' => $jssize, + 'source' => $potfile ? $potfile->basename() : '', + ) ); + + // push recent items on file creation + // TODO push project and locale file + Loco_data_RecentItems::get()->pushBundle( $bundle )->persist(); + + // front end will redirect to the editor + $type = strtolower( $this->get('type') ); + $this->set( 'redirect', Loco_mvc_AdminRouter::generate( sprintf('%s-file-edit',$type), array ( + 'path' => $pofile->getRelativePath($base), + 'bundle' => $bundle->getHandle(), + 'domain' => $project->getId(), + ) ) ); + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/PingController.php b/vendor/loco-translate/src/ajax/PingController.php new file mode 100644 index 0000000..ec90837 --- /dev/null +++ b/vendor/loco-translate/src/ajax/PingController.php @@ -0,0 +1,28 @@ +validate(); + // echo back bytes posted + if( $post->has('echo') ){ + $this->set( 'ping', $post['echo'] ); + } + // else just send pong + else { + $this->set( 'ping', 'pong' ); + } + // always send tick symbol to check json serializing of unicode + $this->set( 'utf8', "\xE2\x9C\x93" ); + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/SaveController.php b/vendor/loco-translate/src/ajax/SaveController.php new file mode 100644 index 0000000..d45b249 --- /dev/null +++ b/vendor/loco-translate/src/ajax/SaveController.php @@ -0,0 +1,165 @@ +validate(); + + // path parameter must not be empty + $path = $post->path; + if( ! $path ){ + throw new InvalidArgumentException('Path parameter required'); + } + + // locale must be posted to indicate whether PO or POT + $locale = $post->locale; + if( is_null($locale) ){ + throw new InvalidArgumentException('Locale parameter required'); + } + + $pofile = new Loco_fs_LocaleFile( $path ); + $pofile->normalize( loco_constant('WP_CONTENT_DIR') ); + $poexists = $pofile->exists(); + + // ensure we only deal with PO/POT source files. + // posting of MO file paths is permitted when PO is missing, but we're about to fix that + $ext = $pofile->extension(); + if( 'mo' === $ext ){ + $pofile = $pofile->cloneExtension('po'); + } + else if( 'pot' === $ext ){ + $locale = ''; + } + else if( 'po' !== $ext ){ + throw new Loco_error_Exception('Invalid file path'); + } + + // force the use of remote file system when configured from front end + $api = new Loco_api_WordPressFileSystem; + + // data posted may be either 'multipart/form-data' (recommended for large files) + if( isset($_FILES['po']) ){ + $data = Loco_gettext_Data::fromSource( Loco_data_Upload::src('po') ); + } + // else 'application/x-www-form-urlencoded' by default + else { + $data = Loco_gettext_Data::fromSource( $post->data ); + } + + // WordPress-ize some headers that differ from JavaScript libs + if( $compile = (bool) $locale ){ + $head = $data->getHeaders(); + $head['Language'] = strtr( $locale, '-', '_' ); + } + + // backup existing file before overwriting, but still allow if backups fails + $num_backups = Loco_data_Settings::get()->num_backups; + if( $num_backups && $poexists ){ + try { + $api->authorizeCopy( $pofile ); + $backups = new Loco_fs_Revisions( $pofile ); + $backups->create(); + $backups->prune($num_backups); + } + catch( Exception $e ){ + Loco_error_AdminNotices::debug( $e->getMessage() ); + $message = __('Failed to create backup file in "%s". Check file permissions or disable backups','loco-translate'); + Loco_error_AdminNotices::warn( sprintf( $message, $pofile->getParent()->basename() ) ); + } + } + + // commit file directly to disk + $api->authorizeSave( $pofile ); + $bytes = $pofile->putContents( $data->msgcat() ); + $mtime = $pofile->modified(); + + // add bundle to recent items on file creation + try { + $bundle = $this->getBundle(); + Loco_data_RecentItems::get()->pushBundle( $bundle )->persist(); + } + catch( Exception $e ){ + // editor permitted to save files not in a bundle, so catching failures + $bundle = null; + } + + // start success data with bytes written and timestamp + $this->set('locale', $locale ); + $this->set('pobytes', $bytes ); + $this->set('poname', $pofile->basename() ); + $this->set('modified', $mtime); + $this->set('datetime', Loco_mvc_ViewParams::date_i18n($mtime) ); + + // Compile MO and JSON files unless saving template + if( $compile ){ + try { + $mofile = $pofile->cloneExtension('mo'); + $api->authorizeSave( $mofile ); + $bytes = $mofile->putContents( $data->msgfmt() ); + $this->set( 'mobytes', $bytes ); + Loco_error_AdminNotices::success( __('PO file saved and MO file compiled','loco-translate') ); + + } + catch( Exception $e ){ + Loco_error_AdminNotices::debug( $e->getMessage() ); + Loco_error_AdminNotices::warn( __('PO file saved, but MO file compilation failed','loco-translate') ); + $this->set( 'mobytes', 0 ); + // prevent further compilation if MO failed + $compile = false; + } + } + else { + Loco_error_AdminNotices::success( __('POT file saved','loco-translate') ); + } + + /*/ Compile JSON translations for WordPress >= 5 + if( $compile && $bundle && function_exists('wp_set_script_translations') ){ + $bytes = 0; + try { + list($domain) = Loco_package_Project::splitId( $this->get('domain') ); + + // hash file reference according to WordPress logic (see load_script_textdomain) + $base = $pofile->dirname().'/'.$pofile->filename(); + foreach( $data->exportRefs('\\.jsx?') as $ref => $messages ){ + if( '.min.js' === substr($ref,-7) ) { + $ref = substr($ref,0,-7).'.js'; + } + // filter similarly to WP's `load_script_textdomain_relative_path` which is called from `load_script_textdomain` + $ref = apply_filters( 'loco_script_relative_path', $ref, $domain ); + // referenced file must exist in bundle, or will never be loaded and so not require a .json file + $file = new Loco_fs_File( $bundle->getDirectoryPath().'/'.$ref ); + if( $file->exists() && ! $file->isDirectory() ){ + $file = new Loco_fs_File( $base.'-'.md5($ref).'.json' ); + $api->authorizeSave( $file ); + $bytes += $file->putContents( $data->jedize($domain,$messages) ); + } + else { + Loco_error_AdminNotices::warn( sprintf('%s not found in bundle',$ref) ); + } + } + + // single JSON file containing all .js ref from this file + if( $messages = $data->splitJs() ){ + $file = $pofile->cloneExtension('json'); + $api->authorizeSave( $file ); + $bytes = $file->putContents( $data->jedize($domain,$messages) ); + } + } + catch( Exception $e ){ + Loco_error_AdminNotices::debug( $e->getMessage() ); + Loco_error_AdminNotices::warn( __('JSON compilation failed','loco-translate') ); + } + $this->set( 'jsbytes', $bytes ); + }*/ + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/SyncController.php b/vendor/loco-translate/src/ajax/SyncController.php new file mode 100644 index 0000000..d7dfe10 --- /dev/null +++ b/vendor/loco-translate/src/ajax/SyncController.php @@ -0,0 +1,77 @@ +validate(); + + $bundle = Loco_package_Bundle::fromId( $post->bundle ); + $project = $bundle->getProjectById( $post->domain ); + if( ! $project instanceof Loco_package_Project ){ + throw new Loco_error_Exception('No such project '.$post->domain); + } + + $file = new Loco_fs_File( $post->path ); + $base = loco_constant('WP_CONTENT_DIR'); + $file->normalize( $base ); + + // POT file always synced with source code (even if a PO being used as POT) + if( 'pot' === $post->type ){ + $potfile = null; + } + // allow post data to force a template file path + else if( $path = $post->sync ){ + $potfile = new Loco_fs_File($path); + $potfile->normalize( $base ); + } + // else use project-configured template if one is defined + else { + $potfile = $project->getPot(); + } + + // sync with POT if it exists + if( $potfile && $potfile->exists() ){ + $this->set('pot', $potfile->basename() ); + try { + $data = Loco_gettext_Data::load($potfile); + } + catch( Exception $e ){ + // translators: Where %s is the name of the invalid POT file + throw new Loco_error_ParseException( sprintf( __('Translation template is invalid (%s)','loco-translate'), $potfile->basename() ) ); + } + } + // else sync with source code + else { + $this->set('pot', '' ); + $domain = (string) $project->getDomain(); + $extr = new Loco_gettext_Extraction($bundle); + $extr->addProject($project); + // bail if any files were skipped + if( $list = $extr->getSkipped() ){ + $n = count($list); + $maximum = Loco_mvc_FileParams::renderBytes( wp_convert_hr_to_bytes( Loco_data_Settings::get()->max_php_size ) ); + $largest = Loco_mvc_FileParams::renderBytes( $extr->getMaxPhpSize() ); + // Translators: Where %2$s is the maximum size of a file that will be included and %3$s is the largest encountered + $text = _n('One file has been skipped because it\'s %3$s. (Max is %2$s). Check all strings are present before saving.','%s files over %2$s have been skipped. (Largest is %3$s). Check all strings are present before saving.',$n,'loco-translate'); + $text = sprintf( $text, number_format($n), $maximum, $largest ); + // not failing, just warning. Nothing will be saved until user saves editor state + Loco_error_AdminNotices::warn( $text ); + } + // OK to return available strings + $data = $extr->includeMeta()->getTemplate($domain); + } + + $this->set( 'po', $data->jsonSerialize() ); + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/XgettextController.php b/vendor/loco-translate/src/ajax/XgettextController.php new file mode 100644 index 0000000..c49f3ac --- /dev/null +++ b/vendor/loco-translate/src/ajax/XgettextController.php @@ -0,0 +1,81 @@ +validate(); + $bundle = $this->getBundle(); + $project = $this->getProject( $bundle ); + + // target location may not be next to POT file at all + $base = loco_constant('WP_CONTENT_DIR'); + $target = new Loco_fs_Directory( $this->get('path') ); + $target->normalize( $base ); + if( $target->exists() && ! $target->isDirectory() ){ + throw new Loco_error_Exception('Target is not a directory'); + } + + // basename should be posted from front end + $name = $this->get('name'); + if( ! $name ){ + throw new Loco_error_Exception('Front end did not post $name'); + } + + // POT file shouldn't exist currently + $potfile = new Loco_fs_File( $target.'/'.$name ); + $api = new Loco_api_WordPressFileSystem; + $api->authorizeCreate($potfile); + // Do extraction and grab only given domain's strings + $ext = new Loco_gettext_Extraction( $bundle ); + $domain = $project->getDomain()->getName(); + $data = $ext->addProject($project)->includeMeta()->getTemplate( $domain ); + + // additional headers to set in new POT file + $head = $data->getHeaders(); + $head['Project-Id-Version'] = $project->getName(); + + // write POT file to disk returning byte length + $potsize = $potfile->putContents( $data->msgcat(true) ); + + // set response data for debugging + if( loco_debugging() ){ + $this->set( 'debug', array ( + 'potname' => $potfile->basename(), + 'potsize' => $potsize, + 'total' => $ext->getTotal(), + ) ); + } + + // push recent items on file creation + // TODO push project and locale file + Loco_data_RecentItems::get()->pushBundle( $bundle )->persist(); + + // put flash message into session to be displayed on redirected page + try { + Loco_data_Session::get()->flash('success', __('Template file created','loco-translate') ); + Loco_data_Session::close(); + } + catch( Exception $e ){ + Loco_error_AdminNotices::debug( $e->getMessage() ); + } + + // redirect front end to bundle view. Discourages manual editing of template + $type = strtolower( $bundle->getType() ); + $href = Loco_mvc_AdminRouter::generate( sprintf('%s-view',$type), array( + 'bundle' => $bundle->getHandle(), + ) ); + $hash = '#loco-'.$project->getId(); + $this->set( 'redirect', $href.$hash ); + + return parent::render(); + } + + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/ajax/common/BundleController.php b/vendor/loco-translate/src/ajax/common/BundleController.php new file mode 100644 index 0000000..0c08d46 --- /dev/null +++ b/vendor/loco-translate/src/ajax/common/BundleController.php @@ -0,0 +1,39 @@ +get('bundle') ){ + // type may be passed as separate argument + if( $type = $this->get('type') ){ + return Loco_package_Bundle::createType( $type, $id ); + } + // else embedded in standalone bundle identifier + // TODO standardize this across all Ajax end points + return Loco_package_Bundle::fromId($id); + } + // else may have type embedded in bundle + throw new Loco_error_Exception('No bundle identifier posted'); + } + + + + /** + * @param Loco_package_Bundle + * @return Loco_package_Project + */ + protected function getProject( Loco_package_Bundle $bundle ){ + $project = $bundle->getProjectById( $this->get('domain') ); + if( ! $project ){ + throw new Loco_error_Exception('Failed to find translation project'); + } + return $project; + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/api/Providers.php b/vendor/loco-translate/src/api/Providers.php new file mode 100644 index 0000000..1e6f97f --- /dev/null +++ b/vendor/loco-translate/src/api/Providers.php @@ -0,0 +1,42 @@ + 'google', + 'name' => 'Google Translate', + 'key' => $settings->offsetGet('google_api_key'), + ), + array ( + 'id' => 'microsoft', + 'name' => 'Microsoft Translator', + 'key' => $settings->offsetGet('microsoft_api_key'), + 'region' => $settings->offsetGet('microsoft_api_region'), + ), + array ( + 'id' => 'yandex', + 'name' => 'Yandex.Translate', + 'key' => $settings->offsetGet('yandex_api_key'), + ), + ); + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/api/WordPressFileSystem.php b/vendor/loco-translate/src/api/WordPressFileSystem.php new file mode 100644 index 0000000..5f437ed --- /dev/null +++ b/vendor/loco-translate/src/api/WordPressFileSystem.php @@ -0,0 +1,409 @@ +form; + } + + + /** + * Pre-auth checks for superficial file system blocks and disconnects any active remotes + * @param Loco_fs_File + * @throws Loco_error_WriteException + * @return bool always true + */ + public function preAuthorize( Loco_fs_File $file ){ + if( ! $this->fs_allowed ){ + $file->getWriteContext()->authorize(); + $this->fs_allowed = true; + } + // Disconnecting remote file system ensures the auth functions always start with direct file access + $file->getWriteContext()->disconnect(); + return true; + } + + + /** + * Authorize for the creation of a file that does not exist + * @param Loco_fs_File + * @return bool whether file system is authorized NOT necessarily whether file is creatable + */ + public function authorizeCreate( Loco_fs_File $file ){ + $this->preAuthorize($file); + if( $file->exists() ){ + throw new Loco_error_WriteException( sprintf( __('%s already exists in this folder','loco-translate'), $file->basename() ) ); + } + return $file->creatable() || $this->authorize($file); + } + + + /** + * Authorize for the update of a file that does exist + * @param Loco_fs_File + * @return bool whether file system is authorized NOT necessarily whether file is updatable + */ + public function authorizeUpdate( Loco_fs_File $file ){ + $this->preAuthorize($file); + if( ! $file->exists() ){ + throw new Loco_error_WriteException("File doesn't exist, try authorizeCreate"); + } + return $file->writable() || $this->authorize($file); + } + + + /** + * Authorize for update or creation, depending whether file exists + * @param Loco_fs_File + * @return bool + */ + public function authorizeSave( Loco_fs_File $file ){ + $this->preAuthorize($file); + return ( $file->exists() ? $file->writable() : $file->creatable() ) || $this->authorize($file); + } + + + /** + * Authorize for copy (to same directory), meaning source file must exist and directory be writable + * @param Loco_fs_File + * @return bool + */ + public function authorizeCopy( Loco_fs_File $file ){ + $this->preAuthorize($file); + if( ! $file->exists() ){ + throw new Loco_error_WriteException("Can't copy a file that doesn't exist"); + } + return $file->creatable() || $this->authorize($file); + } + + + /** + * Authorize for move (to another path if given). + * @param Loco_fs_File file being moved (must exist) + * @param Loco_fs_File target path (should not exist) + * @return bool + */ + public function authorizeMove( Loco_fs_File $source, Loco_fs_File $target = null ){ + // source is in charge of its own deletion + $result = $this->authorizeDelete($source); + // target is in charge of copying original which it must also be able to read. + if( $target && ! $this->authorizeCreate($target) ){ + $result = false; + } + // value returned will be false if at least one file requires we add credentials + return $result; + } + + + /** + * Authorize for the removal of an existing file + * @param Loco_fs_File + * @return bool whether file system is authorized NOT necessarily whether file is removable + */ + public function authorizeDelete( Loco_fs_File $file ){ + $this->preAuthorize($file); + if( ! $file->exists() ){ + throw new Loco_error_WriteException("Can't delete a file that doesn't exist"); + } + return $file->deletable() || $this->authorize($file); + } + + + /** + * Connect file to credentials in posted data. Used when established in advance what connection is needed + * @param Loco_fs_File + * @return bool whether file system is authorized + */ + public function authorizeConnect( Loco_fs_File $file ){ + $this->preAuthorize($file); + // front end may have posted that "direct" connection will work + $post = Loco_mvc_PostParams::get(); + if( 'direct' === $post->connection_type ){ + return true; + } + return $this->authorize($file); + } + + + /** + * Wraps `request_filesystem_credentials` negotiation to obtain a remote connection and buffer WordPress form output + * Call before output started, because buffers. + * @param Loco_fs_File + * @return bool + */ + private function authorize( Loco_fs_File $file ){ + // may already have authorized successfully + if( $fs = $this->fs ){ + $file->getWriteContext()->connect( $fs, false ); + return true; + } + + // may have already failed authorization + if( $this->form ){ + return false; + } + + // network access may be disabled + if( ! apply_filters('loco_allow_remote', true ) ){ + throw new Loco_error_WriteException('Remote connection required, but network access is disabled'); + } + + // else begin new auth + $this->fs = null; + $this->form = ''; + $this->creds_out = array(); + + // observe settings held temporarily in session + try { + $session = Loco_data_Session::get(); + if( isset($session['loco-fs']) ){ + $creds = $session['loco-fs']; + if( is_array($creds) && $this->tryCredentials($creds,$file) ){ + $this->creds_in = array(); + return true; + } + } + } + catch( Exception $e ){ + // tolerate session failure + } + + $post = Loco_mvc_PostParams::get(); + $dflt = array( 'hostname' => '', 'username' => '', 'password' => '', 'public_key' => '', 'private_key' => '', 'connection_type' => '', '_fs_nonce' => '' ); + $this->creds_in = array_intersect_key( $post->getArrayCopy(), $dflt ); + + // deliberately circumventing call to `get_filesystem_method` + // risk of WordPress version compatibility issues, but only sane way to force a remote connection + // @codeCoverageIgnoreStart + if( defined('FS_METHOD') && FS_METHOD ){ + $type = FS_METHOD; + // forcing direct access means request_filesystem_credentials will never give us a form :( + if( 'direct' === $type ){ + return false; + } + } + // direct filesystem if ok if front end already posted it + else if( 'direct' === $post->connection_type ){ + return true; + } + // else perform same logic as request_filesystem_credentials does to establish type + else if( 'ssh' === $post->connection_type && extension_loaded('ssh2') && function_exists('stream_get_contents') ){ + $type = 'ssh2'; + } + else if( extension_loaded('ftp') ){ + $type = 'ftpext'; + } + else if( extension_loaded('sockets') || function_exists('fsockopen') ){ + $type = 'ftpsockets'; + } + // @codeCoverageIgnoreEnd + else { + $type = ''; + } + + // context is nonsense here as the system doesn't know what operation we're performing + // testing directory write-permission when we're updating a file, for example. + $context = '/ignore/this'; + + $type = apply_filters( 'filesystem_method', $type, $post->getArrayCopy(), $context, true ); + + // the only params we'll pass into form will be those used by the ajax fsConnect end point + $extra = array( 'loco-nonce', 'path', 'auth', 'dest' ); + + // capture WordPress output during negotiation. + $buffer = Loco_output_Buffer::start(); + + $creds = request_filesystem_credentials( '', $type, false, $context, $extra ); + if( is_array($creds) ){ + // credentials passed through, should allow connect if they are correct + if( $this->tryCredentials($creds,$file) ){ + $this->persistCredentials(); + return true; + } + // else there must be an error with the credentials + $error = true; + // pull more useful connection error for display in form + if( isset($GLOBALS['wp_filesystem']) ){ + $fs = $GLOBALS['wp_filesystem']; + $GLOBALS['wp_filesystem'] = null; + if( $fs && $fs->errors && $fs->errors->get_error_code() ){ + $error = $fs->errors; + } + } + // annoyingly WordPress moves the error notice above the navigation tabs :-/ + request_filesystem_credentials( '', $type, $error, $context, $extra ); + } + + // now have unauthorized remote connection + $this->form = (string) $buffer->close(); + return false; + } + + + /** + * @param array credentials returned from request_filesystem_credentials + * @param Loco_fs_File file to authorize write context + * @return bool when credentials connected ok + */ + private function tryCredentials( array $creds, Loco_fs_File $file ){ + // lazy construct the file system from current credentials if possible + // in typical WordPress style, after success the object will be held in a global. + if( WP_Filesystem( $creds, '/ignore/this/' ) ){ + $this->fs = $GLOBALS['wp_filesystem']; + // hook new file system into write context (specifying that connect has already been performed) + $file->getWriteContext()->connect( $this->fs, false ); + $this->creds_out = $creds; + return true; + } + return false; + } + + + /** + * Set current credentials in session if settings allow + * @return bool whether credentials persisted + */ + private function persistCredentials(){ + try { + $settings = Loco_data_Settings::get(); + if( $settings['fs_persist'] ){ + $session = Loco_data_Session::get(); + $session['loco-fs'] = $this->creds_out; + $session->persist(); + return true; + } + } + catch( Exception $e ){ + // tolerate session failure + Loco_error_AdminNotices::debug( $e->getMessage() ); + } + return false; + } + + + /** + * Get working credentials that resulted in connection + * @return array + */ + public function getOutputCredentials(){ + return $this->creds_out; + } + + + /** + * Get input credentials from original post. + * this is not the same as getCredentials. It is designed for replay only, regardless of success + * Note that input to request_filesystem_credentials is not the same as the output (specifically how hostname:port is handled) + */ + public function getInputCredentials(){ + return $this->creds_in; + } + + + /** + * Get currently configured filesystem API + * @return WP_Filesystem_Direct + */ + public function getFileSystem(){ + if( ! $this->fs ){ + return self::direct(); + } + return $this->fs; + } + + + /** + * Check if a file is safe from WordPress automatic updates + * @param Loco_fs_File + * @return bool + */ + public function isAutoUpdatable( Loco_fs_File $file ){ + // all paths safe from auto-updates if auto-updates are completely disabled + if( $this->isAutoUpdateDenied() ){ + return false; + } + if( apply_filters( 'automatic_updater_disabled', loco_constant('AUTOMATIC_UPDATER_DISABLED') ) ) { + return false; + } + // Auto-updates aren't denied, so ascertain location "type" and run through the same filters as should_update() + if( $type = $file->getUpdateType() ){ + // TODO provide a useful context for the update offer passed to filters + // WordPress updater will have taken this from remote API data which we don't have here. + $item = new stdClass; + return apply_filters( 'auto_update_'.$type, true, $item ); + } + // else safe (not auto-updatable) + return false; + } + + + /** + * Check if system is configured to deny auto-updates + * @return bool + */ + public function isAutoUpdateDenied(){ + // WordPress >= 4.8 can disable auto updates completely with "automatic_updater" context + if( function_exists('wp_is_file_mod_allowed') && ! wp_is_file_mod_allowed('automatic_updater') ){ + return true; + } + // else simply observe AUTOMATIC_UPDATER_DISABLED constant + if( apply_filters( 'automatic_updater_disabled', loco_constant('AUTOMATIC_UPDATER_DISABLED') ) ) { + return true; + } + // else nothing explicitly denying updates + return false; + } + +} \ No newline at end of file diff --git a/vendor/loco-translate/src/api/WordPressTranslations.php b/vendor/loco-translate/src/api/WordPressTranslations.php new file mode 100644 index 0000000..d89ad96 --- /dev/null +++ b/vendor/loco-translate/src/api/WordPressTranslations.php @@ -0,0 +1,144 @@ + + */ + public function getAvailableCore(){ + $locales = $this->locales; + if( is_null($locales) ){ + $locales = array(); + // get official locales from API if we have network + if( $cached = $this->wp_get_available_translations() ){ + $english_name = 'english_name'; + $native_name = 'native_name'; + } + // else fall back to bundled data cached + else { + $english_name = 0; + $native_name = 1; + $cached = Loco_data_CompiledData::get('locales'); + // debug so we can see on front end that data was offline + // $locales['en-debug'] = ( new Loco_Locale('en','','debug') )->setName('OFFLINE DATA'); + } + foreach( $cached as $tag => $raw ){ + $locale = Loco_Locale::parse($tag); + if( $locale->isValid() ){ + $locale->setName( $raw[$english_name], $raw[$native_name] ); + $locales[ (string) $tag ] = $locale; + } + /* Skip invalid language tags, e.g. "pt_PT_ao90" should be "pt_PT_ao1990" + * No point fixing invalid tags, because core translation files won't match. + else { + Loco_error_AdminNotices::debug( sprintf('Invalid locale: %s', $tag) ); + }*/ + } + $this->locales = $locales; + } + return $locales; + } + + + + /** + * Wrap get_available_languages + * @return array + */ + public function getInstalledCore(){ + // wp-includes/l10n.php should always be included at runtime + if( ! is_array($this->installed) ){ + $this->installed = get_available_languages(); + // en_US is implicitly installed + if( ! in_array('en_US',$this->installed) ){ + array_unshift( $this->installed, 'en_US' ); + } + } + return $this->installed; + } + + + /** + * @return array + */ + private function getInstalledHash(){ + if( ! is_array($this->installed_hash) ){ + $this->installed_hash = array_flip( $this->getInstalledCore() ); + } + return $this->installed_hash; + } + + + /** + * Check if a given locale is installed + * @return bool + */ + public function isInstalled( $locale ){ + return array_key_exists( (string) $locale, $this->getInstalledHash() ); + } + + + /** + * Get WordPress locale data by strictly well-formed language tag + * @return Loco_Locale + */ + public function getLocale( $tag ){ + $all = $this->getAvailableCore(); + return isset($all[$tag]) ? $all[$tag] : null; + } + + + /** + * Check whether remote API may be disabled for whatever reason, usually debugging. + * @return bool + */ + public function hasNetwork(){ + if( is_null($this->enabled) ){ + $this->enabled = (bool) apply_filters('loco_allow_remote', true ); + } + return $this->enabled; + } + +} + diff --git a/vendor/loco-translate/src/compat/CtypeExtension.php b/vendor/loco-translate/src/compat/CtypeExtension.php new file mode 100644 index 0000000..4a1678e --- /dev/null +++ b/vendor/loco-translate/src/compat/CtypeExtension.php @@ -0,0 +1,20 @@ +

      Error: '.implode('. ',$texts).'

      '; + } + +} diff --git a/vendor/loco-translate/src/compat/JsonExtension.php b/vendor/loco-translate/src/compat/JsonExtension.php new file mode 100644 index 0000000..a5fe18f --- /dev/null +++ b/vendor/loco-translate/src/compat/JsonExtension.php @@ -0,0 +1,33 @@ +jsonSerialize() ) + * Note that this shim is also present in WordPress >= 4.4.0 + */ +if( ! interface_exists('JsonSerializable') ){ + interface JsonSerializable { + public function jsonSerialize(); + } +} + +// @codeCoverageIgnoreEnd + +/** + * Redundant interface so this file will autoload when JsonSerializable is referenced + * @internal + */ +interface Loco_compat_JsonSerializable extends JsonSerializable { + +} diff --git a/vendor/loco-translate/src/compat/MbstringExtension.php b/vendor/loco-translate/src/compat/MbstringExtension.php new file mode 100644 index 0000000..0f2a43d --- /dev/null +++ b/vendor/loco-translate/src/compat/MbstringExtension.php @@ -0,0 +1,63 @@ +loadArray( $root ); + } + + + /** + * Construct model from exported array + * @return void + */ + public function loadArray( array $root ){ + $dom = $this->getDom(); + $dom->load( array('#document', array(), array($root) ) ); + } + + + + /** + * {@inheritdoc} + * Emulates *very limited* XPath queries used by the XML DOM. + */ + public function query( $query, $context = null ){ + $match = new LocoConfigNodeList; + $query = explode('/', $query ); + // absolute path always starts in document + if( $absolute = empty($query[0]) ){ + $match->append( $this->getDom() ); + } + // else start with base for relative path + else if( $context instanceof LocoConfigNode ){ + $match->append( $context ); + } + while( $query ){ + $name = array_shift($query); + // self references do nothing + if( ! $name || '.' === $name ){ + continue; + } + // match all current branches to produce new set of parents + $next = new LocoConfigNodeList; + foreach( $match as $parent ){ + foreach( $parent->childNodes as $child ){ + if( $name === $child->nodeName || ( '*' === $name && $child instanceof LocoConfigElement ) || ( 'text()' === $name && $child instanceof LocoConfigText) ){ + $next->append( $child ); + } + } + } + $match = $next; + } + + return $match; + } + +} + + + + + +// The following classes are "private" to this file: +// They partially implement the same interfaces as the core DOM classes and are used for code hints. +// Interfaces are deliberately not used as the real DOM classes would not be able to implement them. + + + +/** + * Node + */ +abstract class LocoConfigNode implements IteratorAggregate { + + /** + * Raw data of internal format + * @var array + */ + protected $data; + + /** + * Child nodes once cast to node objects + * @var LocoConfigNodeList + */ + protected $children; + + /** + * @return mixed + */ + abstract public function export(); + + final public function __construct( $data ){ + $this->data = $data; + } + + protected function get_nodeName(){ + return $this->data[0]; + } + + /*protected function get_attributes(){ + return $this->data[1]; + }*/ + + protected function get_childNodes(){ + return $this->getIterator(); + } + + + public function __get( $prop ){ + $method = array( $this, 'get_'.$prop ); + if( is_callable($method) ){ + return call_user_func( $method ); + } + } + + + /** @return LocoConfigNode */ + public function appendChild( LocoConfigNode $child ){ + $children = $this->getIterator(); + $children->append( $child ); + return $child; + } + + + /** @return bool */ + public function hasChildNodes(){ + return (bool) count( $this->getIterator() ); + } + + + /** + * @return LocoConfigNodeList + */ + public function getIterator(){ + if( ! $this->children ){ + $raw = isset($this->data[2]) ? $this->data[2] : array(); + $this->children = new LocoConfigNodeList( $this->data[2] ); + } + return $this->children; + } + + + public function get_textContent(){ + $s = ''; + foreach( $this as $child ){ + $s .= $child->get_textContent(); + } + return $s; + } + +} + + +/** + * NodeList + */ +class LocoConfigNodeList implements Iterator, Countable, ArrayAccess { + + private $nodes; + + private $i; + + private $n; + + public function __construct( array $nodes = array() ){ + $this->nodes = $nodes; + $this->n = count( $nodes ); + } + + public function count(){ + return $this->n; + } + + public function rewind(){ + $this->i = -1; + $this->next(); + } + + public function key(){ + return $this->i; + } + + public function current(){ + return $this[ $this->i ]; + } + + public function valid(){ + return is_int($this->i); + } + + public function next(){ + if( ++$this->i === $this->n ){ + $this->i = null; + } + } + + public function offsetExists( $i ){ + return $i >= 0 && $i < $this->n; + } + + public function offsetGet( $i ){ + $node = $this->nodes[$i]; + if( ! $node instanceof LocoConfigNode ){ + if( is_array($node) ){ + $node = new LocoConfigElement( $node ); + } + else { + $node = new LocoConfigText( $node ); + } + $this->nodes[$i] = $node; + } + return $node; + } + + /** + * @codeCoverageIgnore + */ + public function offsetSet( $i, $value ){ + throw new Exception('Use append'); + } + + /** + * @codeCoverageIgnore + */ + public function offsetUnset( $i ){ + throw new Exception('Read only'); + } + + + public function append( LocoConfigNode $node ){ + $this->nodes[] = $node; + $this->n++; + } + + + /** + * Revert nodes back to raw array form and return for exporting + * @return array + */ + public function normalize(){ + foreach( $this->nodes as $i => $node ){ + if( $node instanceof LocoConfigNode ){ + $this->nodes[$i] = $node->export(); + } + } + return $this->nodes; + } + +} + + + + + + +/** + * Document + */ +class LocoConfigDocument extends LocoConfigNode { + + /** + * Rapidly set new data for document + */ + public function load( $data ){ + $this->data = $data; + $this->children = null; + } + + + /** + * @return LocoConfigElement + */ + public function createElement( $name ){ + return new LocoConfigElement( array( $name, array(), array() ) ); + } + + + /** + * @return LocoConfigText + */ + public function createTextNode( $text ){ + return new LocoConfigText( $text ); + } + + + /** + * @return LocoConfigElement + */ + public function get_documentElement(){ + $child = null; + foreach( $this as $child ){ + break; + } + return $child; + } + + + /** + * {@inheritdoc} + * Override to keep single element root + */ + public function export(){ + if( $root = $this->get_documentElement() ){ + return $root->export(); + } + } + +} + + + + +/** + * Element + */ +class LocoConfigElement extends LocoConfigNode { + + public function setAttribute( $prop, $value ){ + $this->data[1][$prop] = $value; + } + + public function removeAttribute( $prop ){ + unset( $this->data[1][$prop] ); + } + + public function getAttribute( $prop ){ + if( isset($this->data[1][$prop]) ){ + return $this->data[1][$prop]; + } + return ''; + } + + public function hasAttribute( $prop ){ + return isset($this->data[1][$prop]); + } + + /** + * {@inheritdoc} + */ + public function export(){ + $raw = $this->data; + // return any cast elements back to raw data + if( $this->children ){ + $raw[2] = $this->children->normalize(); + } + return $raw; + } +} + + + +/** + * Text + */ +class LocoConfigText extends LocoConfigNode { + + protected function get_nodeName(){ + return '#text'; + } + + public function hasChildNodes(){ + return false; + } + + public function getIterator(){ + return new ArrayIterator; + } + + public function export(){ + return (string) $this->data; + } + + public function get_nodeValue(){ + return (string) $this->data; + } + + public function get_textContent(){ + return (string) $this->data; + } + +} + + diff --git a/vendor/loco-translate/src/config/BundleReader.php b/vendor/loco-translate/src/config/BundleReader.php new file mode 100644 index 0000000..c40de60 --- /dev/null +++ b/vendor/loco-translate/src/config/BundleReader.php @@ -0,0 +1,172 @@ +bundle = $bundle; + } + + + /** + * @param Loco_fs_File loco.xml file + * @return Loco_package_Bundle + */ + public function loadXml( Loco_fs_File $file ){ + $this->bundle->setDirectoryPath( $file->dirname() ); + $model = new Loco_config_XMLModel; + $model->loadXml( $file->getContents() ); + return $this->loadModel( $model ); + } + + + /** + * @return Loco_package_Bundle + */ + public function loadJson( Loco_fs_File $file ){ + $this->bundle->setDirectoryPath( $file->dirname() ); + return $this->loadArray( json_decode( $file->getContents(), true ) ); + } + + + /** + * @return Loco_package_Bundle + */ + public function loadArray( array $raw ){ + $model = new Loco_config_ArrayModel; + $model->loadArray( $raw ); + return $this->loadModel( $model ); + } + + + + /** + * Agnostic construction of Bundle from any configuration format + * @return Loco_package_Bundle + */ + public function loadModel( Loco_config_Model $model ){ + + // Base directory required to resolve relative paths + $bundle = $this->bundle; + $model->setDirectoryPath( $bundle->getDirectoryPath() ); + + $dom = $model->getDom(); + $bundleElement = $dom->documentElement; + if( ! $bundleElement || 'bundle' !== $bundleElement->nodeName ){ + throw new InvalidArgumentException('Expected root bundle element'); + } + + // Set bundle meta data if configured + // note that bundles have no inherent slug as it can change according to plugin/theme directory naming + if( $bundleElement->hasAttribute('name') ){ + $bundle->setName( $bundleElement->getAttribute('name') ); + } + + // Bundle-level path exclusions + foreach( $model->query('exclude/*',$bundleElement) as $fileElement ){ + $bundle->excludeLocation( $model->evaluateFileElement($fileElement) ); + } + + /* @var $domainElement LocoConfigElement */ + foreach( $model->query('domain',$bundleElement) as $domainElement ){ + $slug = $domainElement->getAttribute('name') or $slug = $bundle->getSlug(); + // bundle may not have a handle set (most likely only in tests) + if( ! $bundle->getHandle() ){ + $bundle->setHandle( $slug ); + } + // Text Domain may also be declared by bundle author + $domain = new Loco_package_TextDomain( $slug ); + $declared = $bundle->getHeaderInfo(); + if( $declared && $declared->TextDomain === $slug ){ + $domain->setCanonical( true ); + } + /* @var $projectElement LocoConfigElement */ + foreach( $model->query('project',$domainElement) as $projectElement ){ + + $name = $projectElement->getAttribute('name') or $name = $bundle->getName(); + $project = new Loco_package_Project( $bundle, $domain, $name ); + if( $projectElement->hasAttribute('slug') ){ + $project->setSlug( $projectElement->getAttribute('slug') ); + } + + // + foreach( $model->query('source',$projectElement) as $sourceElement ){ + // sources may be , or pass in special if it could be either + foreach( $model->query('file',$sourceElement) as $fileElement ){ + $project->addSourceFile( $model->evaluateFileElement($fileElement) ); + } + foreach( $model->query('directory',$sourceElement) as $fileElement ){ + $project->addSourceDirectory( $model->evaluateFileElement($fileElement) ); + } + foreach( $model->query('path',$sourceElement) as $fileElement ){ + $project->addSourceLocation( $model->evaluateFileElement($fileElement) ); + } + foreach( $model->query('exclude/*', $sourceElement) as $fileElement ){ + $project->excludeSourcePath( $model->evaluateFileElement($fileElement) ); + } + } + // Avoid having no source locations + if( ! $project->hasSourceFiles() ){ + if( $bundle->isSingleFile() ){ + $project->addSourceFile( $bundle->getBootstrapPath() ); + } + else { + $project->addSourceDirectory( $bundle->getDirectoryPath() ); + } + } + + // + foreach( $model->query('target',$projectElement) as $targetElement ){ + // targets support only directory paths: + foreach( $model->query('directory',$targetElement) as $fileElement ){ + $project->addTargetDirectory( $model->evaluateFileElement($fileElement) ); + } + foreach( $model->query('exclude/*', $targetElement) as $fileElement ){ + $project->excludeTargetPath( $model->evaluateFileElement($fileElement) ); + } + } + // Avoid having no target locations .. + if( 0 === count($project->getConfiguredTargets() ) ){ + // .. unless the inherited root is a global location + if( $bundle->isTheme() || ( $bundle->isPlugin() && ! $bundle->isSingleFile() ) ){ + $project->addTargetDirectory( $bundle->getDirectoryPath() ); + } + } + + //