commit 0483b4b3646e4a26061a5de0ccc2c2cfbe9ad124 Author: 你的名字 Date: Mon Jul 14 10:22:40 2025 +0800 1 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..a45350d --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +composer.lock +.DS_Store +Thumbs.db +/phpunit.xml +/.idea +/.vscode +runtime +thinkphp +vendor +.env \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.user.ini b/.user.ini new file mode 100644 index 0000000..4e2cdfb --- /dev/null +++ b/.user.ini @@ -0,0 +1 @@ +open_basedir=/www/wwwroot/weipan07_server/:/tmp/ \ No newline at end of file diff --git a/404.html b/404.html new file mode 100644 index 0000000..a2f560c --- /dev/null +++ b/404.html @@ -0,0 +1,74 @@ + + + + + + 404 Not Found + + + +
+ +
404
+
Sorry, the page you visited does not exist.
It may be that the access link is wrong or the file does not exist.
+ +
+ + diff --git a/502.html b/502.html new file mode 100644 index 0000000..5f25659 --- /dev/null +++ b/502.html @@ -0,0 +1,74 @@ + + + + + + 502 Bad Gateway + + + +
+ +
502
+
Gateway error.
The website server has timed out in returning data, please wait a few minutes and try again.
+ +
+ + diff --git a/application/akszadmin/controller/Article.php b/application/akszadmin/controller/Article.php new file mode 100755 index 0000000..28fab97 --- /dev/null +++ b/application/akszadmin/controller/Article.php @@ -0,0 +1,140 @@ +title = '文章列表'; + $query = $this->_query($this->table)->alias('i')->field('i.*,t.name'); + $query->join('lc_article_type t','i.type=t.id')->equal('i.type#i_type')->like('i.title#i_title')->dateBetween('i.time#i_time')->order('i.sort asc,i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->mlist = Db::name('LcArticleType')->select(); + } + + /** + * 添加文章 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加文章'; + $this->assign('langss', [ + ['name' => '中文', 'value' => 'zh-cn'], + ['name' => '英文', 'value' => 'en'], + ['name' => '法文', 'value' => 'fr'], + ['name' => '德文', 'value' => 'de'], + ['name' => '西班牙文', 'value' => 'es'], + ['name' => '意大利文', 'value' => 'it'], + ['name' => '葡萄牙文', 'value' => 'pt'], + ['name' => '俄文', 'value' => 'ru'], + ['name' => '阿拉伯文', 'value' => 'ar'], + ]); + $this->_form($this->table, 'form'); + } + + /** + * 编辑文章 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑文章'; + $this->assign('langss', [ + ['name' => '中文', 'value' => 'zh-cn'], + ['name' => '英文', 'value' => 'en'], + ['name' => '法文', 'value' => 'fr'], + ['name' => '德文', 'value' => 'de'], + ['name' => '西班牙文', 'value' => 'es'], + ['name' => '意大利文', 'value' => 'it'], + ['name' => '葡萄牙文', 'value' => 'pt'], + ['name' => '俄文', 'value' => 'ru'], + ['name' => '阿拉伯文', 'value' => 'ar'], + ]); + $this->_form($this->table, 'form'); + } + + /** + * 删除文章 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isGet()) { + $this->class = Db::name("LcArticleType")->order('id asc')->select(); + if(!isset($vo['show'])) $vo['show'] = '1'; + } + if (empty($vo['time'])) $vo['time'] = date("Y-m-d H:i:s"); + } + +} diff --git a/application/akszadmin/controller/ArticleType.php b/application/akszadmin/controller/ArticleType.php new file mode 100755 index 0000000..185a719 --- /dev/null +++ b/application/akszadmin/controller/ArticleType.php @@ -0,0 +1,113 @@ +title = '文章分类管理'; + $query = $this->_query($this->table)->like('name'); + $query->order('sort asc,id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + + } + + /** + * 添加文章分类 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加文章分类'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑文章分类 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑文章分类'; + $this->_form($this->table, 'form'); + } + + /** + * 删除文章分类 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isPost()&&empty($vo['add_time'])) $vo['add_time'] = date("Y-m-d H:i:s"); + } + +} diff --git a/application/akszadmin/controller/Auth.php b/application/akszadmin/controller/Auth.php new file mode 100755 index 0000000..4fec23d --- /dev/null +++ b/application/akszadmin/controller/Auth.php @@ -0,0 +1,180 @@ +title = '系统权限管理'; + $query = $this->_query($this->table)->dateBetween('create_at'); + $query->like('title,desc')->equal('status')->order('sort desc,id desc')->page(); + } + + /** + * 权限配置节点 + * @auth true + * @throws \ReflectionException + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function apply() + { + $map = ['auth' => input('id', '0')]; + $action = strtolower(input('action', '')); + if ($action === 'get') { + $checkeds = Db::name('SystemAuthNode')->where($map)->column('node'); + $this->success('获取权限节点成功!', AdminService::instance()->getTree($checkeds)); + } elseif ($action === 'save') { + list($post, $data) = [$this->request->post(), []]; + foreach (isset($post['nodes']) ? $post['nodes'] : [] as $node) { + $data[] = ['auth' => $map['auth'], 'node' => $node]; + } + Db::name('SystemAuthNode')->where($map)->delete(); + Db::name('SystemAuthNode')->insertAll($data); + AdminService::instance()->apply(true); + $this->success('权限授权更新成功!', 'javascript:history.back()'); + } else { + $this->title = '权限配置节点'; + $this->_form($this->table, 'apply'); + } + } + + /** + * 添加系统权限 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 编辑系统权限 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 刷新系统权限 + * @auth true + */ + public function refresh() + { + try { + AdminService::instance()->apply(true); + $this->success('刷新系统授权成功!'); + } catch (\think\exception\HttpResponseException $exception) { + throw $exception; + } catch (\Exception $e) { + $this->error("刷新系统授权失败
{$e->getMessage()}"); + } + } + + /** + * 禁用系统权限 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function forbid() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '0']); + } + + /** + * 启用系统权限 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function resume() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '1']); + } + + /** + * 删除系统权限 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + + /** + * 删除结果处理 + * @param boolean $result + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + protected function _remove_delete_result($result) + { + if ($result) { + $map = ['auth' => $this->request->post('id')]; + Db::name('SystemAuthNode')->where($map)->delete(); + $this->success("权限删除成功!", ''); + } else { + $this->error("权限删除失败,请稍候再试!"); + } + } + +} diff --git a/application/akszadmin/controller/Bank.php b/application/akszadmin/controller/Bank.php new file mode 100755 index 0000000..4a2da7e --- /dev/null +++ b/application/akszadmin/controller/Bank.php @@ -0,0 +1,100 @@ +title = '银行卡列表'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name as u_name'); + $query->join('lc_user u','i.uid=u.id')->like('i.account#i_account,u.phone#u_phone,u.name#u_name')->order('i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + + } + + /** + * 编辑银行卡 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑银行卡'; + $this->_form($this->table, 'form'); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if($this->request->isGet()){ + $vo['phone'] = Db::name("LcUser")->where(['id'=>$vo['uid']])->value('phone'); + } + } + + /** + * 删除银行卡 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Cash.php b/application/akszadmin/controller/Cash.php new file mode 100755 index 0000000..f3009b3 --- /dev/null +++ b/application/akszadmin/controller/Cash.php @@ -0,0 +1,131 @@ +title = '提现记录'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone'); + $query->join('lc_user u','i.uid=u.id') + ->equal('i.status#i_status') + ->like('u.phone#u_phone,u.name#u_name') + ->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + + } + public function edit() + { + $this->applyCsrfToken(); + if($this->request->isPost()) { + $id = $this->request->param('id'); + $reaolae = $this->request->param('reaolae'); + $cash = Db::name($this->table)->find($id); + if(!$cash){ + $this->error('提现订单不存在'); + } + if($cash['status'] != 0){ + $this->error('提现订单已处理'); + } + addFinance($cash['uid'], $cash['money'],1, '提现失败,返还金额' . $cash['money'] . '元'); + setNumber('LcUser', 'money', $cash['money'], 1, "id = {$cash['uid']}"); + $this->_save($this->table, ['reaolae'=>$reaolae,'status' => '2', 'time2' => date('Y-m-d H:i:s')]); + }else{ + $this->title = '拒绝提现'; + $id = $this->request->param('id'); + $recharge = Db::name($this->table)->find($id); + + if($recharge){ + $recharge['username'] = Db::name("LcUser")->where(['id'=>$recharge['uid']])->value('phone'); + } + $this->_form($this->table, 'edit'); + } + } + /** + * 同意提现 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function agree() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '1', 'time2' => date('Y-m-d H:i:s')]); + } + + /** + * 拒绝提现 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function refuse() + { + $this->applyCsrfToken(); + $id = $this->request->param('id'); + $cash = Db::name($this->table)->find($id); + addFinance($cash['uid'], $cash['money'],1, '提现失败,返还金额' . $cash['money'] . '元'); + setNumber('LcUser', 'money', $cash['money'], 1, "id = {$cash['uid']}"); + $this->_save($this->table, ['status' => '2', 'time2' => date('Y-m-d H:i:s')]); + } + + /** + * 删除记录 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Config.php b/application/akszadmin/controller/Config.php new file mode 100755 index 0000000..1f4ace7 --- /dev/null +++ b/application/akszadmin/controller/Config.php @@ -0,0 +1,130 @@ + '华东 1 杭州', + 'oss-cn-shanghai.aliyuncs.com' => '华东 2 上海', + 'oss-cn-qingdao.aliyuncs.com' => '华北 1 青岛', + 'oss-cn-beijing.aliyuncs.com' => '华北 2 北京', + 'oss-cn-zhangjiakou.aliyuncs.com' => '华北 3 张家口', + 'oss-cn-huhehaote.aliyuncs.com' => '华北 5 呼和浩特', + 'oss-cn-shenzhen.aliyuncs.com' => '华南 1 深圳', + 'oss-cn-hongkong.aliyuncs.com' => '香港 1', + 'oss-us-west-1.aliyuncs.com' => '美国西部 1 硅谷', + 'oss-us-east-1.aliyuncs.com' => '美国东部 1 弗吉尼亚', + 'oss-ap-southeast-1.aliyuncs.com' => '亚太东南 1 新加坡', + 'oss-ap-southeast-2.aliyuncs.com' => '亚太东南 2 悉尼', + 'oss-ap-southeast-3.aliyuncs.com' => '亚太东南 3 吉隆坡', + 'oss-ap-southeast-5.aliyuncs.com' => '亚太东南 5 雅加达', + 'oss-ap-northeast-1.aliyuncs.com' => '亚太东北 1 日本', + 'oss-ap-south-1.aliyuncs.com' => '亚太南部 1 孟买', + 'oss-eu-central-1.aliyuncs.com' => '欧洲中部 1 法兰克福', + 'oss-eu-west-1.aliyuncs.com' => '英国 1 伦敦', + 'oss-me-east-1.aliyuncs.com' => '中东东部 1 迪拜', + ]; + + /** + * 系统参数配置 + * @auth true + * @menu true + */ + public function info() + { + $this->title = '系统参数配置'; + $this->fetch(); + } + + /** + * 修改系统能数配置 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function config() + { + $this->applyCsrfToken(); + if (Request::isGet()) { + $this->fetch('system-config'); + } + foreach (Request::post() as $key => $value) { + sysconf($key, $value); + } + $this->success('系统参数配置成功!'); + } + + /** + * 文件存储引擎 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function file() + { + $this->applyCsrfToken(); + if (Request::isGet()) { + $this->type = input('type', 'local'); + $this->fetch("storage-{$this->type}"); + } + $post = Request::post(); + if (isset($post['storage_type']) && isset($post['storage_local_exts'])) { + $exts = array_unique(explode(',', strtolower($post['storage_local_exts']))); + sort($exts); + if (in_array('php', $exts)) $this->error('禁止上传可执行文件到本地服务器!'); + $post['storage_local_exts'] = join(',', $exts); + } + foreach ($post as $key => $value) sysconf($key, $value); + if (isset($post['storage_type']) && $post['storage_type'] === 'oss') { + try { + $local = sysconf('storage_oss_domain'); + $bucket = $this->request->post('storage_oss_bucket'); + $domain = \library\File::instance('oss')->setBucket($bucket); + if (empty($local) || stripos($local, '.aliyuncs.com') !== false) { + sysconf('storage_oss_domain', $domain); + } + $this->success('阿里云OSS存储配置成功!'); + } catch (HttpResponseException $exception) { + throw $exception; + } catch (\Exception $e) { + $this->error("阿里云OSS存储配置失效,{$e->getMessage()}"); + } + } else { + $this->success('文件存储配置成功!'); + } + } + +} diff --git a/application/akszadmin/controller/Finance.php b/application/akszadmin/controller/Finance.php new file mode 100755 index 0000000..0654f5e --- /dev/null +++ b/application/akszadmin/controller/Finance.php @@ -0,0 +1,63 @@ +title = '流水记录'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.type#i_type')->like('i.reason#i_reason,u.phone#u_phone,u.name#u_name')->dateBetween('i.time#i_time')->valueBetween('i.money')->order('i.id desc')->page(); + + } + + /** + * 删除记录 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Goods.php b/application/akszadmin/controller/Goods.php new file mode 100755 index 0000000..303b85a --- /dev/null +++ b/application/akszadmin/controller/Goods.php @@ -0,0 +1,171 @@ +title = '产品列表'; + $query = $this->_query($this->table)->like('title'); + $query->order('sort asc,id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + + } + + /** + * 添加产品 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加产品'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑产品 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑产品'; + $this->_form($this->table, 'form'); + } + /** + * 状态 开启或者关闭 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function iskqopen() + { + $this->applyCsrfToken(); + $id = $this->request->param('id'); + $iskq = $this->request->param('iskq'); + $this->_save($this->table, ['iskq' => $iskq]); + } + + public function showps(){ + $this->applyCsrfToken(); + $id = $this->request->param('id'); + $iskq = $this->request->param('do'); + $this->_save($this->table, ['showps' => $iskq]); + } + public function showps2(){ + $this->applyCsrfToken(); + $id = $this->request->param('id'); + $iskq = $this->request->param('do'); + $this->_save($this->table, ['showps2' => $iskq]); + } + /** + * 状态 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function proisopen() + { + $this->applyCsrfToken(); + $id = $this->request->param('id'); + $isopen = $this->request->param('isopen'); + + $this->_save($this->table, ['isopen' => $isopen]); + } + /** + * 删除产品 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isGet()) { + + } + } + /** + * 风控管理 + * @auth true + * @menu true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function risk() + { + $this->title = '风控管理'; + $this->_form($this->risk_table, 'risk'); + } + +} diff --git a/application/akszadmin/controller/Index.php b/application/akszadmin/controller/Index.php new file mode 100755 index 0000000..bfa043a --- /dev/null +++ b/application/akszadmin/controller/Index.php @@ -0,0 +1,311 @@ +where("access_time > $now")->count(); + return json(['code' => 200, 'data' => $online_user]); + } + + /** + * 显示后台首页 + * @throws \ReflectionException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function index() + { + $this->title = '系统管理后台'; + $auth = AdminService::instance()->apply(true); + if (!$auth->isLogin()) { + $this->redirect('@' . ADMIN_MODULE . '/login'); + } + $this->menus = MenuService::instance()->getTree(); + if (empty($this->menus) && !$auth->isLogin()) { + $this->redirect('@' . ADMIN_MODULE . '/login'); + } else { + $this->fetch(); + } + } + + /** + * Describe:查询充值提现记录 + * DateTime: 2020/5/15 0:54 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function check() + { + $auth = AdminService::instance()->apply(true); + if ($auth->isLogin()) { + $cash_count = Db::name("LcCash")->where(['status' => 0, 'warn' => 0])->count(); + $firstDate = time(); + $lastDate = time() + 300; + $Order_count = Db::name("LcOrder")->where("ostaus = 0 AND warn = 0 and kong_type = 0")->count(); + + $recharge_count = Db::name("LcRecharge")->where(['status' => 0, 'warn' => 0])->count(); + if ($Order_count > 0) { + $this->success("您有{$Order_count}条新的订单记录,请查看", + ["url" => "/static/mp3/order.mp3_{$recharge_count}@{$cash_count}&{$Order_count}"]); + } + if ($cash_count > 0 && $recharge_count > 0) { + $this->success("您有{$cash_count}条新的提现记录和{$recharge_count}条新的充值记录,请查看", + ["url" => "/static/mp3/cztx.mp3_{$recharge_count}@{$cash_count}&{$Order_count}"]); + } + if ($cash_count > 0 && $recharge_count == 0) { + $this->success("您有{$cash_count}条新的提现记录,请查看", + ["url" => "/static/mp3/tx.mp3_{$recharge_count}@{$cash_count}&{$Order_count}"]); + } + if ($cash_count == 0 && 0 < $recharge_count) { + $this->success("您有{$recharge_count}条新的充值记录,请查看", + ["url" => "/static/mp3/cz.mp3_{$recharge_count}@{$cash_count}&{$Order_count}"]); + } + $this->error("暂无记录"); + } + $this->error("请先登录"); + } + + /** + * Describe:忽略提醒 + * DateTime: 2020/5/15 0:56 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function system_ignore() + { + $auth = AdminService::instance()->apply(true); + if ($auth->isLogin()) { + Db::name("LcCash")->where(['warn' => 0])->update(['warn' => 1]); + Db::name("LcRecharge")->where(['warn' => 0])->update(['warn' => 1]); + Db::name("LcOrder")->where(['warn' => 0])->update(['warn' => 1]); + $this->success("操作成功"); + } + $this->error("请先登录"); + } + + /** + * 后台环境信息 + */ + public function main() + { + /*$this->think_ver = \think\App::VERSION; + $this->mysql_ver = Db::query('select version() as ver')[0]['ver'];*/ + $this->invest_count = Db::name('LcOrder')->sum('ploss'); + $this->user_count = Db::name('LcUser')->count(); + $this->recharge_sum = Db::name('LcRecharge')->where("status = 1")->sum('money'); + $this->cash_sum = Db::name('LcCash')->where("status = 1")->sum('money'); + $table = $this->finance_report(); + $this->month = $table['month']; + $this->last_month = $table['last_month']; + $this->day = $table['day']; + $this->today_key = array_search(date('Y-m-d'), array_column($this->day, 'date')); + $now = time() - 300; + $this->online_user = Db::name('LcUser')->where("logintime > $now")->count(); + $this->fetch(); + } + + private function finance_report() + { + $firstDate = strtotime(date('Y-m-01 00:00:00', strtotime(date("Y-m-d")))); + $lastDate = strtotime(date('Y-m-01 23:59:59', strtotime(date("Y-m-d"))) . " +1 month -1 day"); + $month['recharge'] = Db::name('LcRecharge')->where("UNIX_TIMESTAMP(time) BETWEEN $firstDate AND $lastDate AND status = 1")->sum('money'); + $month['cash'] = Db::name('LcCash')->where("UNIX_TIMESTAMP(time) BETWEEN $firstDate AND $lastDate AND status = 1")->sum('money'); + $month['invest_list'] = Db::name('LcRecharge')->where("UNIX_TIMESTAMP(time) BETWEEN $firstDate AND $lastDate AND status = 1")->group('uid')->count(); + $month['invest'] = Db::name('LcInvest')->where("UNIX_TIMESTAMP(time) BETWEEN $firstDate AND $lastDate")->count(); + $month['invest_sum'] = Db::name('LcOrder')->where(" buytime BETWEEN $firstDate AND $lastDate")->sum('ploss'); + + $lastMonthFirstDate = strtotime(date('Y-m-01 00:00:00', strtotime(date("Y-m-d"))) . " -1 month"); + $lastMonthLastDate = strtotime(date('Y-m-01 23:59:59', strtotime(date("Y-m-d"))) . " -1 day"); + $lastMonth['recharge'] = Db::name('LcRecharge')->where("UNIX_TIMESTAMP(time) BETWEEN $lastMonthFirstDate AND $lastMonthLastDate AND status = 1")->sum('money'); + $lastMonth['cash'] = Db::name('LcCash')->where("UNIX_TIMESTAMP(time) BETWEEN $lastMonthFirstDate AND $lastMonthLastDate AND status = 1")->sum('money'); + $lastMonth['invest_list'] = Db::name('LcRecharge')->where("UNIX_TIMESTAMP(time) BETWEEN $lastMonthFirstDate AND $lastMonthLastDate AND status = 1")->group('uid')->count(); + $lastMonth['invest'] = Db::name('LcInvest')->where("UNIX_TIMESTAMP(time) BETWEEN $lastMonthFirstDate AND $lastMonthLastDate")->count(); + $lastMonth['invest_sum'] = Db::name('LcOrder')->where(" buytime BETWEEN $lastMonthFirstDate AND $lastMonthLastDate")->sum('ploss'); + + $monthDays = $this->getMonthDays(); + foreach ($monthDays as $k => $v) { + $first = strtotime($v); + $last = $first + 86400 - 1; + $day[$k]['date'] = $v; + $day[$k]['recharge'] = Db::name('LcRecharge')->where("UNIX_TIMESTAMP(time) BETWEEN $first AND $last AND status = 1")->sum('money'); + $day[$k]['cash'] = Db::name('LcCash')->where("UNIX_TIMESTAMP(time) BETWEEN $first AND $last AND status = 1")->sum('money'); + $day[$k]['invest_list'] = Db::name('LcRecharge')->where("UNIX_TIMESTAMP(time) BETWEEN $first AND $last AND status = 1")->group('uid')->count(); + $day[$k]['new_user'] = Db::name('LcUser')->where("UNIX_TIMESTAMP(time) BETWEEN $first AND $last")->count(); + $day[$k]['invest'] = Db::name('LcInvest')->where("UNIX_TIMESTAMP(time) BETWEEN $first AND $last")->count(); + $day[$k]['invest_sum'] = Db::name('LcInvest')->where("UNIX_TIMESTAMP(time) BETWEEN $first AND $last")->sum('money'); + $day[$k]['expire'] = Db::name('LcOrder')->where(" buytime BETWEEN $first AND $last")->sum('ploss'); + $day[$k]['ordernumer'] = Db::name('LcOrder')->where(" buytime BETWEEN $first AND $last ")->count(); + $day[$k]['interest'] = Db::name('LcOrder')->where(" buytime BETWEEN $first AND $last")->sum('fee'); + } + return array('day' => $day, 'month' => $month, 'last_month' => $lastMonth); + } + + /** + * 获取当前月已过日期 + * @return array + */ + private function getMonthDays() + { + $monthDays = []; + $firstDay = date('Y-m-01', time()); + $i = 0; + $now_day = date('d'); + $lastDay = date('Y-m-d', strtotime("$firstDay +1 month -1 day")); + while (date('Y-m-d', strtotime("$firstDay +$i days")) <= $lastDay) { + // if($i>=$now_day) break; + $monthDays[] = date('Y-m-d', strtotime("$firstDay +$i days")); + $i++; + } + return $monthDays; + } + + /** + * 修改密码 + * @login true + * @param integer $id + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function pass($id) + { + $this->applyCsrfToken(); + if (intval($id) !== intval(session('user.id'))) { + $this->error('只能修改当前用户的密码!'); + } + if (!AdminService::instance()->isLogin()) { + $this->error('需要登录才能操作哦!'); + } + if ($this->request->isGet()) { + $this->verify = true; + $this->_form('SystemUser', 'admin@user/pass', 'id', [], ['id' => $id]); + } else { + $data = $this->_input([ + 'password' => $this->request->post('password'), + 'repassword' => $this->request->post('repassword'), + 'oldpassword' => $this->request->post('oldpassword'), + ], [ + 'oldpassword' => 'require', + 'password' => 'require|min:4', + 'repassword' => 'require|confirm:password', + ], [ + 'oldpassword.require' => '旧密码不能为空!', + 'password.require' => '登录密码不能为空!', + 'password.min' => '登录密码长度不能少于4位有效字符!', + 'repassword.require' => '重复密码不能为空!', + 'repassword.confirm' => '重复密码与登录密码不匹配,请重新输入!', + ]); + $user = Db::name('SystemUser')->where(['id' => $id])->find(); + if (md5($data['oldpassword']) !== $user['password']) { + $this->error('旧密码验证失败,请重新输入!'); + } + if (Data::save('SystemUser', ['id' => $user['id'], 'password' => md5($data['password'])])) { + $this->success('密码修改成功,下次请使用新密码登录!', ''); + } else { + $this->error('密码修改失败,请稍候再试!'); + } + } + } + + /** + * 修改用户资料 + * @login true + * @param integer $id 会员ID + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function info($id = 0) + { + + if (!AdminService::instance()->isLogin()) { + $this->error('需要登录才能操作哦!'); + } + $this->applyCsrfToken(); + if (intval($id) === intval(session('user.id'))) { + $this->_form('SystemUser', 'akszadmin@user/form', 'id', [], ['id' => $id]); + } else { + $this->error('只能修改登录用户的资料!'); + } + } + + /** + * 清理运行缓存 + * @auth true + */ + public function clearRuntime() + { + try { + Console::call('clear'); + Console::call('xclean:session'); + $this->success('清理运行缓存成功!'); + } catch (HttpResponseException $exception) { + throw $exception; + } catch (\Exception $e) { + $this->error("清理运行缓存失败,{$e->getMessage()}"); + } + } + + /** + * 压缩发布系统 + * @auth true + */ + public function buildOptimize() + { + try { + Console::call('optimize:route'); + Console::call('optimize:schema'); + Console::call('optimize:autoload'); + Console::call('optimize:config'); + $this->success('压缩发布成功!'); + } catch (HttpResponseException $exception) { + throw $exception; + } catch (\Exception $e) { + $this->error("压缩发布失败,{$e->getMessage()}"); + } + } + +} diff --git a/application/akszadmin/controller/Info.php b/application/akszadmin/controller/Info.php new file mode 100755 index 0000000..fa16e5b --- /dev/null +++ b/application/akszadmin/controller/Info.php @@ -0,0 +1,109 @@ +title = '网站设置'; + $this->_form($this->table, 'form'); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isPost()&&isset($vo['ban_ip'])&&!empty($vo['ban_ip'])){ + $vo['ban_ip'] = trim(str_replace(',',',',$vo['ban_ip'])); + } + } + + /** + * 奖励设置 + * @auth true + * @menu true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function reward() + { + $this->title = '奖励设置'; + $this->_form($this->reward_table, 'reward'); + } + + /** + * 支付设置 + * @auth true + * @menu true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function pay() + { + $this->title = '支付设置'; + $this->_form($this->table, 'pay'); + } + + /** + * 图片设置 + * @auth true + * @menu true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function img() + { + $this->title = '支付设置'; + $this->_form($this->table, 'img'); + } +} diff --git a/application/akszadmin/controller/Invest.php b/application/akszadmin/controller/Invest.php new file mode 100755 index 0000000..9e6be5b --- /dev/null +++ b/application/akszadmin/controller/Invest.php @@ -0,0 +1,64 @@ +title = '已投项目管理'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.type1#i_type1')->like('i.title#i_title,u.phone#u_phone')->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->tlist = Db::name('LcItemType')->select(); + $this->profit = sprintf("%.2f",Db::name('LcInvestList')->where("status = 1 AND pay1 > 0")->sum('pay1')); + $this->un_profit = sprintf("%.2f",Db::name('LcInvestList')->where("status = 0 AND pay1 > 0")->sum('pay1')); + } +} diff --git a/application/akszadmin/controller/InvestList.php b/application/akszadmin/controller/InvestList.php new file mode 100755 index 0000000..490976c --- /dev/null +++ b/application/akszadmin/controller/InvestList.php @@ -0,0 +1,65 @@ +title = '已投项目管理'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.iid#i_iid')->like('i.title#i_title,u.phone#u_phone')->dateBetween('i.time1#i_time1')->order('i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->refund = sprintf("%.2f",Db::name('LcInvestList')->where("status = 1 AND pay1 > 0")->sum('pay1')); + foreach($data as &$vo){ + if($vo['status'] == '0') $vo['time2'] = '未返款'; + } + } +} diff --git a/application/akszadmin/controller/Item.php b/application/akszadmin/controller/Item.php new file mode 100755 index 0000000..6725470 --- /dev/null +++ b/application/akszadmin/controller/Item.php @@ -0,0 +1,132 @@ +title = '项目管理'; + $query = $this->_query($this->table)->equal('type,class')->like('title'); + $query->order('sort asc,id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->mlist = Db::name('LcItemClass')->select(); + $this->tlist = Db::name('LcItemType')->select(); + foreach ($data as &$vo) { + list($vo['pay_type'], $vo['item_class']) = [[], []]; + foreach ($this->tlist as $type) if ($type['id'] == $vo['type']) $vo['pay_type'] = $type; + foreach ($this->mlist as $class) if ($class['id'] == $vo['class']) $vo['item_class'] = $class; + $vo['percent'] = model('akszadmin/item')->getProjectPercent($vo['id']); + } + } + + /** + * 添加项目 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加项目'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑项目 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑项目'; + $this->_form($this->table, 'form'); + } + + /** + * 删除项目 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isGet()) { + $vo['prize'] = isset($vo['prize'])?$vo['prize']:0; + $vo['integral'] = isset($vo['integral'])?$vo['integral']:0; + if (empty($vo['class']) && $this->request->get('class', '0')) $vo['class'] = $this->request->get('class', '0'); + if (empty($vo['type']) && $this->request->get('type', '0')) $vo['type'] = $this->request->get('type', '0'); + $this->class = Db::name("LcItemClass")->order('id asc')->select(); + $this->type = Db::name("LcItemType")->order('id asc')->select(); + } + if ($this->request->isPost()) { + if($vo['type']==2&&$vo['day']<7) $this->error("每周返息期限需大于等于7天"); + if($vo['type']==3&&$vo['day']<30) $this->error("每月返息期限需大于等于30天"); + } + if (empty($vo['add_time'])) $vo['add_time'] = date("Y-m-d H:i:s"); + } + +} diff --git a/application/akszadmin/controller/ItemClass.php b/application/akszadmin/controller/ItemClass.php new file mode 100755 index 0000000..cb49ecc --- /dev/null +++ b/application/akszadmin/controller/ItemClass.php @@ -0,0 +1,121 @@ +title = '项目分类管理'; + $query = $this->_query($this->table)->like('name'); + $query->order('sort asc,id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->mlist = Db::name('LcUserMember')->select(); + foreach ($data as &$vo) { + list($vo['member']) = [[]]; + foreach ($this->mlist as $member) if ($member['id'] == $vo['member_id']) $vo['member'] = $member; + } + } + + /** + * 添加项目分类 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加项目分类'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑项目分类 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑项目分类'; + $this->_form($this->table, 'form'); + } + + /** + * 删除项目分类 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isGet()) { + if (empty($vo['member_id']) && $this->request->get('member_id', '0')) $vo['member_id'] = $this->request->get('member_id', '0'); + $this->member = Db::name("LcUserMember")->order('id desc')->select(); + } + if (empty($vo['add_time'])) $vo['add_time'] = date("Y-m-d H:i:s"); + } + +} diff --git a/application/akszadmin/controller/Login.php b/application/akszadmin/controller/Login.php new file mode 100755 index 0000000..702f7bc --- /dev/null +++ b/application/akszadmin/controller/Login.php @@ -0,0 +1,119 @@ +isLogin()) { + $this->redirect('@' . ADMIN_MODULE); + } else { + $this->title = '系统登录'; + $this->captcha_type = 'login_captcha'; + $this->captcha_token = Data::uniqidDateCode(18); + $this->app->session->set($this->captcha_type, $this->captcha_token); + $this->devmode = SystemService::instance()->checkRunMode('dev'); + $this->fetch(); + } + } else { + + $data = $this->_vali([ + 'username.require' => '登录账号不能为空!', + 'username.min:4' => '登录账号长度不能少于4位有效字符!', + 'password.require' => '登录密码不能为空!', + 'password.min:4' => '登录密码长度不能少于4位有效字符!', + 'verify.require' => '图形验证码不能为空!', + 'uniqid.require' => '图形验证标识不能为空!', + ]); + if (!CaptchaService::instance()->check($data['verify'], $data['uniqid'])) { + $this->error('图形验证码验证失败,请重新输入!'); + } + // 用户信息验证 + $map = ['is_deleted' => '0', 'username' => $data['username']]; + $user = Db::name('SystemUser')->where($map)->order('id desc')->find(); + if (empty($user)) { + $this->error('登录账号或密码错误,请重新输入1!'); + } + if (md5("{$user['password']}{$data['uniqid']}") !== $data['password']) { + $this->error('登录账号或密码错误,请重新输入2!'); + } + if (empty($user['status'])) { + $this->error('账号已经被禁用,请联系管理员!'); + } + Db::name('SystemUser')->where(['id' => $user['id']])->update([ + 'login_ip' => Request::ip(), + 'login_at' => Db::raw('now()'), + 'login_num' => Db::raw('login_num+1'), + ]); + $this->app->session->set('user', $user); + AdminService::instance()->apply(true); + sysoplog('系统管理', '用户登录系统后台成功'); + $this->success('登录成功', url('@' . ADMIN_MODULE)); + } + } + + /** + * 生成验证码 + * 需要指定类型及令牌 + */ + public function captcha() + { + $image = CaptchaService::instance(); + $this->type = input('type', 'captcha-type'); + $this->token = input('token', 'captcha-token'); + $captcha = ['image' => $image->getData(), 'uniqid' => $image->getUniqid()]; + if ($this->app->session->get($this->type) === $this->token) { + $captcha['code'] = $image->getCode(); + $this->app->session->delete($this->type); + } + $this->success('生成验证码成功', $captcha); + } + + /** + * 退出登录 + */ + public function out() + { + $this->app->session->clear(); + $this->app->session->destroy(); + $this->success('退出登录成功!', url('@' . ADMIN_MODULE . '/login')); + } + +} diff --git a/application/akszadmin/controller/Mall.php b/application/akszadmin/controller/Mall.php new file mode 100755 index 0000000..183a701 --- /dev/null +++ b/application/akszadmin/controller/Mall.php @@ -0,0 +1,116 @@ +title = '矿机管理'; + $query = $this->_query($this->table)->like('title'); + $query->order('sort asc,id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + + } + + /** + * 添加矿机 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加矿机'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑矿机 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑矿机'; + $this->_form($this->table, 'form'); + } + + /** + * 删除矿机 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isPost()) { + if($vo['total']<$vo['stock']) $this->error("矿机总量需大于剩余库存"); + if($vo['day_income']<$vo['cost']) $this->error("日总产出需大于日运维费"); + } + } + +} diff --git a/application/akszadmin/controller/MallInvest.php b/application/akszadmin/controller/MallInvest.php new file mode 100755 index 0000000..a0099b1 --- /dev/null +++ b/application/akszadmin/controller/MallInvest.php @@ -0,0 +1,61 @@ +title = '已投项目管理'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.type1#i_type1')->like('i.title#i_title,u.phone#u_phone')->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + } +} diff --git a/application/akszadmin/controller/MallInvestList.php b/application/akszadmin/controller/MallInvestList.php new file mode 100755 index 0000000..f6696ac --- /dev/null +++ b/application/akszadmin/controller/MallInvestList.php @@ -0,0 +1,65 @@ +title = '已租矿机管理'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.iid#i_iid')->like('i.title#i_title,u.phone#u_phone')->dateBetween('i.time1#i_time1')->order('i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->refund = sprintf("%.2f",Db::name('LcInvestList')->where("status = 1 AND pay1 > 0")->sum('pay1')); + foreach($data as &$vo){ + if($vo['status'] == '0') $vo['time2'] = '挖矿中'; + } + } +} diff --git a/application/akszadmin/controller/Member.php b/application/akszadmin/controller/Member.php new file mode 100755 index 0000000..a7b72c7 --- /dev/null +++ b/application/akszadmin/controller/Member.php @@ -0,0 +1,93 @@ +title = '会员等级管理'; + $query = $this->_query($this->table)->like('name'); + $query->order('id asc')->page(); + } + + /** + * 添加会员组 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加会员组'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑会员组 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑会员组'; + $this->_form($this->table, 'form'); + } + + /** + * 删除会员组 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + +} diff --git a/application/akszadmin/controller/Menu.php b/application/akszadmin/controller/Menu.php new file mode 100755 index 0000000..0c62c26 --- /dev/null +++ b/application/akszadmin/controller/Menu.php @@ -0,0 +1,160 @@ +title = '系统菜单管理'; + $this->_page($this->table, false); + } + + /** + * 列表数据处理 + * @param array $data + */ + protected function _index_page_filter(&$data) + { + foreach ($data as &$vo) { + if ($vo['url'] !== '#') { + $vo['url'] = trim(url($vo['url']) . (empty($vo['params']) ? '' : "?{$vo['params']}"), '/\\'); + } + $vo['ids'] = join(',', Data::getArrSubIds($data, $vo['id'])); + } + $data = Data::arr2table($data); + } + + /** + * 添加系统菜单 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 编辑系统菜单 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _form_filter(&$vo) + { + if ($this->request->isGet()) { + // 读取系统功能节点 + $this->nodes = MenuService::instance()->getList(); + // 选择自己的上级菜单 + if (empty($vo['pid']) && $this->request->get('pid', '0')) $vo['pid'] = $this->request->get('pid', '0'); + // 列出可选上级菜单 + $menus = Db::name($this->table)->where(['status' => '1'])->order('sort desc,id asc')->column('id,pid,url,title'); + $this->menus = Data::arr2table(array_merge($menus, [['id' => '0', 'pid' => '-1', 'url' => '#', 'title' => '顶部菜单']])); + if (isset($vo['id'])) foreach ($this->menus as $key => $menu) if ($menu['id'] === $vo['id']) $vo = $menu; + foreach ($this->menus as $key => &$menu) { + if ($menu['spt'] >= 3 || $menu['url'] !== '#') unset($this->menus[$key]); + if (isset($vo['spt']) && $vo['spt'] <= $menu['spt']) unset($this->menus[$key]); + } + } + } + + /** + * 启用系统菜单 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function resume() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '1']); + } + + /** + * 禁用系统菜单 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function forbid() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '0']); + } + + /** + * 删除系统菜单 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + +} diff --git a/application/akszadmin/controller/Msg.php b/application/akszadmin/controller/Msg.php new file mode 100755 index 0000000..f8f219f --- /dev/null +++ b/application/akszadmin/controller/Msg.php @@ -0,0 +1,121 @@ +title = '站内信列表'; + $query = $this->_query($this->table)->like('phone'); + $query->dateBetween('add_time')->order('sort asc,id dasc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + foreach($data as &$vo){ + if(empty($vo['phone'])) $vo['phone'] = "所有人"; + } + } + + /** + * 添加站内信 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加站内信'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑站内信 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑站内信'; + $this->_form($this->table, 'form'); + } + + /** + * 删除站内信 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isGet()) { + if(!isset($vo['top'])) $vo['top'] = '0'; + } + if($this->request->isPost()) { + if($vo['phone']) $vo['uid'] = Db::name('LcUser')->where("phone = '{$vo['phone']}'")->value('id'); + } + if (empty($vo['add_time'])) $vo['add_time'] = date("Y-m-d H:i:s"); + } +} diff --git a/application/akszadmin/controller/Oplog.php b/application/akszadmin/controller/Oplog.php new file mode 100755 index 0000000..6d0aa24 --- /dev/null +++ b/application/akszadmin/controller/Oplog.php @@ -0,0 +1,94 @@ +title = '系统操作日志'; + $query = $this->_query($this->table)->like('action,node,content,username,geoip'); + $query->dateBetween('create_at')->order('id desc')->page(); + } + + /** + * 列表数据处理 + * @auth true + * @param array $data + * @throws \Exception + */ + protected function _index_page_filter(&$data) + { + $ip = new \Ip2Region(); + foreach ($data as &$vo) { + $result = $ip->btreeSearch($vo['geoip']); + $vo['isp'] = isset($result['region']) ? $result['region'] : ''; + $vo['isp'] = str_replace(['内网IP', '0', '|'], '', $vo['isp']); + } + } + + /** + * 清理系统日志 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function clear() + { + if (Db::name($this->table)->whereRaw('1=1')->delete() !== false) { + $this->success('日志清理成功!'); + } else { + $this->error('日志清理失败,请稍候再试!'); + } + } + + /** + * 删除系统日志 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + +} diff --git a/application/akszadmin/controller/Order.php b/application/akszadmin/controller/Order.php new file mode 100755 index 0000000..21b2942 --- /dev/null +++ b/application/akszadmin/controller/Order.php @@ -0,0 +1,130 @@ +title = '持仓列表'; + $this->type = $this->request->param('type'); + + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name as u_name'); + $query->leftjoin('lc_user u','i.uid=u.id')->like('u.phone#u_phone,u.name#u_name')->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } + + /** + * 编辑持仓 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '查看'; + $this->_form($this->table, 'form'); + } + public function edits() + { + if(\think\facade\Request::isPost()){ + $param = \think\facade\Request::param(); + $id=$param['id']; + if($param['pid']){ + $title=Db::name('LcProduct')->where(['id'=>$param['pid']])->value('title'); + }; + + $datac['uid']=$param['uid']; + $datac['pid']=$param['pid']; + $datac['ptitle']=$title; + $datac['ostyle']=$param['ostyle']; + $datac['buyprice']=$param['buyprice']; + $datac['sellprice']=$param['sellprice']; + $datac['ploss']=$param['ploss']; + $datac['buytime']=strtotime($param['buytime']); + $datac['selltime']=strtotime($param['selltime']); + $this->_save($this->table, $datac); + } + $this->title = '编辑订单信息'; + $this->goods = Db::name('LcProduct')->field("id,title")->order("sort asc,id desc")->select(); + $this->_form($this->table, 'edits'); + } + + /** + * 改平仓 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function gaipingcang() + { + // $this->applyCsrfToken(); + $id = $this->request->param('id'); + $sellprice = $this->request->param('sellprice'); + + $this->_save($this->table, ['sellprice' => $sellprice]); + } + + /*单控操作*/ + public function dankong(){ + $id = $this->request->param('oid'); + $kong_type = $this->request->param('kong_type'); + if($kong_type==3 ){ + $risk = Db::name('LcRisk')->find(); + $this->_save($this->table, ['kong_type' => $kong_type,'endloss'=>$risk['qybl']]); + }else if($kong_type==4){ + $risk = Db::name('LcRisk')->find(); + $this->_save($this->table, ['kong_type' => $kong_type,'lossrate'=>$risk['qkbl']]); + }else{ + $this->_save($this->table, ['kong_type' => $kong_type]); + } + } + + public function remove() + { + if (in_array('10000', explode(',', $this->request->post('id')))) { + $this->error('系统超级账号禁止删除!'); + } + + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/OrderLog.php b/application/akszadmin/controller/OrderLog.php new file mode 100755 index 0000000..2daa7ce --- /dev/null +++ b/application/akszadmin/controller/OrderLog.php @@ -0,0 +1,50 @@ +title = '平仓日志列表'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name as u_name'); + $query->leftjoin('lc_user u','i.uid=u.id')->like('u.phone#u_phone,u.name#u_name')->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } +} diff --git a/application/akszadmin/controller/Prize.php b/application/akszadmin/controller/Prize.php new file mode 100755 index 0000000..ef1cfa0 --- /dev/null +++ b/application/akszadmin/controller/Prize.php @@ -0,0 +1,49 @@ +title = '抽奖设置'; + $this->_form($this->table, 'form'); + } +} diff --git a/application/akszadmin/controller/PrizeList.php b/application/akszadmin/controller/PrizeList.php new file mode 100755 index 0000000..14e3d55 --- /dev/null +++ b/application/akszadmin/controller/PrizeList.php @@ -0,0 +1,89 @@ +title = '抽奖记录'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name as u_name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.type#i_type')->like('u.phone#u_phone,u.name#u_name')->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } + + /** + * 增减余额 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function add(){ + $this->title = '添加抽奖记录'; + $this->_form($this->table, 'form'); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if($this->request->isPost()){ + if(!$vo['phone']) $this->error("用户账号必填"); + if(!$vo['name']) $this->error("奖品名称必填"); + $uid = Db::name("LcUser")->where(['phone'=>$vo['phone']])->value('id'); + if(!$uid) $this->error("暂无该用户"); + $vo['uid'] = $uid; + $vo['time'] = date('Y-m-d H:i:s'); + } + } + + /** + * 删除抽奖记录 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Queue.php b/application/akszadmin/controller/Queue.php new file mode 100755 index 0000000..b203d62 --- /dev/null +++ b/application/akszadmin/controller/Queue.php @@ -0,0 +1,144 @@ +message = Console::call('xtask:state')->fetch(); + $this->command = ProcessService::instance()->think('xtask:start'); + $this->listen = preg_match('/process.*?\d+.*?running/', $this->message, $attr); + } catch (\Exception $exception) { + $this->listen = false; + $this->message = $exception->getMessage(); + } + $this->title = '系统任务管理'; + $this->iswin = ProcessService::instance()->iswin(); + $query = $this->_query($this->table)->dateBetween('create_at,start_at,end_at'); + $query->like('title,preload')->equal('status')->order('id desc')->page(); + } + + /** + * 重启系统任务 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function redo() + { + $this->_save($this->table, ['status' => '1']); + } + + /** + * WIN开始监听任务 + * @auth true + */ + public function start() + { + try { + $message = nl2br(Console::call('xtask:start')->fetch()); + if (preg_match('/process.*?\d+/', $message, $attr)) { + $this->success('任务监听主进程启动成功!'); + } else { + $this->error($message); + } + } catch (HttpResponseException $exception) { + throw $exception; + } catch (\Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * WIN停止监听任务 + * @auth true + */ + public function stop() + { + try { + $message = nl2br(Console::call('xtask:stop')->fetch()); + if (stripos($message, 'succeeded')) { + $this->success('停止任务监听主进程成功!'); + } elseif (stripos($message, 'finish')) { + $this->success('没有找到需要停止的进程!'); + } else { + $this->error($message); + } + } catch (HttpResponseException $exception) { + throw $exception; + } catch (\Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * 清理3天前的记录 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function clear() + { + $map = [['time', '<', strtotime('-3days')]]; + $result = Db::name($this->table)->where($map)->delete(); + if ($result !== false) { + $this->success('成功清理3天前的任务记录!'); + } else { + $this->error('清理3天前的任务记录失败!'); + } + } + + /** + * 删除系统任务 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->_delete($this->table); + } + +} diff --git a/application/akszadmin/controller/Recharge.php b/application/akszadmin/controller/Recharge.php new file mode 100755 index 0000000..daa0d05 --- /dev/null +++ b/application/akszadmin/controller/Recharge.php @@ -0,0 +1,175 @@ +title = '充值记录'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.status#i_status')->like('i.orderid#i_orderid,i.type#i_type,u.phone#u_phone,u.name#u_name')->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->type = Db::name($this->table)->field('type')->group('type')->select(); + $this->rejected = sprintf("%.2f",Db::name($this->table)->where("status = 2")->sum('money')); + $this->finished = sprintf("%.2f",Db::name($this->table)->where("status = 1")->sum('money')); + $this->reviewed = sprintf("%.2f",Db::name($this->table)->where("status = 0")->sum('money')); + } + public function edit() + { + $this->applyCsrfToken(); + if($this->request->isPost()) { + $id = $this->request->param('id'); + $reaolae = $this->request->param('reaolae'); + $this->_save($this->table, ['reaolae'=>$reaolae,'status' => '2','time2' => date('Y-m-d H:i:s')]); + }else{ + $this->title = '拒绝充值'; + $id = $this->request->param('id'); + $recharge = Db::name($this->table)->find($id); + if($recharge){ + $recharge['username'] = Db::name("LcUser")->where(['id'=>$recharge['uid']])->value('phone'); + } + $this->_form($this->table, 'edit'); + } + } + /** + * 同意充值 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function agree() + { + $this->applyCsrfToken(); + $id = $this->request->param('id'); + $recharge = Db::name($this->table)->find($id); + if($recharge&&$recharge['status'] == 0){ + $money = $recharge['money']; + $uid = $recharge['uid']; + $type = $recharge['type']; + addFinance($uid, $money,1, $type . '入款' . $money . '元'); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + $rechargeMoney = Db::name('LcFinance')->where('uid = '.$uid.' and reason like "%入款%"')->sum('money'); + $level = Db::name('LcUserMember')->where('value <='.$rechargeMoney.' ')->order('level desc')->find(); + if (!empty($level)){ + Db::name('LcUser')->where('id', $uid)->update([ + 'level' => $level['level'], + 'member' => $level['id'], + ]); + } +// if($tid) setRechargeRebate($tid, $money); + if(getInfo('pay_bank_give') > 0 && $recharge['type'] == '银行入款'){ + $money = $money * getInfo('pay_bank_give') /100; + addFinance($uid, $money, 1, '通过'.$type . '奖励' . $money . '元'); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + } + if(getInfo('gz_bankz') > 0 && $recharge['type'] == '公账入款'){ + $money = $money * getInfo('gz_bankz') /100; + addFinance($uid, $money, 1, '通过'.$type . '奖励' . $money . '元'); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + } + if(getInfo('wx_bank_give') > 0 && $recharge['type'] == '微信转银行卡'){ + $money = $money * getInfo('wx_bank_give') /100; + addFinance($uid, $money, 1, '通过'.$type . '奖励' . $money . '元'); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + } + if(getInfo('alipay_bank_give') > 0 && $recharge['type'] == '支付宝转银行卡'){ + $money = $money * getInfo('alipay_bank_give') /100; + addFinance($uid, $money, 1, '通过'.$type . '奖励' . $money . '元'); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + } + $this->_save($this->table, ['status' => '1','time2' => date('Y-m-d H:i:s')]); + } + } + + /** + * 增减余额 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function change(){ + if(\think\facade\Request::isPost()){ + $data = $this->request->param(); + if(!$data['name']) $this->error("用户账号必填"); + if(!$data['money']) $this->error("增减金额必填"); + $uid = Db::name("LcUser")->where(['phone'=>$data['name']])->value('id'); + if(!$uid) $this->error("暂无该用户"); + addFinance($uid, $data['money'], $data['type'], $data['reason']); + setNumber('LcUser', 'money', $data['money'], $data['type'], "id = $uid"); + $this->success("操作成功"); + } + $this->fetch('form'); + } + + /** + * 拒绝充值 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function refuse() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '2','time2' => date('Y-m-d H:i:s')]); + } + + /** + * 删除充值记录 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Shop.php b/application/akszadmin/controller/Shop.php new file mode 100755 index 0000000..4051a0a --- /dev/null +++ b/application/akszadmin/controller/Shop.php @@ -0,0 +1,116 @@ +title = '商品列表'; + $query = $this->_query($this->table)->like('title'); + $query->order('sort asc,id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->mlist = Db::name('LcArticleType')->select(); + } + + /** + * 添加商品 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加商品'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑商品 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑商品'; + $this->_form($this->table, 'form'); + } + + /** + * 删除商品 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isGet()) { + if(!isset($vo['type'])) $vo['type'] = '1'; + } + } + +} diff --git a/application/akszadmin/controller/ShopOrder.php b/application/akszadmin/controller/ShopOrder.php new file mode 100755 index 0000000..5d16cfd --- /dev/null +++ b/application/akszadmin/controller/ShopOrder.php @@ -0,0 +1,62 @@ +title = '兑换列表'; + $query = $this->_query($this->table)->alias('i')->field('i.*,u.phone,u.name as u_name'); + $query->join('lc_user u','i.uid=u.id')->equal('i.type#i_type')->like('u.phone#u_phone,u.name#u_name')->dateBetween('i.time#i_time')->order('i.id desc')->page(); + } + + /** + * 删除兑换 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Slide.php b/application/akszadmin/controller/Slide.php new file mode 100755 index 0000000..24a8615 --- /dev/null +++ b/application/akszadmin/controller/Slide.php @@ -0,0 +1,103 @@ +title = '轮播图列表'; + $query = $this->_query($this->table); + $query->order('sort asc,id asc')->page(); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \ReflectionException + */ + protected function _form_filter(&$vo){ + if ($this->request->isGet()) { + if(!isset($vo['show'])) $vo['show'] = '1'; + } + } + + /** + * 添加轮播图 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->title = '添加轮播图'; + $this->_form($this->table, 'form'); + } + + /** + * 编辑轮播图 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->title = '编辑轮播图'; + $this->_form($this->table, 'form'); + } + + /** + * 删除轮播图 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Sms.php b/application/akszadmin/controller/Sms.php new file mode 100755 index 0000000..d6feca1 --- /dev/null +++ b/application/akszadmin/controller/Sms.php @@ -0,0 +1,90 @@ +title = '短信模板管理'; + $query = $this->_query($this->table)->like('type'); + $query->order('id asc')->page(); + } + + /** + * 编辑短信 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 启用短信 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function resume() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '1']); + } + + /** + * 关闭短信 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function forbid() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '0']); + } + +} diff --git a/application/akszadmin/controller/User.php b/application/akszadmin/controller/User.php new file mode 100755 index 0000000..a1b7f73 --- /dev/null +++ b/application/akszadmin/controller/User.php @@ -0,0 +1,202 @@ +title = '系统用户管理'; + $query = $this->_query($this->table)->like('username,phone,mail')->equal('status'); + $query->dateBetween('login_at,create_at')->where(['is_deleted' => '0'])->order('id desc')->page(); + } + + /** + * 添加系统用户 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 编辑系统用户 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 修改用户密码 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function pass() + { + + $this->applyCsrfToken(); + if ($this->request->isGet()) { + $this->verify = false; + $this->_form($this->table, 'pass'); + } else { + $post = $this->request->post(); + if ($post['password'] !== $post['repassword']) { + $this->error('两次输入的密码不一致!'); + } + if (Data::save($this->table, ['id' => $_SESSION['fw']['user']['id'], 'password' => md5($post['password'])], 'id')) { + $this->success('密码修改成功,下次请使用新密码登录!', ''); + } else { + $this->error('密码修改失败,请稍候再试!'); + } + } + } + + /** + * 后台加密 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function suffix() { + $this->applyCsrfToken(); + $adminModuleFile = env('root_path') . '/admin_module.php'; + if ($this->request->isGet()) { + if (file_exists($adminModuleFile)) { + $this->adminModule = include $adminModuleFile; + } + return $this->fetch(); + } else { + $suffix = $this->request->post('suffix'); + if (!preg_match('/^([0-9a-zA-Z]+)$/', $suffix)) { + $this->error('后台加密后缀只能包含数字/大小写英文!'); + } + if (file_put_contents($adminModuleFile, "success('后台加密后缀修改成功!', url("@$suffix")); + } else { + $this->error('后台加密后缀修改失败,请稍候再试!'); + } + } + } + + /** + * 表单数据处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function _form_filter(&$data) + { + if ($this->request->isPost()) { + // 用户权限处理 + $data['authorize'] = (isset($data['authorize']) && is_array($data['authorize'])) ? join(',', $data['authorize']) : ''; + // 用户账号重复检查 + if (isset($data['id'])) unset($data['username']); + elseif (Db::name($this->table)->where(['username' => $data['username'], 'is_deleted' => '0'])->count() > 0) { + $this->error("账号{$data['username']}已经存在,请使用其它账号!"); + } + } else { + $data['authorize'] = explode(',', isset($data['authorize']) ? $data['authorize'] : ''); + $this->authorizes = Db::name('SystemAuth')->where(['status' => '1'])->order('sort desc,id desc')->select(); + } + } + + /** + * 禁用系统用户 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function forbid() + { + if (in_array('10000', explode(',', $this->request->post('id')))) { + $this->error('系统超级账号禁止操作!'); + } + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '0']); + } + + /** + * 启用系统用户 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function resume() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['status' => '1']); + } + + /** + * 删除系统用户 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + if (in_array('10000', explode(',', $this->request->post('id')))) { + $this->error('系统超级账号禁止删除!'); + } + $this->applyCsrfToken(); + $this->_delete($this->table); + } + +} diff --git a/application/akszadmin/controller/Users.php b/application/akszadmin/controller/Users.php new file mode 100755 index 0000000..990d192 --- /dev/null +++ b/application/akszadmin/controller/Users.php @@ -0,0 +1,281 @@ +title = '会员列表'; + $query = $this->_query($this->table)->alias('u')->field('u.*,m.name as m_name'); + if (input('get.online_user/d') === 1) { + $query->order('u.access_time', 'desc'); + } + $query->join('lc_user_member m', + 'u.member=m.id')->equal('u.auth#u_auth,u.clock#u_clock,u.member#u_member') + ->like('u.ip#i_orderid,u.phone#u_phone,u.name#u_name,u.ip#u_ip') + ->dateBetween('u.time#u_time') + ->order('u.id desc')->page(); + } + + /** + * 状态 开启或者关闭 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function iskqopen() + { + + $id = $this->request->param('id'); + $iskq = $this->request->param('iskq'); + $this->_save($this->table, ['isjy' => $iskq]); + } + + /** + * 数据列表处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + protected function _index_page_filter(&$data) + { + $this->member = Db::name("lc_user_member")->field('id,name')->select(); + $ip = new \Ip2Region(); + foreach ($data as &$vo) { + $vo['online'] = $vo['access_time'] > (time() - 300) ? 1 : 0; + $vo['top'] = Db::name("lc_user")->where("id = {$vo['top']}")->value('phone'); + $vo['cash_sum'] = Db::name("lc_cash")->where("uid = {$vo['id']} AND status = '1'")->sum('money'); + $vo['recharge_sum'] = Db::name("lc_recharge")->where("uid = {$vo['id']} AND status = '1'")->sum('money'); + $vo['invest_sum'] = Db::name('lc_invest')->where("uid = {$vo['id']}")->sum('money'); + $vo['wait_invest'] = Db::name('lc_invest_list')->where("uid = {$vo['id']} AND pay1 > 0 AND status = 0")->sum('money1'); + $vo['wait_money'] = Db::name('lc_invest_list')->where("uid = {$vo['id']} AND money2 > 0 AND status = 0")->sum('money2'); + $result = $ip->btreeSearch($vo['ip']); + $vo['isp'] = isset($result['region']) ? $result['region'] : ''; + $vo['isp'] = str_replace(['内网IP', '0', '|'], '', $vo['isp']); + $result2 = $ip->btreeSearch($vo['loginip']); + $vo['isp2'] = isset($result2['region']) ? $result2['region'] : ''; + $vo['isp2'] = str_replace(['内网IP', '0', '|'], '', $vo['isp2']); + } + } + + public function user_relation() + { + $this->title = '会员关系网'; + if ($this->request->isGet()) { + $list = []; + $phone = $this->request->param('phone'); + $type = $this->request->param('type'); + if ($type == 1) { + $top = Db::name('LcUser')->where(['phone' => $phone])->value('top'); + if ($top) { + $list = Db::name('LcUser')->where(['id' => $top])->select(); + } + } else { + $uid = Db::name('LcUser')->where(['phone' => $phone])->value('id'); + if ($uid) { + $list = Db::name('LcUser')->where(['top' => $uid])->select(); + } + } + if ($list) { + foreach ($list as &$v) { + $vo['top_phone'] = ''; + if ($v['top']) { + $vo['top_phone'] = Db::name('LcUser')->where(['id' => $v['top']])->value('phone'); + } + } + } + $this->assign('list', $list); + } + $this->fetch(); + } + + /** + * 表单数据处理 + * @param array $data + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function _form_filter(&$vo) + { + if ($this->request->isPost()) { + + if ($vo['mwpassword']) { + $vo['password'] = md5($vo['mwpassword']); + } + if ($vo['mwpassword2']) { + $vo['password2'] = md5($vo['mwpassword2']); + } + if (isset($vo['id'])) { + $money = Db::name($this->table)->where("id = {$vo['id']}")->value('money'); + if ($money && $money != $vo['money']) { + $handle_money = $money - $vo['money']; + $type = $handle_money > 0 ? 2 : 1; + model('akszadmin/Users')->addFinance($vo['id'], abs($handle_money), $type, '系统操作'); + } + if (!empty($vo['bank'])) { + Db::name("LcBank")->where('uid', $vo['id'])->update([ + 'bank' => $vo['bank'], + 'area' => $vo['area'], + 'account' => $vo['account'] + ]); + } + + } else { + $vo['time'] = date('Y-m-d H:i:s'); + } + } else { + if (!isset($vo['auth'])) { + $vo['auth'] = '0'; + } + $this->member = Db::name("LcUserMember")->order('id desc')->select(); + + } + } + + /** + * 添加用户 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function add() + { + $this->applyCsrfToken(); + $this->_form($this->table, 'form'); + } + + /** + * 编辑用户 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function edit() + { + $this->applyCsrfToken(); + + $uid = $this->request->param('id'); + + $this->bankinfo = Db::name("LcBank")->where("uid = {$uid}")->order('id desc')->find(); + + $this->_form($this->table, 'form'); + } + /** + * 实名认证审核 + * @auth true + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function review() + { + $this->title = '实名认证审核'; + $this->id = input('id'); + if ($this->request->isGet()) { + $user = Db::name("LcUser")->where("id = {$this->id}")->find(); + $this->assign('user', $user); + $this->fetch(); + }else{ + $id = input('id'); + $rz_status = input('rz_status'); + $name = input('name'); + $idcard = input('idcard'); + $res = Db::name("LcUser")->where("id = {$id}")->update(['name'=>$name,'idcard'=>$idcard,'rz_status'=>$rz_status]); + if($res){ + $this->success('审核成功'); + }else{ + $this->error('审核失败'); + } + } + } + + /** + * 禁用用户 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function forbid() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['clock' => '0']); + } + + /** + * 启用用户 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function resume() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['clock' => '1']); + } + + public function setrobot() + { + $this->applyCsrfToken(); + $this->_save($this->table, ['robot' => $_POST['clock']]); + } + + /** + * 删除用户 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function remove() + { + $this->applyCsrfToken(); + $this->_delete($this->table); + } +} diff --git a/application/akszadmin/controller/Yuebao.php b/application/akszadmin/controller/Yuebao.php new file mode 100755 index 0000000..8e34ffa --- /dev/null +++ b/application/akszadmin/controller/Yuebao.php @@ -0,0 +1,220 @@ +where('id',">",0)->select(); + $query = $this->_query('lc_yuebao')->where("id > 0 and status < 5"); + $query->order('id desc')->page(); + //$this->assign('list',$list); + $this->fetch(); + + } + + /** + * 删除记录 + * @auth true + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function lists() + { + $list=Db::name('lc_yuebao_lists')->where("status < 5")->order('id desc')->select(); + $lists=array(); + foreach($list as $x=>$v){ + $v['start_time']=date('Y-m-d H:i:s',$v['start_time']); + $v['end_time']=date('Y-m-d H:i:s',$v['end_time']); + $lists[$x]=$v; + } + $counttotal=count($list); + $counttotalmoney=Db::name('lc_yuebao_lists')->where("status = 1")->sum('money'); + $countdoing=Db::name('lc_yuebao_lists')->where("status = 1")->count(); + $countnosend=Db::name('lc_yuebao_lists')->where("status = 1")->sum('nowprofit'); + $countsended=Db::name('lc_yuebao_log')->where("status = 2")->sum('nowprofit'); + //$list=$lists; + $this->assign('list',$lists); + $this->assign('counttotal',$counttotal); + $this->assign('counttotalmoney',round($counttotalmoney,4)); + $this->assign('countdoing',$countdoing); + $this->assign('countnosend',round($countnosend,4)); + $this->assign('countsended',round($countsended,4)); + $query = $this->_query('lc_yuebao_lists')->where("status < 5"); + $query->order('id desc')->page(); + //var_dump($list);die; + + + $this->fetch(); + //$this->fetch(); + } + public function yebdel(){ + if($_SESSION['fw']['user']['username']=="admin"){ + Db::name('lc_yuebao')->where("id = ".$_GET['id'])->update(['status'=>9]); + return "OK"; + }else{ + return "false"; + } + + } + public function yebstop(){ + if($_SESSION['fw']['user']['username']=="admin"){ + $getstatus=Db::name('lc_yuebao')->where("id = ".$_GET['id'])->find(); + if($getstatus['status']==0) Db::name('lc_yuebao')->where("id = ".$_GET['id'])->update(['status'=>1]); + if($getstatus['status']==1) Db::name('lc_yuebao')->where("id = ".$_GET['id'])->update(['status'=>0]); + //Db::name('lc_yuebao')->where("id = ".$_GET['id'])->update(['status'=>0]); + return "OK"; + }else{ + return "false"; + } + + } + public function yebadd(){ + if($_SESSION['fw']['user']['username']!="admin"){return "非法访问";exit;die;} + if(empty($_POST)){return "数据错误!";exit;die;} + $adddata=array( + 'title'=>$_POST['title'], + 'lily'=>$_POST['lily'], + 'days'=>$_POST['days'], + 'advise'=>0, + 'lowmoney'=>$_POST['lowmoney'], + 'stars'=>$_POST['stars'], + 'addtime'=>time(), + 'status'=>$_POST['status'], + ); + $ok=Db::name('lc_yuebao')->insert($adddata); + return $ok==1?"OK":"false";die; + } + public function yebedit(){ + if($_SESSION['fw']['user']['username']!="admin"){return "非法访问";exit;die;} + if(empty($_POST)){return "数据错误!";exit;die;} + $adddata=array( + 'title'=>$_POST['title'], + 'lily'=>$_POST['lily'], + 'days'=>$_POST['days'], + 'advise'=>0, + 'lowmoney'=>$_POST['lowmoney'], + 'stars'=>$_POST['stars'], + 'addtime'=>time(), + 'status'=>$_POST['status'], + ); + $ok=Db::name('lc_yuebao')->where('id = '.$_POST['yebid'])->update($adddata); + return $ok==1?"OK":"false";die; + } + public function yebgetbyid(){ + $res=Db::name('lc_yuebao')->where('id = '.$_GET['id'])->find(); + return $res; + } + + public function listclear(){ + if($_SESSION['fw']['user']['username']!="admin"){return "非法访问";exit;die;} + if(empty($_POST)){return "数据错误!";exit;die;} + + $getlistinfo=Db::table('lc_yuebao_lists')->where('id='.$_POST['id'])->find(); + if($getlistinfo['status']!=1 or empty($getlistinfo)){return "操作失败:订单无法操作!";die;} + + $getuserinfo=Db::table('lc_user')->where('id='.$getlistinfo['uid'])->find(); + if(!empty($getuserinfo)){ + Db::table('lc_yuebao_lists')->where('id='.$_POST['id'])->update(['status'=>2,'end_time'=>time()]); + //记录日志! + unset($getlistinfo['id']); + $getlistinfo['status']=2; + $getlistinfo['end_time']=time(); + $getlistinfo['balance']=$getuserinfo['money']; + $getlistinfo['closetime']=time(); + $getlistinfo['remarks']="管理员".$_SESSION['fw']['user']['username']."人工结算"; + Db::table('lc_yuebao_log')->insert($getlistinfo); + //更新用户余额 + $newbalance=$getuserinfo['money']+$getlistinfo['nowprofit']+$getlistinfo['money']; + Db::table('lc_user')->where('id='.$getlistinfo['uid'])->update(['money'=>$newbalance]); + + //更新UC + $where['uid']=$getlistinfo['uid']; + $yebucinfo=Db::table('lc_yuebao_uc')->where($where)->find(); + $newbalance=$yebucinfo['balance']-$getlistinfo['money']; + Db::table('lc_yuebao_uc')->where($where)->update(['balance'=>$newbalance]); + + //再做UCLOG + $yebuclog=array( + 'uid'=>$getlistinfo['uid'], + 'balance'=>$yebucinfo['balance'], + 'money'=>$getlistinfo['money'], + 'addtime'=>time(), + 'remarks'=>"用户购买理财方案:".$getlistinfo['yebtitle'] + ); + Db::table('lc_yuebao_uclog')->insert($yebuclog); + + return "ok"; + + }else{ + return "操作失败:订单无法操作!"; + } + die; + + + //更新参保状态。 + + } + + public function listkeep(){ + if($_SESSION['fw']['user']['username']!="admin"){return "非法访问";exit;die;} + if(empty($_POST)){return "数据错误!";exit;die;} + $getlistinfo=Db::table('lc_yuebao_lists')->where('id='.$_POST['id'])->find(); + if($getlistinfo['status']==2){ + $getlistinfo['start_time']=time(); + $getlistinfo['end_time']=time()+$getlistinfo['days']*86400; + $getlistinfo['status']=1; + $getlistinfo['nowprofit']=0; + }elseif($getlistinfo['status']==1){ + $getlistinfo['end_time']=$getlistinfo['end_time']+$getlistinfo['days']*86400; + } + unset($getlistinfo['id']); + Db::table('lc_yuebao_lists')->where('id='.$_POST['id'])->update($getlistinfo); + return "操作成功";die; + } + public function listdel(){ + if($_SESSION['fw']['user']['username']!="admin"){return "非法访问";exit;die;} + if(empty($_POST)){return "数据错误!";exit;die;} + Db::name('lc_yuebao')->where("id = ".$_GET['id'])->update(['status'=>9]); + return "OK";die; + + } +} diff --git a/application/akszadmin/controller/api/Plugs.php b/application/akszadmin/controller/api/Plugs.php new file mode 100755 index 0000000..d718d39 --- /dev/null +++ b/application/akszadmin/controller/api/Plugs.php @@ -0,0 +1,150 @@ +title = '图标选择器'; + $this->field = input('field', 'icon'); + $this->fetch(); + } + + /** + * 获取文件上传参数 + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function check() + { + $diff1 = explode(',', strtolower(input('exts', ''))); + $diff2 = explode(',', strtolower(sysconf('storage_local_exts'))); + $exts = array_intersect($diff1, $diff2); + $this->success('获取文件上传参数', [ + 'exts' => join('|', $exts), + 'mime' => File::mine($exts), + 'type' => $this->getUploadType(), + 'data' => $this->getUploadData(), + ]); + } + + /** + * 后台通用文件上传 + * @login true + * @return \think\response\Json + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function upload() + { + if (!($file = $this->getUploadFile()) || empty($file)) { + return json(['uploaded' => false, 'error' => ['message' => '文件上传异常,文件可能过大或未上传']]); + } + if (!$file->checkExt(strtolower(sysconf('storage_local_exts')))) { + return json(['uploaded' => false, 'error' => ['message' => '文件上传类型受限,请在后台配置']]); + } + if ($file->checkExt('php,sh')) { + return json(['uploaded' => false, 'error' => ['message' => '可执行文件禁止上传到本地服务器']]); + } + $this->safe = boolval(input('safe')); + $this->uptype = $this->getUploadType(); + $this->extend = pathinfo($file->getInfo('name'), PATHINFO_EXTENSION); + if ($this->uptype === 'local' && GdImageClass::isSupportSuffix($this->extend)) { + try { + (new GdImageClass($file->getRealPath(),$this->extend))->convertTo($file->getRealPath(), 'webp'); + $file= new \think\File($file->getRealPath()); + $this->extend = 'webp'; + } catch (\Exception $exception) { + return json(['uploaded' => false, 'error' => ['message' => '文件处理失败: ' . $exception->getMessage()]]); + } + } + /** @noinspection DuplicatedCode */ + $name = File::name($file->getPathname(), $this->extend, '', 'md5_file'); + $info = File::instance($this->uptype)->save($name, file_get_contents($file->getRealPath()), $this->safe); + if (is_array($info) && isset($info['url'])) { + return json(['uploaded' => true, 'filename' => $name, 'url' => $this->safe ? $name : $info['url']]); + } else { + return json(['uploaded' => false, 'error' => ['message' => '文件处理失败,请稍候再试!']]); + } + } + + /** + * 生成文件上传参数 + * @return array + * @throws \think\Exception + */ + private function getUploadData() + { + if ($this->getUploadType() === 'qiniu') { + $file = File::instance('qiniu'); + return [ + 'url' => $file->upload(true), + 'token' => $file->buildUploadToken(), + 'uptype' => $this->getUploadType() + ]; + } else { + return [ + 'url' => '?s=' . ADMIN_MODULE . '/api.plugs/upload', + 'token' => uniqid('local_upload_'), + 'uptype' => $this->getUploadType() + ]; + } + } + + /** + * 获取文件上传方式 + * @return string + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + private function getUploadType() + { + $this->uptype = input('uptype'); + if (!in_array($this->uptype, ['local', 'oss', 'qiniu'])) { + $this->uptype = sysconf('storage_type'); + } + return $this->uptype; + } + + /** + * 获取本地文件对象 + * @return \think\File + */ + private function getUploadFile() + { + try { + return $this->request->file('file'); + } catch (\Exception $e) { + $this->error(lang($e->getMessage())); + } + } + +} diff --git a/application/akszadmin/controller/api/Update.php b/application/akszadmin/controller/api/Update.php new file mode 100755 index 0000000..30dc0f1 --- /dev/null +++ b/application/akszadmin/controller/api/Update.php @@ -0,0 +1,60 @@ +success('获取当前文件列表成功!', $sync->build()); + } + + /** + * 读取线上文件数据 + * @param string $encode + */ + public function read($encode) + { + $this->file = env('root_path') . decode($encode); + if (file_exists($this->file)) { + $this->success('读取文件成功!', [ + 'format' => 'base64', + 'content' => base64_encode(file_get_contents($this->file)), + ]); + } else { + $this->error('获取文件内容失败!'); + } + } + +} diff --git a/application/akszadmin/model/Item.php b/application/akszadmin/model/Item.php new file mode 100755 index 0000000..5ed7975 --- /dev/null +++ b/application/akszadmin/model/Item.php @@ -0,0 +1,53 @@ +item_table)->find($id); + if($item['auto']>0){ + $xc=$this->diffBetweenTwoDays($item['time'],date('Y-m-d H:i:s')); + if($xc>$item['auto']){ + $total=100; + }else{ + $total= round($xc/$item['auto']*100); + } + }else{ + $pid = $item['id']; + $percent = $item['percent']; + $investMoney = Db::name($this->invest_table)->where('pid', $pid)->sum('money'); + $actual = $investMoney / ($item['total'] * 10000) * 100; + $total = $actual + $percent; + } + if (100 < $total) return 100; + return $total; + } + + public function diffBetweenTwoDays ($day1, $day2) + { + $second1 = strtotime($day1); + $second2 = strtotime($day2); + if ($second1 < $second2) { + $tmp = $second2; + $second2 = $second1; + $second1 = $tmp; + } + return ($second1 - $second2) / 86400; + } +} diff --git a/application/akszadmin/model/Users.php b/application/akszadmin/model/Users.php new file mode 100755 index 0000000..94dc345 --- /dev/null +++ b/application/akszadmin/model/Users.php @@ -0,0 +1,48 @@ +user_table)->find($uid); + if($user['money']<0) return false; + if(!$user) return false; + $data = array( + 'uid' => $uid, + 'money' => $money, + 'type' => $type, + 'reason' => $reason, + 'before' => $user['money'], + 'time' => date('Y-m-d H:i:s') + ); + Db::startTrans(); + $re = Db::name($this->finance_table)->insert($data); + if($re){ + Db::commit(); + return true; + }else{ + Db::rollback(); + return false; + } + } +} diff --git a/application/akszadmin/sys.php b/application/akszadmin/sys.php new file mode 100755 index 0000000..7ada068 --- /dev/null +++ b/application/akszadmin/sys.php @@ -0,0 +1,195 @@ +check($node); + } +} + +if (!function_exists('sysdata')) { + /** + * JSON 数据读取与存储 + * @param string $name 数据名称 + * @param mixed $value 数据内容 + * @return mixed + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + function sysdata($name, $value = null) + { + if (is_null($value)) { + return SystemService::instance()->getData($name); + } else { + return SystemService::instance()->setData($name, $value); + } + } +} + +if (!function_exists('sysoplog')) { + /** + * 写入系统日志 + * @param string $action 日志行为 + * @param string $content 日志内容 + * @return boolean + */ + function sysoplog($action, $content) + { + return SystemService::instance()->setOplog($action, $content); + } +} + +if (!function_exists('sysqueue')) { + /** + * 创建异步处理任务 + * @param string $title 任务名称 + * @param string $loade 执行内容 + * @param integer $later 延时执行时间 + * @param array $data 任务附加数据 + * @param integer $double 任务多开 + * @return boolean + * @throws \think\Exception + */ + function sysqueue($title, $loade, $later = 0, $data = [], $double = 1) + { + $map = [['title', 'eq', $title], ['status', 'in', [1, 2]]]; + if (empty($double) && Db::name('SystemQueue')->where($map)->count() > 0) { + throw new \think\Exception('该任务已经创建,请耐心等待处理完成!'); + } + $result = Db::name('SystemQueue')->insert([ + 'title' => $title, 'preload' => $loade, + 'data' => json_encode($data, JSON_UNESCAPED_UNICODE), + 'time' => $later > 0 ? time() + $later : time(), + 'double' => intval($double), 'create_at' => date('Y-m-d H:i:s'), + ]); + return $result !== false; + } +} + +if (!function_exists('local_image')) { + /** + * 下载远程文件到本地 + * @param string $url 远程图片地址 + * @param boolean $force 是否强制重新下载 + * @param integer $expire 强制本地存储时间 + * @return string + */ + function local_image($url, $force = false, $expire = 0) + { + $result = File::down($url, $force, $expire); + if (isset($result['url'])) { + return $result['url']; + } else { + return $url; + } + } +} + +if (!function_exists('base64_image')) { + /** + * base64 图片上传接口 + * @param string $content 图片base64内容 + * @param string $dirname 图片存储目录 + * @return string + */ + function base64_image($content, $dirname = 'base64/') + { + try { + if (preg_match('|^data:image/(.*?);base64,|i', $content)) { + list($ext, $base) = explode('|||', preg_replace('|^data:image/(.*?);base64,|i', '$1|||', $content)); + $info = File::save($dirname . md5($base) . '.' . (empty($ext) ? 'tmp' : $ext), base64_decode($base)); + return $info['url']; + } else { + return $content; + } + } catch (\Exception $e) { + return $content; + } + } +} + +/** + * @description:充值奖励 + * @date: 2020/5/14 0014 + * @param $tid + * @param $money + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function setRechargeRebate($tid, $money) +{ + $reward = Db::name('LcReward')->where(['id'=>1])->value("recharge"); + $rebate = round($reward * $money / 100, 2); + if (0 < $rebate) { + addFinance($tid, $rebate, 1, '推荐会员充值' . $money . '元,获得佣金' . $rebate . '元'); + setNumber('LcUser', 'money', $rebate, 1, "id = $tid"); + setNumber('LcUser', 'income', $rebate, 1, "id = $tid"); + } +} + +// 访问权限检查中间键 +Middleware::add(function (Request $request, \Closure $next) { + if (AdminService::instance()->check()) { + return $next($request); + } elseif (AdminService::instance()->isLogin()) { + return json(['code' => 0, 'msg' => '抱歉,没有访问该操作的权限!']); + } else { + return json(['code' => 0, 'msg' => '抱歉,需要登录获取访问权限!', 'url' => url('@akszadmin/login')]); + } +}); + function curl2post($url,$data){ + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); //设置访问的url地址 + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + $data && curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $tmpInfo = curl_exec($ch); + if (curl_errno($ch)) { + return curl_error($ch); + } + curl_close($ch); + return $tmpInfo; + } + +// ThinkAdmin 图形验证码 +Route::get('/think/akszadmin/captcha', function () { + $image = CaptchaService::instance(); + return json(['code' => '1', 'info' => '生成验证码', 'data' => [ + 'uniqid' => $image->getUniqid(), 'image' => $image->getData() + ]]); +}); diff --git a/application/akszadmin/view/api/plugs/icon.html b/application/akszadmin/view/api/plugs/icon.html new file mode 100755 index 0000000..d7dd5f2 --- /dev/null +++ b/application/akszadmin/view/api/plugs/icon.html @@ -0,0 +1,3659 @@ + + + + + {block name="title"}{$title|default=''}{if !empty($title)} · {/if}{:sysconf('site_name')}{/block} + + + + + + + + + + + + + + + + + + + + diff --git a/application/akszadmin/view/article/form.html b/application/akszadmin/view/article/form.html new file mode 100755 index 0000000..be2a7ee --- /dev/null +++ b/application/akszadmin/view/article/form.html @@ -0,0 +1,92 @@ +{extend name='akszadmin@main'} + +{block name="content"} + +
+ +
+ +
+ + + +
+ +
+ + +
+ +
+ 文章内容 + +
+ +
+ {notempty name='vo.id'}{/notempty} + + +
+ +
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/article/index.html b/application/akszadmin/view/article/index.html new file mode 100755 index 0000000..52bad78 --- /dev/null +++ b/application/akszadmin/view/article/index.html @@ -0,0 +1,88 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/article/add")} + +{/if} +{if auth("akszadmin/article/remove")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='article/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + {/foreach} + +
+ + + + 文章标题文章类型语言文章状态发布时间
+ + + + + {$vo.title|default='--'} + + {$vo.name|default='--'} + + {$vo.lang|default='--'} + + {if $vo.show == 1} + 显示 + {/if} + {if $vo.show == 0} + 不显示 + {/if} + + {$vo.time|default='--'} + + +
+ {if auth("akszadmin/article/edit")} + 编 辑 + {else} + 编 辑 + {/if} + {if auth("akszadmin/article/remove")} + 删 除 + {else} + 删 除 + {/if} + +
+ +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/article/index_search.html b/application/akszadmin/view/article/index_search.html new file mode 100755 index 0000000..68848fb --- /dev/null +++ b/application/akszadmin/view/article/index_search.html @@ -0,0 +1,33 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/article_type/class_search.html b/application/akszadmin/view/article_type/class_search.html new file mode 100755 index 0000000..d32a606 --- /dev/null +++ b/application/akszadmin/view/article_type/class_search.html @@ -0,0 +1,15 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/article_type/form.html b/application/akszadmin/view/article_type/form.html new file mode 100755 index 0000000..ffd1957 --- /dev/null +++ b/application/akszadmin/view/article_type/form.html @@ -0,0 +1,32 @@ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/article_type/index.html b/application/akszadmin/view/article_type/index.html new file mode 100755 index 0000000..c9e9252 --- /dev/null +++ b/application/akszadmin/view/article_type/index.html @@ -0,0 +1,61 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/article_type/add")} + +{/if} +{if auth("remove")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='article_type/class_search'} + + {notempty name='list'} + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + {/foreach} + +
+ + + + 分类名称添加时间
+ + + + + {$vo.name|default=''} + {$vo.add_time} + + {if auth("akszadmin/article_type/edit")} + 编 辑 + {/if} + + {if auth("akszadmin/article_type/remove")} + 删 除 + {/if} + +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/auth/apply.html b/application/akszadmin/view/auth/apply.html new file mode 100755 index 0000000..fd07add --- /dev/null +++ b/application/akszadmin/view/auth/apply.html @@ -0,0 +1,116 @@ +{extend name='main'} + +{block name="button"} + +{if auth("akszadmin/auth/refresh")} + +{/if} + +{/block} + +{block name="content"} +
+ +
+
+ + +
+
+{/block} + +{block name="script"} + +{/block} + +{block name="style"} + + + +{/block} \ No newline at end of file diff --git a/application/akszadmin/view/auth/form.html b/application/akszadmin/view/auth/form.html new file mode 100755 index 0000000..58387dd --- /dev/null +++ b/application/akszadmin/view/auth/form.html @@ -0,0 +1,30 @@ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+ + +
+
\ No newline at end of file diff --git a/application/akszadmin/view/auth/index.html b/application/akszadmin/view/auth/index.html new file mode 100755 index 0000000..af11a73 --- /dev/null +++ b/application/akszadmin/view/auth/index.html @@ -0,0 +1,80 @@ +{extend name='main'} + +{block name="button"} + +{if auth("akszadmin/auth/add")} + +{/if} + +{if auth("akszadmin/auth/remove")} + +{/if} + +{/block} + +{block name="content"} + +
+ {include file='auth/index_search'} + + {notempty name='list'} + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + {/foreach} + +
+ + 权限信息创建时间使用状态
+ + + 权限名称:{$vo.title|default='-'}
+

权限描述:{$vo.desc|default="没有写描述哦!"}

+
+ 日期:{$vo.create_at|format_datetime|str_replace=' ','
时间:',###|raw} +
+ {eq name='vo.status' value='0'}已禁用{else}使用中{/eq} + + + {if auth("akszadmin/auth/edit")} + | + 编 辑 + {/if} + + {if auth("akszadmin/auth/apply")} + 授 权 + {/if} + + {if $vo.status eq 1 and auth("akszadmin/auth/forbid")} + 禁 用 + {elseif $vo.status eq 0 and auth("akszadmin/auth/resume")} + 启 用 + {/if} + + {if auth("akszadmin/auth/remove")} + 删 除 + {/if} + +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+ +{/block} diff --git a/application/akszadmin/view/auth/index_search.html b/application/akszadmin/view/auth/index_search.html new file mode 100755 index 0000000..2547555 --- /dev/null +++ b/application/akszadmin/view/auth/index_search.html @@ -0,0 +1,42 @@ +
+ 条件搜索 + +
+ + \ No newline at end of file diff --git a/application/akszadmin/view/bank/form.html b/application/akszadmin/view/bank/form.html new file mode 100755 index 0000000..0a951fe --- /dev/null +++ b/application/akszadmin/view/bank/form.html @@ -0,0 +1,24 @@ +
+ +
+
+ + +
+ +
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/bank/index.html b/application/akszadmin/view/bank/index.html new file mode 100755 index 0000000..4bd42fd --- /dev/null +++ b/application/akszadmin/view/bank/index.html @@ -0,0 +1,69 @@ +{extend name='akszadmin@main'} +{block name="button"} +{if auth("remove")} + +{/if} +{/block} +{block name="content"} +
+ {include file='bank/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + + {/foreach} + +
+ + 编号会员ID用户名开户姓名所属银行支行名称银行卡号操作
+ + + {$vo.id|default='--'} + + {$vo.uid|default='--'} + + {$vo.phone|default='--'} + + {$vo.u_name|default='--'} + + {$vo.bank|default='--'} + + {$vo.area|default='--'} + + {$vo.account|default='--'} + + {if auth("akszadmin/article_type/edit")} + 编 辑 + {/if} + {if auth("remove")} + 删 除 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/bank/index_search.html b/application/akszadmin/view/bank/index_search.html new file mode 100755 index 0000000..c08aeba --- /dev/null +++ b/application/akszadmin/view/bank/index_search.html @@ -0,0 +1,27 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/cash/edit.html b/application/akszadmin/view/cash/edit.html new file mode 100755 index 0000000..e03b2a3 --- /dev/null +++ b/application/akszadmin/view/cash/edit.html @@ -0,0 +1,50 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+
+ +
+ +
+
+ +
+ +
+ 拒绝理由 + + +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+
+{/block} +{block name='script'} + +{/block} \ No newline at end of file diff --git a/application/akszadmin/view/cash/index.html b/application/akszadmin/view/cash/index.html new file mode 100755 index 0000000..6c8415e --- /dev/null +++ b/application/akszadmin/view/cash/index.html @@ -0,0 +1,122 @@ +{extend name='akszadmin@main'} +{block name="button"} +{if auth("remove")} + +{/if} +{/block} +{block name="content"} +
+ {include file='cash/index_search'} + + + {notempty name='list'} + + + + + + + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + + + + + + + + {/foreach} + +
+ + 编号账户姓名提现金额(元)手续费实际到账(元)开户银行拒绝原因提交时间处理进度操作
+ + + {$vo.id|default='--'} + + {$vo.phone|default='--'} + + {$vo.name|default='--'} + + {$vo.money|default='--'} + + {$vo.sxfbfb|default='--'}% + + {$vo.dzje|default='--'} + + 账户名称:{$vo.name|default='--'} + {if $vo.bid == 0} +
{$vo.bank|default='--'} +
支付宝账号:{$vo.account|default='--'} + {else/} +
开户银行:{$vo.bank|default='--'} +
支行名称:{$vo.area|default='--'} +
银行账号:{$vo.account|default='--'} + {/if} +
+ + {$vo.reaolae|default='审核通过'} + + + {$vo.time|default='--'} + + {if $vo.status == 0} + 待审核 + {/if} + {if $vo.status == 1} + 已完成 + {/if} + {if $vo.status == 2} + 已拒绝 + {/if} + + {if auth("akszadmin/invest_list/detail")} + 查看详情 + {/if} + {if $vo.status eq 0} + {if auth("agree")} + 同 意 + {/if} + {if auth("refuse")} + 拒 绝 + + {/if} + {else} + 删 除 + {/if} + + +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/cash/index_search.html b/application/akszadmin/view/cash/index_search.html new file mode 100755 index 0000000..27e8821 --- /dev/null +++ b/application/akszadmin/view/cash/index_search.html @@ -0,0 +1,41 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/config/info.html b/application/akszadmin/view/config/info.html new file mode 100755 index 0000000..b363c50 --- /dev/null +++ b/application/akszadmin/view/config/info.html @@ -0,0 +1,88 @@ +{extend name="main"} + +{block name="button"} + +{if auth('config')} +修改系统配置 +{/if} + +{/block} + +{block name="content"} + +
+ 文件存储引擎: + {foreach ['local'=>'本地服务器存储','qiniu'=>'七牛云对象存储','oss'=>'阿里云OSS存储'] as $k=>$v} + {if sysconf('storage_type') eq $k} + {if auth('file')}{$v}{else}{$v}{/if} + {elseif auth('file')}{$v}{/if} + {/foreach} +
+ +
+
+ 平台邀请码 + +

平台邀请码(可修改)

+
+
+ 网站名称 Website + +

网站名称及网站图标,将显示在浏览器的标签上

+
+
+ 管理程序名称 Name + +

管理程序名称,将显示在后台左上角标题

+
+
+ 管理程序版本 Version + +

管理程序版本,将显示在后台左上角标题

+
+ +
+ 网站备案号 Miitbeian + +

网站备案号,可以在备案管理中心查询获取,将显示在登录页面下面

+
+
+ 网站版权信息 Copyright + +

网站版权信息,在后台登录页面显示版本信息并链接到备案到信息备案管理系统

+
+
+{/block} + +{block name='style'} + +{/block} \ No newline at end of file diff --git a/application/akszadmin/view/config/storage-local.html b/application/akszadmin/view/config/storage-local.html new file mode 100755 index 0000000..84b802d --- /dev/null +++ b/application/akszadmin/view/config/storage-local.html @@ -0,0 +1,20 @@ +
+
+
+

文件将存储在本地服务器,需确保服务器的 public/upload 目录有写入权限,有足够的存储空间!

+
+
+ +
+ +

设置系统允许上传文件的后缀,多个以英文逗号隔开。如:png,jpg,rar,doc

+
+
+
+
+ + + +
+
+
\ No newline at end of file diff --git a/application/akszadmin/view/config/storage-oss.html b/application/akszadmin/view/config/storage-oss.html new file mode 100755 index 0000000..7496bbf --- /dev/null +++ b/application/akszadmin/view/config/storage-oss.html @@ -0,0 +1,80 @@ +
+
+
+

文件将上传到阿里云OSS空间,需要配置OSS公开访问及跨域策略!

+ 目前已实现自动创建空间及配置访问策略!我要免费申请 +
+
+ +
+ +

设置系统允许上传文件的后缀,多个以英文逗号隔开。如:png,jpg,rar,doc

+
+
+
+ +
+ {foreach ['http','https','auto'] as $pro} + + {/foreach} +

阿里云对象存储访问协议(http、https、auto),其中 https 需要配置证书才能使用,auto 为相对协议自动根据域名切换http与https。

+
+
+
+ +
+ +

填写OSS存储空间名称,如:think-admin-oss(需要是全区唯一的值,不存在时会自动创建)

+
+
+
+ +
+ +

请选择OSS数据中心访问节点,有效值如:oss-cn-shenzhen.aliyuncs.com

+
+
+
+ +
+ +

可以在 [ 阿里云 > 个人中心 ] 设置并获取到访问密钥。

+
+
+
+ +
+ +

可以在 [ 阿里云 > 个人中心 ] 设置并获取到安全密钥。

+
+
+
+ +
+ +

填写OSS存储外部访问域名,如:think-admin-oss.oss-cn-shenzhen.aliyuncs.com(正常情况下是自动获取的)

+
+
+
+
+ + + +
+
+ +
diff --git a/application/akszadmin/view/config/storage-qiniu.html b/application/akszadmin/view/config/storage-qiniu.html new file mode 100755 index 0000000..7b5c5f6 --- /dev/null +++ b/application/akszadmin/view/config/storage-qiniu.html @@ -0,0 +1,80 @@ +
+
+
+

文件将上传到七牛云存储,对象存储需要配置为公开访问的Bucket空间!

+ 完成实名认证后可获得10G免费存储空间哦!我要免费申请 +
+
+ +
+ +

设置系统允许上传文件的后缀,多个以英文逗号隔开。如:png,jpg,rar,doc

+
+
+
+ +
+ {foreach ['http','https','auto'] as $pro} + + {/foreach} +

七牛云存储访问协议,其中 https 需要配置证书才能使用,auto 为相对协议。

+
+
+
+ +
+ {foreach ['华东','华北','华南','北美'] as $area} + + {/foreach} +

七牛云存储空间所在区域,需要严格对应储存所在区域才能上传文件。

+
+
+
+ +
+ +

填写七牛云存储空间名称,如:static

+
+
+
+ +
+ +

填写七牛云存储访问域名,如:static.ctolog.cc

+
+
+
+ +
+ +

可以在 [ 七牛云 > 个人中心 ] 设置并获取到访问密钥。

+
+
+
+ +
+ +

可以在 [ 七牛云 > 个人中心 ] 设置并获取到安全密钥。

+
+
+
+
+ + + +
+
+
\ No newline at end of file diff --git a/application/akszadmin/view/config/system-config.html b/application/akszadmin/view/config/system-config.html new file mode 100755 index 0000000..8a0d64a --- /dev/null +++ b/application/akszadmin/view/config/system-config.html @@ -0,0 +1,28 @@ +
+
+ +
+ +

平台邀请码

+
+
+ +

网站名称,将在浏览器的标签上显示名称

+
+ +
+ +
+ + +
+
+ +
+ diff --git a/application/akszadmin/view/finance/index.html b/application/akszadmin/view/finance/index.html new file mode 100755 index 0000000..a10addf --- /dev/null +++ b/application/akszadmin/view/finance/index.html @@ -0,0 +1,65 @@ +{extend name='akszadmin@main'} +{block name="button"} +{if auth("remove")} + +{/if} +{/block} +{block name="content"} +
+ {include file='finance/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + + {/foreach} + +
+ + 流水编号交易对象真实姓名交易金额(元)交易前余额(元)详情流水时间
+ + + {$vo.id} + + {$vo.phone} + + {$vo.name} + + {if $vo.type == 1} + +{$vo.money} + {else} + -{$vo.money} + {/if} + + {$vo.before} + + {$vo.reason} + + {$vo.time} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/finance/index_search.html b/application/akszadmin/view/finance/index_search.html new file mode 100755 index 0000000..a3bc2f0 --- /dev/null +++ b/application/akszadmin/view/finance/index_search.html @@ -0,0 +1,47 @@ +
+ 条件搜索 + + +
\ No newline at end of file diff --git a/application/akszadmin/view/goods/form.html b/application/akszadmin/view/goods/form.html new file mode 100755 index 0000000..d064b14 --- /dev/null +++ b/application/akszadmin/view/goods/form.html @@ -0,0 +1,218 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+
+
+ +
+
+ +
+
+ +
+
+ 产品图标 + + + + + + +
+ +
+ +
+
+

注意: 客户订单在条件范围内时,会根据订单的涨或跌,自动减或加最小值与最大值之间的随机数,留空或者0则为不开启

+
+ + +
+
+
+

注意: 产品获取接口值后,会加上+-此处的值。如5,则在接口获取的数据中加上-5~5之间的随机数。

+
+ +
+
+
+

注意: 填0表示不显示

+
+ + + + +
+
+
+

投资金额【以 | 符号隔开】

+
+ + + + +
+
+
+

注意: 填入比例区间,例如:2或者2.1-2.2

+
+ + + + +
+
+
+

注意: 填入比例区间,例如:2或者2.1-2.2

+
+ + + + +
+
+
+

注意: 填入比例区间,例如:0.01-0.10

+
+ + + +
+
+
+

注意:开市时间,精准到秒,如:00:00:00~03:00:00|08:00:00~23:59:59 不得出现中文符号,全天不开市请留空

+
+ + + + + + + +
+
+ 产品备注 + +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+
+{/block} +{block name='script'} + +{/block} \ No newline at end of file diff --git a/application/akszadmin/view/goods/index.html b/application/akszadmin/view/goods/index.html new file mode 100755 index 0000000..5157da3 --- /dev/null +++ b/application/akszadmin/view/goods/index.html @@ -0,0 +1,97 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/goods/add")} + +{/if} +{if auth("akszadmin/goods/remove")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='goods/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + + + {/foreach} + +
+ + + + 产品标题门槛产品代码状态随机值风控最小值风控最大值操作
+ + + + + {$vo.title|default='--'} + + {$vo.min|default='0'} + + {$vo.code|default='--'} + + {if $vo.isopen == 1} 开市 {else /} 休市 {/if} + + {$vo.rands|default='--'} + + {$vo.point_low|default='--'} + + {$vo.point_top|default='--'} + +
+ {if auth("akszadmin/goods/edit")} + {if $vo.iskq == 1} + 开启 + {else /} + 关闭 + {/if} + + {if $vo.isopen == 1} + 点击休市 + {else /} + 点击开市 + {/if} + 编 辑 + {/if} + {if auth("akszadmin/goods/remove")} + 删 除 + {/if} + {$vo.showps==1?"隐盈":"显盈"} + {$vo.showps2==1?"隐亏":"显亏"} +
+
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/goods/index_search.html b/application/akszadmin/view/goods/index_search.html new file mode 100755 index 0000000..643142a --- /dev/null +++ b/application/akszadmin/view/goods/index_search.html @@ -0,0 +1,15 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/goods/risk.html b/application/akszadmin/view/goods/risk.html new file mode 100755 index 0000000..0331439 --- /dev/null +++ b/application/akszadmin/view/goods/risk.html @@ -0,0 +1,86 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+
+
+
+

说明:比如设置几点到几点稳赢,如:14:20-15:30

+
+ +
+
+
+

说明:比如设置几点到几点稳输,如:18:10-18:30

+
+ +
+
+ + +
+
+ + +
+
+
+

说明: 此处设置会员ID(如:8888),多个用户用|符号分开(如:8888|9999)设置之后该会员所有订单都会亏损,请谨慎操作。如停止该功能请在上面留空或者填0,并提交。

+
+ +
+
+
+

说明: 此处设置会员ID(如:8888),多个用户用|符号分开(如:8888|9999)设置之后该会员所有订单都会赢利,请谨慎操作。如停止该功能请在上面留空或者填0,并提交。

+
+ +
+
+
+

说明: 下单达到此金额,则会受到下面风控影响。

+
+ +
+
+
+

说明: 输入金额区间,在金额区间之内会根据此概率盈亏。不在此区间则不受风控影响

+

格式: 区间开始-区间结束:客户赢利概率|  符号必须为英文符号,如0-100:50|100-200:30

+
+ +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+
+
+{/block} +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/index/index.html b/application/akszadmin/view/index/index.html new file mode 100755 index 0000000..9c925df --- /dev/null +++ b/application/akszadmin/view/index/index.html @@ -0,0 +1,242 @@ + + + + {block name="title"}{$title|default=''}{if !empty($title)} · {/if}{:sysconf('site_name')}{/block} + + + + + + + + + + + + {block name="style"}{/block} + + + + + + + +{block name='body'} +
+ +
+
+ + +
+ + + +
+ + + +
+
+ + {foreach $menus as $oneMenu} + {notempty name='oneMenu.sub'} + + {/notempty} + {/foreach} +
+
+ + + +
{block name='content'}{/block}
+ + +
+ +{/block} + + + + + +{block name='script'}{/block} + + + diff --git a/application/akszadmin/view/index/main.html b/application/akszadmin/view/index/main.html new file mode 100755 index 0000000..be54e6b --- /dev/null +++ b/application/akszadmin/view/index/main.html @@ -0,0 +1,200 @@ +{extend name='main'} + +{block name='content'} + + + +
+
数据统计
+
+
+
+
总盈亏
+
{:number_format($invest_count)}
+
当前盈亏总数
+
+ +
+
+
+
用户总量
+
{:number_format($user_count)}
+
当前用户总数量(人)
+
+ +
+
+
+
充值总额
+
{:number_format($recharge_sum)}
+
已支付充值订单总金额(元)
+
+ +
+
+
+
提现总额
+
{:number_format($cash_sum)}
+
已完成提现订单总金额(元)
+
+ +
+
+
+ +
+
实时概况
+
+
+
+
+ +
+
+
今日充值
+
{:number_format($day[$today_key]['recharge'],2)}
+
今日充值成功金额(元)
+
+
+
今日提现
+
{:number_format($day[$today_key]['cash'],2)}
+
今日提现成功金额(元)
+
+
+
+
+
+
+ +
+
+
今日新增
+
{$day[$today_key]['new_user']}
+
今日新增会员数(人)
+
+
+
在线人数
+
{$online_user}
+
当前在线会员数(人)
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
综合报表
备注入款出款首冲人数活跃人数客户盈亏
上月¥{:number_format($last_month['recharge'],2)}元¥{:number_format($last_month['cash'],2)}元{:$last_month['invest_list']}人0人¥{:number_format($last_month['invest_sum'],2)}元
本月{:number_format($month['recharge'],2)}元{:number_format($month['cash'],2)}元{:$month['invest_list']}人0人{:number_format($month['invest_sum'],2)}元
总计where('status = 1')->sum('money'),2);?>元where('status = 1')->sum('money'),2);?>元0人
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + {volist name="day" id="v"} + + + + + + + + + + + + {/volist} + +
本月明细
日期新增用户入款出款首冲人数活跃人数订单数量客户盈亏流水
{$v['date']}{$v['new_user']}人¥{:number_format($v['recharge'],2)}元{:number_format($v['cash'],2)}元{:$v['invest_list']}人0人{:$v['ordernumer']}条¥{:number_format($v['expire'],2)}元¥{:number_format($v['interest'],2)}元
+
+
+
+{/block} diff --git a/application/akszadmin/view/info/form.html b/application/akszadmin/view/info/form.html new file mode 100755 index 0000000..8e2d1b5 --- /dev/null +++ b/application/akszadmin/view/info/form.html @@ -0,0 +1,285 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+
+
+ + + +
+
+ + +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + +
+
+ + + + +
+
+ + + +
+
+ + +
+
+ + + + +
+ +
+ +
+ + + +
+ {notempty name='vo.id'}{/notempty} + +
+
+
+{/block} +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/info/img.html b/application/akszadmin/view/info/img.html new file mode 100755 index 0000000..70a85cf --- /dev/null +++ b/application/akszadmin/view/info/img.html @@ -0,0 +1,202 @@ +{extend name='akszadmin@main'} + +{block name="content"} + +
+
+
    +
  • 系统图片
  • + + +
+
+
+
+
+ 网站首页LOGO + + + + + + + + + +
260x70像素
+ +
+ +
+
+ APP图标 + + + + + + + + + +
100x100像素
+ +
+ +
+
+ 登录图标 + + + + + + + + + +
100x100像素
+ +
+ +
+
+ 新闻页面底部图标,png格式 + + + + + + + + + +
100x100像素
+ +
+ +
+
+ 公司章 + + + + + + + + + +
500x500像素,png格式
+ +
+ +
+
+ 保险章 + + + + + + + + + +
500x500像素,png格式
+ +
+ +
+
+
+ +
+
+
+ 活动图片 + + + + + + + + + +
活动图片地址
+ +
+
+ + +
+
+
+ +
+
+
+ 活动图片 + + + + + + + + + +
活动图片地址
+ +
+
+ + +
+
+
+ +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/info/pay.html b/application/akszadmin/view/info/pay.html new file mode 100755 index 0000000..6b25b86 --- /dev/null +++ b/application/akszadmin/view/info/pay.html @@ -0,0 +1,329 @@ +{extend name='akszadmin@main'} + +{block name="content"} + +
+
+
    +
  • 银行入款
  • + +
+
+
+
+
+ + + +
+
+ + + +
+
+ +
+
+
+ + + + +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/info/reward.html b/application/akszadmin/view/info/reward.html new file mode 100755 index 0000000..b6b146f --- /dev/null +++ b/application/akszadmin/view/info/reward.html @@ -0,0 +1,94 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+
+
+ + + +
+ +
+ + + +
+ +
+ + + +
+ + + + +
+ {notempty name='vo.id'}{/notempty} + +
+
+
+{/block} +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/invest/index.html b/application/akszadmin/view/invest/index.html new file mode 100755 index 0000000..eeaf381 --- /dev/null +++ b/application/akszadmin/view/invest/index.html @@ -0,0 +1,51 @@ +{extend name='akszadmin@main'} + +{block name="content"} +
+ {include file='invest/index_search'} + + {notempty name='list'} + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + {/foreach} + +
投资信息投资人投资数据投资时间
+ 项目名称:{$vo.title|default='--'}
+ 合同编号:{$vo.number|default='--'}
+ 还款类型:{$vo.type2|default='--'}
+
+ 投资人ID:{$vo.uid|default='--'}
+ 投资人姓名:{$vo.name|default='--'}
+ 投资人电话:{$vo.phone|default='--'}
+
+ 投资金额:{$vo.money|default='--'} 元
+ 费率:{$vo.rate|default='--'} %
+ 期限:{$vo.day|default='--'} 天
+
+ 投资时间:{$vo.time|default='--'}
+ +
+ {if auth("akszadmin/invest_list/detail")} + 查看详情 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/invest/index_search.html b/application/akszadmin/view/invest/index_search.html new file mode 100755 index 0000000..465bea5 --- /dev/null +++ b/application/akszadmin/view/invest/index_search.html @@ -0,0 +1,49 @@ +
+ 条件搜索 + + +
\ No newline at end of file diff --git a/application/akszadmin/view/invest_list/index.html b/application/akszadmin/view/invest_list/index.html new file mode 100755 index 0000000..e417ed5 --- /dev/null +++ b/application/akszadmin/view/invest_list/index.html @@ -0,0 +1,43 @@ +{extend name='akszadmin@main'} + +{block name="content"} +
+ {include file='invest_list/index_search'} + + {notempty name='list'} + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + {/foreach} + +
投资信息投资人投资数据投资时间
+ 项目名称:{$vo.title|default='--'}
+ 返款编号:{$vo.id|default='--'}
+
+ 投资人ID:{$vo.uid|default='--'}
+ 投资人姓名:{$vo.name|default='--'}
+ 投资人电话:{$vo.phone|default='--'}
+
+ 预计返款金额:{$vo.pay1|default='--'} 元
+ 实际返款金额:{$vo.pay2|default='--'} 元
+
+ 预计返款:{$vo.time1|default='--'}
+ 实际返款:{$vo.time2|default='--'}
+
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/invest_list/index_search.html b/application/akszadmin/view/invest_list/index_search.html new file mode 100755 index 0000000..203bbd2 --- /dev/null +++ b/application/akszadmin/view/invest_list/index_search.html @@ -0,0 +1,30 @@ +
+ 条件搜索 + + +
\ No newline at end of file diff --git a/application/akszadmin/view/item/form.html b/application/akszadmin/view/item/form.html new file mode 100755 index 0000000..b541f0b --- /dev/null +++ b/application/akszadmin/view/item/form.html @@ -0,0 +1,236 @@ +{extend name='akszadmin@main'} + +{block name="content"} + + +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + +
+ +
+ + + +
+ +
+ + + +
+ + +
+ 项目封面图片 + + + + + + + + + +
项目封面
+ +
+ +
+ 产品详情 + +
+ +
+ {notempty name='vo.id'}{/notempty} + + +
+ +
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/item/index.html b/application/akszadmin/view/item/index.html new file mode 100755 index 0000000..8644f18 --- /dev/null +++ b/application/akszadmin/view/item/index.html @@ -0,0 +1,81 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/item/add")} + +{/if} +{if auth("akszadmin/item/remove")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='item/index_search'} + + {notempty name='list'} + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + {/foreach} + +
+ + + + 项目信息项目分类项目配置其他配置
+ {$vo.title|default='--'}
+ 开始时间:{$vo.time|default='--'}
+
+ 所属分类:{$vo.item_class.name|default='--'}
+ 还款方式:{$vo.pay_type.name|default='--'}
+
+ 项目金额:{$vo.total|default='--'}万元
+ 收益率:{$vo.rate|default='--'}%
+ 项目期限:{$vo.day|default='--'}天
+
+ 项目进度:{$vo.percent|default='--'}%
+ 起投金额:{$vo.min|default='--'}元
+ 投资次数:{$vo.num|default='--'}次
+
+ +
+ {if auth("akszadmin/item/edit")} + 编 辑 + {else} + 编 辑 + {/if} + {if auth("akszadmin/item/remove")} + 删 除 + {else} + 删 除 + {/if} + +
+ +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/item/index_search.html b/application/akszadmin/view/item/index_search.html new file mode 100755 index 0000000..4bb4a1a --- /dev/null +++ b/application/akszadmin/view/item/index_search.html @@ -0,0 +1,45 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/item_class/class_search.html b/application/akszadmin/view/item_class/class_search.html new file mode 100755 index 0000000..d32a606 --- /dev/null +++ b/application/akszadmin/view/item_class/class_search.html @@ -0,0 +1,15 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/item_class/form.html b/application/akszadmin/view/item_class/form.html new file mode 100755 index 0000000..de5eb41 --- /dev/null +++ b/application/akszadmin/view/item_class/form.html @@ -0,0 +1,47 @@ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/item_class/index.html b/application/akszadmin/view/item_class/index.html new file mode 100755 index 0000000..7ff26e8 --- /dev/null +++ b/application/akszadmin/view/item_class/index.html @@ -0,0 +1,62 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/item_class/add")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='item_class/class_search'} + + {notempty name='list'} + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + {/foreach} + +
+ + + + 分类名称会员分组添加时间
+ + + + + {$vo.name|default=''} + + {$vo.member.name|default=''} + {$vo.add_time|format_datetime} + + {if auth("akszadmin/item_class/edit")} + 编 辑 + {/if} + + {if auth("akszadmin/item_class/remove")} + 删 除 + {/if} + +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/login/index.html b/application/akszadmin/view/login/index.html new file mode 100755 index 0000000..9612bf8 --- /dev/null +++ b/application/akszadmin/view/login/index.html @@ -0,0 +1,57 @@ +{extend name="index/index"} + +{block name="body"} +
+
+ {:sysconf('app_name')}{:sysconf('app_version')} + {notempty name='devmode'} + + Fork me on Gitee + + {/notempty} +
+
+

系统管理

+
    +
  • + +
  • +
  • + +
  • +
  • + + +
  • +
  • + +
  • +
+
+ +
+{/block} + +{block name='style'} + + + +{/block} + +{block name='script'} + + +{/block} diff --git a/application/akszadmin/view/main.html b/application/akszadmin/view/main.html new file mode 100755 index 0000000..b548b60 --- /dev/null +++ b/application/akszadmin/view/main.html @@ -0,0 +1,11 @@ +
+ {block name='style'}{/block} + {notempty name='title'} +
+ {$title|default=''} +
{block name='button'}{/block}
+
+ {/notempty} +
{block name='content'}{/block}
+ {block name='script'}{/block} +
\ No newline at end of file diff --git a/application/akszadmin/view/mall/form.html b/application/akszadmin/view/mall/form.html new file mode 100755 index 0000000..a2f4103 --- /dev/null +++ b/application/akszadmin/view/mall/form.html @@ -0,0 +1,118 @@ +{extend name='akszadmin@main'} + +{block name="content"} + + +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ 矿机封面图片 + + + + + + + + + +
矿机封面
+ +
+ +
+ 矿机详情 + +
+ +
+ {notempty name='vo.id'}{/notempty} + + +
+ +
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/mall/index.html b/application/akszadmin/view/mall/index.html new file mode 100755 index 0000000..a2c3421 --- /dev/null +++ b/application/akszadmin/view/mall/index.html @@ -0,0 +1,77 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/mall/add")} + +{/if} +{if auth("akszadmin/mall/remove")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='mall/index_search'} + + {notempty name='list'} + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + {/foreach} + +
+ + + + 矿机信息矿机配置其他配置
+ {$vo.title|default='--'}
+ 添加时间:{$vo.time|default='--'}
+ 使用期限:{$vo.day|default='--'}
+
+ 保证金:{$vo.min|default='--'}元
+ 日总产出:{$vo.day_income|default='--'} BTC/天
+ 日运维费:{$vo.cost|default='--'} BTC/天
+
+ 算力:{$vo.power|default='--'}TH/s
+ 矿机总量:{$vo.total|default='--'}份
+ 剩余矿机:{$vo.stock|default='--'}份
+
+ +
+ {if auth("akszadmin/mall/edit")} + 编 辑 + {else} + 编 辑 + {/if} + {if auth("akszadmin/mall/remove")} + 删 除 + {else} + 删 除 + {/if} + +
+ +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/mall/index_search.html b/application/akszadmin/view/mall/index_search.html new file mode 100755 index 0000000..adcb1e0 --- /dev/null +++ b/application/akszadmin/view/mall/index_search.html @@ -0,0 +1,15 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/mall_invest/index.html b/application/akszadmin/view/mall_invest/index.html new file mode 100755 index 0000000..1095b68 --- /dev/null +++ b/application/akszadmin/view/mall_invest/index.html @@ -0,0 +1,50 @@ +{extend name='akszadmin@main'} + +{block name="content"} +
+ {include file='mall_invest/index_search'} + + {notempty name='list'} + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + {/foreach} + +
租赁信息投资人投资数据时间
+ 矿机名称:{$vo.title|default='--'}
+ 日运维费:{$vo.cost|default='--'}
+
+ 投资人ID:{$vo.uid|default='--'}
+ 投资人姓名:{$vo.name|default='--'}
+ 投资人电话:{$vo.phone|default='--'}
+
+ 保证金:{$vo.money|default='--'} 元
+ 日净收益:{$vo.profit|default='--'} BTC
+ 使用期限:{$vo.day|default='--'} 天
+
+ 租赁时间:{$vo.time|default='--'}
+ 结束时间:{$vo.time2|default='--'}
+
+ {if auth("akszadmin/invest_list/detail")} + 查看详情 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/mall_invest/index_search.html b/application/akszadmin/view/mall_invest/index_search.html new file mode 100755 index 0000000..7d8d7ee --- /dev/null +++ b/application/akszadmin/view/mall_invest/index_search.html @@ -0,0 +1,27 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/mall_invest_list/index.html b/application/akszadmin/view/mall_invest_list/index.html new file mode 100755 index 0000000..fc7b505 --- /dev/null +++ b/application/akszadmin/view/mall_invest_list/index.html @@ -0,0 +1,43 @@ +{extend name='akszadmin@main'} + +{block name="content"} +
+ {include file='mall_invest_list/index_search'} + + {notempty name='list'} + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + {/foreach} + +
投资信息投资人投资数据投资时间
+ 矿机名称:{$vo.title|default='--'}
+ 挖矿编号:{$vo.id|default='--'}
+
+ 投资人ID:{$vo.uid|default='--'}
+ 投资人姓名:{$vo.name|default='--'}
+ 投资人电话:{$vo.phone|default='--'}
+
+ 预计收益:{$vo.pay1|default='--'} BTC
+ 实际收益:{$vo.pay2|default='--'} BTC
+
+ 预计收益时间:{$vo.time1|default='--'}
+ 实际收益时间:{$vo.time2|default='--'}
+
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/mall_invest_list/index_search.html b/application/akszadmin/view/mall_invest_list/index_search.html new file mode 100755 index 0000000..a80fa70 --- /dev/null +++ b/application/akszadmin/view/mall_invest_list/index_search.html @@ -0,0 +1,30 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/member/form.html b/application/akszadmin/view/member/form.html new file mode 100755 index 0000000..720b481 --- /dev/null +++ b/application/akszadmin/view/member/form.html @@ -0,0 +1,35 @@ +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/member/index.html b/application/akszadmin/view/member/index.html new file mode 100755 index 0000000..8a79d14 --- /dev/null +++ b/application/akszadmin/view/member/index.html @@ -0,0 +1,60 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/member/add")} + +{/if} +{if auth("remove")} + +{/if} +{/block} + +{block name="content"} +
+ + {notempty name='list'} + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + {/foreach} + +
+ + 会员组编号等级名称充值限制
+ + + {$vo.id|default=''} + + {$vo.name|default=''} + + {$vo.value|default=''} + + {if auth("akszadmin/member/edit")} + 编 辑 + {/if} + + {if auth("akszadmin/member/remove")} + 删 除 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/menu/form.html b/application/akszadmin/view/menu/form.html new file mode 100755 index 0000000..5aded12 --- /dev/null +++ b/application/akszadmin/view/menu/form.html @@ -0,0 +1,89 @@ +
+ +
+ +
+ +
+ +

必选,请选择上级菜单或顶级菜单(目前最多支持三级菜单)

+
+
+ +
+ +
+ +

必填,请填写菜单名称(如:系统管理),建议字符不要太长,一般4-6个汉字

+
+
+ +
+ +
+ +

+ 必填,请填写系统节点(如:admin/user/index),节点加入权限管理时菜单才会自动隐藏,非规则内的不会隐藏; +
正常情况下,在输入的时候会有自动提示。如果是上级菜单时,请填写"#"符号,不要填写地址或节点地址 +

+
+
+ +
+ +
+ +

可选,设置菜单链接的GET访问参数(如:name=1&age=3)

+
+
+ +
+ +
+
+ +
+ + + + +

可选,设置菜单选项前置图标,目前只支持 Font Awesome 5.2.0 字体图标

+
+
+ +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+ + +
+ +
+ +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/menu/index.html b/application/akszadmin/view/menu/index.html new file mode 100755 index 0000000..43b0ffc --- /dev/null +++ b/application/akszadmin/view/menu/index.html @@ -0,0 +1,80 @@ +{extend name='main'} + +{block name="button"} + +{if auth("add")} + +{/if} + +{if auth("remove")} + +{/if} + +{/block} + +{block name="content"} +
+ {empty name='list'} +
没 有 记 录 哦!
+ {else} + + + + + + + + + + + + + {foreach $list as $key=>$vo} + + + + + + + + + + {/foreach} + +
+ + + +
+ + + + {$vo.spl|raw}{$vo.title}{$vo.url}{eq name='vo.status' value='0'}已禁用{else}使用中{/eq} + + {if auth("add")} + | + + 添 加 + + 添 加 + + {/if} + + {if auth("edit")} + 编 辑 + {/if} + + {if $vo.status eq 1 and auth("forbid")} + 禁 用 + {elseif auth("resume")} + 启 用 + {/if} + + {if auth("remove")} + 删 除 + {/if} + +
+ {/empty} +
+{/block} diff --git a/application/akszadmin/view/msg/form.html b/application/akszadmin/view/msg/form.html new file mode 100755 index 0000000..37bf128 --- /dev/null +++ b/application/akszadmin/view/msg/form.html @@ -0,0 +1,72 @@ +{extend name='akszadmin@main'} + +{block name="content"} + +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ 站内信内容 + +
+ +
+ {notempty name='vo.id'}{/notempty} + + +
+ +
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/msg/index.html b/application/akszadmin/view/msg/index.html new file mode 100755 index 0000000..1101a44 --- /dev/null +++ b/application/akszadmin/view/msg/index.html @@ -0,0 +1,75 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/article/add")} + +{/if} +{if auth("akszadmin/article/remove")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='msg/index_search'} + + {notempty name='list'} + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + {/foreach} + +
+ + + + 信息标题接收账号发布时间
+ + + + + {$vo.title|default='--'} + + {$vo.phone|default='--'} + + {$vo.add_time|default='--'} + + +
+ {if auth("akszadmin/msg/edit")} + 编 辑 + {else} + 编 辑 + {/if} + {if auth("akszadmin/msg/remove")} + 删 除 + {else} + 删 除 + {/if} + +
+ +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/msg/index_search.html b/application/akszadmin/view/msg/index_search.html new file mode 100755 index 0000000..68cb9c7 --- /dev/null +++ b/application/akszadmin/view/msg/index_search.html @@ -0,0 +1,21 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/oplog/index.html b/application/akszadmin/view/oplog/index.html new file mode 100755 index 0000000..dfe3e41 --- /dev/null +++ b/application/akszadmin/view/oplog/index.html @@ -0,0 +1,68 @@ +{extend name='main'} + +{block name="button"} + +{if auth("clear")} + +{/if} + +{if auth("remove")} + +{/if} + +{/block} + +{block name="content"} +
+ {include file='oplog/index_search'} + + {notempty name='list'} + + + + + + + + + + + + {foreach $list as $key=>$vo} + + + + + + + + + {/foreach} + + {/notempty} +
+ + 操作权限操作行为地理位置操作时间
+ + + {$vo.username|default='-'}
+ {$vo.node|default='-'} +
+

{$vo.action|default='-'}

+

{$vo.content|default='-'}

+
+

{$vo.geoip|default='-'}

+

{$vo.isp|default='-'}

+
+ 日期:{$vo.create_at|format_datetime|str_replace=' ','
时间:',###|raw} +
+ {if auth("remove")} + 删 除 + {/if} +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+ +{/block} diff --git a/application/akszadmin/view/oplog/index_search.html b/application/akszadmin/view/oplog/index_search.html new file mode 100755 index 0000000..54341bb --- /dev/null +++ b/application/akszadmin/view/oplog/index_search.html @@ -0,0 +1,56 @@ +
+ + 条件搜索 + + + +
+ + \ No newline at end of file diff --git a/application/akszadmin/view/order/edits.html b/application/akszadmin/view/order/edits.html new file mode 100755 index 0000000..f14cd4b --- /dev/null +++ b/application/akszadmin/view/order/edits.html @@ -0,0 +1,95 @@ +
+ +
+ + +
+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} + + diff --git a/application/akszadmin/view/order/form.html b/application/akszadmin/view/order/form.html new file mode 100755 index 0000000..ea35640 --- /dev/null +++ b/application/akszadmin/view/order/form.html @@ -0,0 +1,71 @@ +{extend name='akszadmin@main'} + +{block name="content"} + +
+
+ +
+

{$vo.uid|default=''}

+
+
+ +
+ +
+

{$vo.orderno|default=''}

+
+
+
+ +
+

{$vo.ptitle|default=''}

+
+
+
+ +
+

{if $vo.ostaus == 1}平仓{else/}建仓{/if}

+
+
+
+ +
+

{$vo.buyprice}

+
+
+
+ +
+

{$vo.sellprice}

+
+
+
+ +
+

{$vo.fee}

+
+
+
+ +
+

{:date('Y-m-d H:i:s',$vo.buytime)}

+
+
+
+ +
+

{:date('Y-m-d H:i:s',$vo.selltime)}

+
+
+
+ +
+

{$vo.ploss}

+
+
+
+ +{/block} + + diff --git a/application/akszadmin/view/order/index.html b/application/akszadmin/view/order/index.html new file mode 100755 index 0000000..11d88a9 --- /dev/null +++ b/application/akszadmin/view/order/index.html @@ -0,0 +1,170 @@ +{extend name='akszadmin@main'} +{block name="content"} + +
+ {include file='order/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + {if $vo.ostyle == 0} + + {elseif $vo.ostyle == 1/} + + {/if} + + + + + {if $vo.ploss == 0} + + {else /} + + {/if} + + {if $vo.ploss != 0} + + {else /} + + {/if} + + + + + + + {/foreach} + +
订单编号会员ID用户名订单时间产品信息状态方向时间/点数建仓点位平仓点位委托余额无效委托余额有效委托余额实际盈亏买后余额单控操作详情
+ {$vo.id|default='--'} + + {$vo.uid|default='--'} + + {$vo.phone|default='--'} + + {:date('Y-m-d H:i:s',$vo.buytime)} + + {$vo.ptitle|default='--'} + + {if $vo.ostaus==1}平仓{else/}建仓{/if} + 买涨买跌 + {$vo.endprofit|default='--'}{if $vo.eid==1}点{else/}秒{/if} + + {$vo.buyprice|default='--'} + + + + ¥{$vo.fee} + + ¥{$vo.fee} + + ¥0 + + ¥{$vo.fee} + + ¥0 + 0} class="color_red text-center nowrap" {else /} class="color_green text-center nowrap" {/if}> + ¥{$vo.ploss} + + ¥{$vo.commission} + + {if $vo.ostaus!=1} + + {else/}已平仓{/if} + + 查 看 + {if $vo.ostaus==1} + 删 除 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+ +{/block} +{block name='script'} + +{/block} + + diff --git a/application/akszadmin/view/order/index_search.html b/application/akszadmin/view/order/index_search.html new file mode 100755 index 0000000..6b66aec --- /dev/null +++ b/application/akszadmin/view/order/index_search.html @@ -0,0 +1,29 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/order_log/index.html b/application/akszadmin/view/order_log/index.html new file mode 100755 index 0000000..4262b04 --- /dev/null +++ b/application/akszadmin/view/order_log/index.html @@ -0,0 +1,53 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+ {include file='order_log/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + {/foreach} + +
编号会员ID用户名订单ID增加金额增加积分平仓后余额时间
+ {$vo.id|default='--'} + + {$vo.uid|default='--'} + + {$vo.phone|default='--'} + + {$vo.oid|default='--'} + + {$vo.addprice|default='--'} + + {$vo.addpoint|default='--'} + + {$vo.user_money|default='--'} + + {:date('Y-m-d H:i:s',$vo.time)} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/order_log/index_search.html b/application/akszadmin/view/order_log/index_search.html new file mode 100755 index 0000000..6ce0881 --- /dev/null +++ b/application/akszadmin/view/order_log/index_search.html @@ -0,0 +1,21 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/prize/form.html b/application/akszadmin/view/prize/form.html new file mode 100755 index 0000000..9e94b6d --- /dev/null +++ b/application/akszadmin/view/prize/form.html @@ -0,0 +1,270 @@ +{extend name='akszadmin@main'} + +{block name="content"} + +
+
+
    +
  • 抽奖配置
  • +
  • 一等奖
  • +
  • 二等奖
  • +
  • 三等奖
  • +
  • 四等奖
  • +
  • 五等奖
  • +
  • 六等奖
  • +
+
+
+
+
+ +
+
+ 活动规则 + +
+
+
+
+
+
+ + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + +
+
+
+ +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/prize_list/form.html b/application/akszadmin/view/prize_list/form.html new file mode 100755 index 0000000..05004aa --- /dev/null +++ b/application/akszadmin/view/prize_list/form.html @@ -0,0 +1,50 @@ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/prize_list/index.html b/application/akszadmin/view/prize_list/index.html new file mode 100755 index 0000000..79b0c04 --- /dev/null +++ b/application/akszadmin/view/prize_list/index.html @@ -0,0 +1,72 @@ +{extend name='akszadmin@main'} +{block name="button"} +{if auth("add")} + +{/if} +{if auth("remove")} + +{/if} +{/block} +{block name="content"} +
+ {include file='prize_list/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + {/foreach} + +
+ + 编号会员ID用户名奖品类型奖品名称抽奖日期操作
+ + + {$vo.id|default='--'} + + {$vo.uid|default='--'} + + {$vo.phone|default='--'} + + {if $vo.type == 1} + 现金 + {/if} + {if $vo.type == 2} + 实物 + {/if} + + {$vo.name|default='--'} + + {$vo.time|default='--'} + + {if auth("akszadmin/shop_order/remove")} + 删 除 + {else} + 删 除 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/prize_list/index_search.html b/application/akszadmin/view/prize_list/index_search.html new file mode 100755 index 0000000..31b8694 --- /dev/null +++ b/application/akszadmin/view/prize_list/index_search.html @@ -0,0 +1,35 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/queue/index.html b/application/akszadmin/view/queue/index.html new file mode 100755 index 0000000..ec95f24 --- /dev/null +++ b/application/akszadmin/view/queue/index.html @@ -0,0 +1,94 @@ +{extend name='main'} + +{block name="button"} + +{if auth("start") && $iswin} + +{/if} + +{if auth("stop") && $iswin} + +{/if} + +{if auth("remove")} + +{/if} + +{if auth("clear")} + +{/if} + +{/block} + +{block name="content"} + +
+ {include file='queue/index_search'} + + {notempty name='list'} + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + {/foreach} + +
+ + 任务信息任务时间任务状态
+ + + 任务名称:{$vo.title}
+ 任务指令:{$vo.preload} +
+ 计划时间:{$vo.time|format_datetime} {if isset($vo.exec_pid) and $vo.exec_pid>0}( 进程 {$vo.exec_pid|default='-'} ){/if}
+ {if $vo.status eq 3 or $vo.status eq 4} + 执行时间:{$vo.start_at|format_datetime}( 耗时 {:sprintf("%.4f",strtotime($vo.end_at)-strtotime($vo.start_at))} 秒 ) + {elseif $vo.status eq 2} 开始时间:{$vo.start_at|format_datetime} + {else} 创建时间:{$vo.create_at|format_datetime} {/if} +
+
+ {eq name='vo.double' value='1'} + + {else} + + {/eq} + + {eq name='vo.status' value='1'} + 待处理 + {elseif $vo.status eq 2} + 处理中 + {elseif $vo.status eq 3} + 处理完成 + {elseif $vo.status eq 4} + 处理失败 + + + + {/eq} + + {if auth("akszadmin/queue/remove") and in_array($vo.status,[1,3,4])} + + + + {/if} +
+
{$vo.desc|raw|default="没有获取到状态描述"}
+
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/queue/index_search.html b/application/akszadmin/view/queue/index_search.html new file mode 100755 index 0000000..114cca6 --- /dev/null +++ b/application/akszadmin/view/queue/index_search.html @@ -0,0 +1,70 @@ +{if session('user.username') eq 'admin'} +
+ 守护状态 +
+

守护进程运行状态

+ {if $listen} + {$message|raw|default='--'} + {else} + {$message|raw|default='--'} + {/if} +

配置定时任务来检查并启动进程(建议每分钟执行)

+

{$command|default='--'}

+
+
+{/if} + +
+ 条件搜索 + +
+ + diff --git a/application/akszadmin/view/recharge/edit.html b/application/akszadmin/view/recharge/edit.html new file mode 100755 index 0000000..c72f6c6 --- /dev/null +++ b/application/akszadmin/view/recharge/edit.html @@ -0,0 +1,58 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+
+ +
+ +
+
+ +
+
+ +
+ + +
+ 拒绝理由 + + +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+
+{/block} +{block name='script'} + +{/block} \ No newline at end of file diff --git a/application/akszadmin/view/recharge/form.html b/application/akszadmin/view/recharge/form.html new file mode 100755 index 0000000..95718a4 --- /dev/null +++ b/application/akszadmin/view/recharge/form.html @@ -0,0 +1,50 @@ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/recharge/index.html b/application/akszadmin/view/recharge/index.html new file mode 100755 index 0000000..d3ca107 --- /dev/null +++ b/application/akszadmin/view/recharge/index.html @@ -0,0 +1,83 @@ +{extend name='akszadmin@main'} +{block name="button"} +{if auth("change")} + +{/if} +{if auth("remove")} + +{/if} +{/block} +{block name="content"} +
+ {include file='recharge/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + + {/foreach} + +
+ + 账户充值金额(元)支付方式提交时间状态拒绝理由操作
+ + + {$vo.phone} + + {$vo.money} + + {$vo.type} + + {$vo.time} + + {if $vo.status == 0} + 待审核 + {/if} + {if $vo.status == 1} + 已完成 + {/if} + {if $vo.status == 2} + 已拒绝 + {/if} + + {$vo.reaolae} + + {if $vo.status eq 0} + {if auth("agree")} + 同 意 + {/if} + {if auth("refuse")} + + 拒 绝 + + {/if} + {else} + 删 除 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/recharge/index_search.html b/application/akszadmin/view/recharge/index_search.html new file mode 100755 index 0000000..e6fe0f9 --- /dev/null +++ b/application/akszadmin/view/recharge/index_search.html @@ -0,0 +1,71 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/shop/form.html b/application/akszadmin/view/shop/form.html new file mode 100755 index 0000000..70589ab --- /dev/null +++ b/application/akszadmin/view/shop/form.html @@ -0,0 +1,91 @@ +{extend name='akszadmin@main'} + +{block name="content"} + +
+ +
+ +
+ + +
+ +
+ + + +
+ +
+ 商品大图 + + + + + + + + + +
商品封面
+ +
+ +
+ 商品详情 + +
+ +
+ {notempty name='vo.id'}{/notempty} + + +
+ +
+
+{/block} + +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/shop/index.html b/application/akszadmin/view/shop/index.html new file mode 100755 index 0000000..9654e52 --- /dev/null +++ b/application/akszadmin/view/shop/index.html @@ -0,0 +1,90 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/shop/add")} + +{/if} +{if auth("akszadmin/shop/remove")} + +{/if} +{/block} + +{block name="content"} +
+ {include file='shop/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + {/foreach} + +
+ + + + 商品图商品标题商品类型商品库存所需积分
+ + + + + {notempty name='vo.img'} + + {/notempty} + + {$vo.title|default='--'} + + {if $vo.type == 1} + 现金 + {/if} + {if $vo.type == 2} + 实物 + {/if} + + {$vo.num|default='--'} + + {$vo.integral|default='--'} + + +
+ {if auth("akszadmin/shop/edit")} + 编 辑 + {else} + 编 辑 + {/if} + {if auth("akszadmin/shop/remove")} + 删 除 + {else} + 删 除 + {/if} + +
+ +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/shop/index_search.html b/application/akszadmin/view/shop/index_search.html new file mode 100755 index 0000000..3682735 --- /dev/null +++ b/application/akszadmin/view/shop/index_search.html @@ -0,0 +1,15 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/shop_order/index.html b/application/akszadmin/view/shop_order/index.html new file mode 100755 index 0000000..6a90d20 --- /dev/null +++ b/application/akszadmin/view/shop_order/index.html @@ -0,0 +1,69 @@ +{extend name='akszadmin@main'} +{block name="button"} +{if auth("akszadmin/shop_order/remove")} + +{/if} +{/block} +{block name="content"} +
+ {include file='shop_order/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + {/foreach} + +
+ + 编号会员ID用户名商品类型商品名称兑换日期操作
+ + + {$vo.id|default='--'} + + {$vo.uid|default='--'} + + {$vo.phone|default='--'} + + {if $vo.type == 1} + 现金 + {/if} + {if $vo.type == 2} + 实物 + {/if} + + {$vo.goods|default='--'} + + {$vo.time|default='--'} + + {if auth("akszadmin/shop_order/remove")} + 删 除 + {else} + 删 除 + {/if} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/shop_order/index_search.html b/application/akszadmin/view/shop_order/index_search.html new file mode 100755 index 0000000..3f947ab --- /dev/null +++ b/application/akszadmin/view/shop_order/index_search.html @@ -0,0 +1,35 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/slide/form.html b/application/akszadmin/view/slide/form.html new file mode 100755 index 0000000..2f96600 --- /dev/null +++ b/application/akszadmin/view/slide/form.html @@ -0,0 +1,52 @@ +
+
+
+ + +
+ +
+ 图片 + + + + + + + + + +
750x300像素
+ +
+ +
+ +
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/slide/index.html b/application/akszadmin/view/slide/index.html new file mode 100755 index 0000000..47907d8 --- /dev/null +++ b/application/akszadmin/view/slide/index.html @@ -0,0 +1,85 @@ +{extend name='akszadmin@main'} + +{block name="button"} +{if auth("akszadmin/slide/add")} + +{/if} +{if auth("akszadmin/slide/remove")} + +{/if} +{/block} + +{block name="content"} +
+ + {notempty name='list'} + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + {/foreach} + +
+ + + + 图片图片路径链接地址状态
+ + + + + {notempty name='vo.path'} + + {/notempty} + + {$vo.path|default='--'} + + {$vo.url|default='--'} + + {if $vo.show == 0} + 隐藏 + {/if} + {if $vo.show == 1} + 显示 + {/if} + + +
+ {if auth("akszadmin/slide/edit")} + 编 辑 + {else} + 编 辑 + {/if} + {if auth("akszadmin/slide/remove")} + 删 除 + {else} + 删 除 + {/if} + +
+ +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+{/block} diff --git a/application/akszadmin/view/sms/class_search.html b/application/akszadmin/view/sms/class_search.html new file mode 100755 index 0000000..8f6732d --- /dev/null +++ b/application/akszadmin/view/sms/class_search.html @@ -0,0 +1,15 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/sms/form.html b/application/akszadmin/view/sms/form.html new file mode 100755 index 0000000..d6ffa65 --- /dev/null +++ b/application/akszadmin/view/sms/form.html @@ -0,0 +1,32 @@ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ {notempty name='vo.id'}{/notempty} + + +
+
+{block name='script'} + +{/block} diff --git a/application/akszadmin/view/sms/index.html b/application/akszadmin/view/sms/index.html new file mode 100755 index 0000000..70bc9ab --- /dev/null +++ b/application/akszadmin/view/sms/index.html @@ -0,0 +1,53 @@ +{extend name='akszadmin@main'} + +{block name="content"} +
+ {include file='sms/class_search'} + + {notempty name='list'} + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + {/foreach} + +
短信名称短信内容状态备注操作
+ {$vo.type|default=''} + {$vo.msg} + {if $vo.status == 0} + 已关闭 + {/if} + {if $vo.status == 1} + 已开启 + {/if} + {$vo.code} + + {if $vo.status eq 1 and auth("forbid")} + 关 闭 + {elseif auth("resume")} + 启 用 + {/if} + + {if auth("edit")} + 编 辑 + {/if} + +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/user/form.html b/application/akszadmin/view/user/form.html new file mode 100755 index 0000000..0751aff --- /dev/null +++ b/application/akszadmin/view/user/form.html @@ -0,0 +1,73 @@ +
+
+
+ +

登录用户账号创建后,不允许再次修改。

+
+
+ +

可选,用户联系手机号码,需要填写正确的格式

+
+
+ +

可选,用户联系电子邮箱,需要填写正确的格式

+
+ + {notempty name='authorizes'} +
+ 角色访问授权 + Authorization +
+ {if isset($vo.username) and $vo.username eq 'admin'} + 超级用户不需要配置权限 + {elseif empty($authorizes)} + 未配置权限 + {else} + {foreach $authorizes as $authorize} + + {/foreach} + {/if} +
+
+ {/notempty} + +
+ +
+
+ +
+ {notempty name='vo.id'}{/notempty} + +
+ + +
+ +
diff --git a/application/akszadmin/view/user/index.html b/application/akszadmin/view/user/index.html new file mode 100755 index 0000000..3550623 --- /dev/null +++ b/application/akszadmin/view/user/index.html @@ -0,0 +1,77 @@ +{extend name='main'} + +{block name="button"} + +{if auth("add")} + +{/if} + +{if auth("remove")} + +{/if} + +{/block} + +{block name="content"} +
+ {include file='user/index_search'} + + {notempty name='list'} + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + {/foreach} + +
+ + 用户账号联系手机登录次数使用状态创建时间登录时间
+ + {$vo.username|default=''}{$vo.phone|default='-'}{$vo.login_num|default=0}{eq name='vo.status' value='0'}已禁用{else}使用中{/eq}{$vo.create_at|format_datetime}{if $vo.login_num>0}{$vo.login_at|format_datetime}{else} - {/if} + + {if auth("pass")} + 密 码 + {/if} + + {if auth("edit")} + 编 辑 + {/if} + + {if $vo.status eq 1 and auth("forbid")} + 禁 用 + {elseif $vo.status eq 0 and auth("resume")} + 启 用 + {/if} + + {if auth("remove")} + 删 除 + {/if} + +
+ + {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} + +
+ +{/block} diff --git a/application/akszadmin/view/user/index_search.html b/application/akszadmin/view/user/index_search.html new file mode 100755 index 0000000..b2d26a1 --- /dev/null +++ b/application/akszadmin/view/user/index_search.html @@ -0,0 +1,57 @@ +
+ + 条件搜索 + + + +
+ + diff --git a/application/akszadmin/view/user/pass.html b/application/akszadmin/view/user/pass.html new file mode 100755 index 0000000..bc60936 --- /dev/null +++ b/application/akszadmin/view/user/pass.html @@ -0,0 +1,57 @@ +
+ +
+ + + + + + + + + + + + + + + +
+ +

请输入旧密码来验证修改权限,旧密码不限制格式。

+
+ + +
+ +

密码必需包含大小写字母、数字、符号的任意两者组合。

+
+ +
+ +

密码必需包含大小写字母、数字、符号的任意两者组合。

+
+ +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+ + +
+ +
diff --git a/application/akszadmin/view/user/suffix.html b/application/akszadmin/view/user/suffix.html new file mode 100755 index 0000000..113283d --- /dev/null +++ b/application/akszadmin/view/user/suffix.html @@ -0,0 +1,17 @@ +
+
+
+ +

请输入后台加密后缀!

+
+
+
+
+ + +
+
\ No newline at end of file diff --git a/application/akszadmin/view/users/form.html b/application/akszadmin/view/users/form.html new file mode 100755 index 0000000..f6702ba --- /dev/null +++ b/application/akszadmin/view/users/form.html @@ -0,0 +1,74 @@ +
+
+
+ + + +
+
+ + + + + +
+ + + + {if !empty($bankinfo)} +
+ +
+ + +
+
+ +{/if} +
+ +
+ {notempty name='vo.id'}{/notempty} + +
+ + +
+
+ +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/users/index.html b/application/akszadmin/view/users/index.html new file mode 100755 index 0000000..8f513f0 --- /dev/null +++ b/application/akszadmin/view/users/index.html @@ -0,0 +1,123 @@ +{extend name='main'} + +{block name="button"} + +{if auth("add")} + +{/if} + +{if auth("forbid")} + +{/if} + +{if auth("remove")} + +{/if} + +{/block} + +{block name="content"} +
+ {include file='users/index_search'} + + {notempty name='list'} + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + {/foreach} + +
+ + 用户信息用户资料用户资金(点击金额查看)用户详情时间
+ + + ID:{$vo.id|default='--'}
+ 姓名:{$vo.phones|default='--'}
+ 用户名:{$vo.phone|default='--'}
+ 状态: + {eq name='vo.online' value='false'} + 离线 + {else} + 在线 + {/eq} +
+ 实名: + {eq name='vo.rz_status' value='0'} + {$vo.robot==1?'假人':'未实名'} + {elseif $vo.rz_status == 1} + {$vo.robot==1?'假人':'待审核'} + {elseif $vo.rz_status == 2} + {$vo.robot==1?'假人':'已实名'} + {elseif $vo.rz_status == 3} + {$vo.robot==1?'假人':'已驳回'} + {/eq}
+ +
+ 会员等级:{$vo.m_name|default='--'}
+ 推荐人:{$vo.top|default='--'}
+ IP:{$vo.ip|default='--'}
+ ISP:{$vo.isp|default='--'}
+ 注册来源:{$vo.zcly|default='--'}
+
+ 账户余额:{$vo.money|default='--'} 元
+ 提现总额:{$vo.cash_sum|default='--'} 元
+ 充值总额:{$vo.recharge_sum|default='--'} 元
+ 投资总额:{$vo.invest_sum|default='--'} 元
+
+ 待收利息:{$vo.wait_invest|default='--'} 元
+ 待收本金:{$vo.wait_money|default='--'} 元
+ 成长值:{$vo.value|default='--'}
+
+ 用户状态: + {eq name='vo.clock' value='0'} + 已冻结 + {else} + 正常 + {/eq}
+ 注册时间:{$vo.time}
+ 最近操作:{$vo.logintime|format_datetime}
+ 登陆IP:{$vo.loginip|default='--'}
+ ISP:{$vo.isp2|default='--'}
+
+ {if $vo.isjy == 1} + 交易关闭 + {else /} + 交易开启 + {/if} + {if auth("review")} + 实名认证审核 + {/if} + {if auth("edit")} + 编 辑 + {/if} + {if $vo.clock eq 1 and auth("forbid")} + 冻 结 + {elseif $vo.clock eq 0 and auth("resume")} + 解 冻 + {/if} +
{$vo.robot==1?"设置成真人":"设置成假人"} +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+ +{/block} diff --git a/application/akszadmin/view/users/index_search.html b/application/akszadmin/view/users/index_search.html new file mode 100755 index 0000000..d0bd797 --- /dev/null +++ b/application/akszadmin/view/users/index_search.html @@ -0,0 +1,88 @@ +
+ + 条件搜索 + + + +
+ + diff --git a/application/akszadmin/view/users/relation_search.html b/application/akszadmin/view/users/relation_search.html new file mode 100755 index 0000000..179aef7 --- /dev/null +++ b/application/akszadmin/view/users/relation_search.html @@ -0,0 +1,29 @@ +
+ 条件搜索 + + +
diff --git a/application/akszadmin/view/users/review.html b/application/akszadmin/view/users/review.html new file mode 100755 index 0000000..17a1175 --- /dev/null +++ b/application/akszadmin/view/users/review.html @@ -0,0 +1,55 @@ +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +
+ {notempty name='$id'}{/notempty} + +
+ + +
+
+ +{block name='script'} + +{/block} diff --git a/application/akszadmin/view/users/user_relation.html b/application/akszadmin/view/users/user_relation.html new file mode 100755 index 0000000..6e4b94e --- /dev/null +++ b/application/akszadmin/view/users/user_relation.html @@ -0,0 +1,54 @@ +{extend name='akszadmin@main'} +{block name="content"} +
+ {include file='users/relation_search'} + + {notempty name='list'} + + + + + + + + + + + + + {foreach $list as $key=>$vo} + + + + + + + + + + {/foreach} + {/notempty} + +
会员ID用户名姓名余额是否认证推荐人用户名编号
+ {$vo.id|default='--'} + + {$vo.phone|default='--'} + + {$vo.name|default='--'} + + {$vo.money|default='--'} + + {if $vo.auth == 1} + 已认证 + {/if} + {if $vo.auth == 0} + 未认证 + {/if} + + {$vo.top_phone|default='--'} + + 查看详情 +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} diff --git a/application/akszadmin/view/yuebao/index.html b/application/akszadmin/view/yuebao/index.html new file mode 100755 index 0000000..b241145 --- /dev/null +++ b/application/akszadmin/view/yuebao/index.html @@ -0,0 +1,217 @@ +{extend name='main'} + +{block name="button"} + + +{/block} + +{block name="content"} + +
+ 余额宝理财 +
+ + +
+
+
+ + + {notempty name='list'} + + + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + + + {/foreach} + +
+ + 序号余额宝名称收益率(%)锁定天数最低金额(天)推荐添加时间状态
+ + + {$vo.id} + + {$vo.title} + + {$vo.lily} + + {$vo.days} + + {$vo.lowmoney} + + + {$vo.stars==0?"未推荐":""} + {$vo.stars==1?"已推荐":""} + + {$vo.addtime} + + {$vo.status==0?"已下架":""} + {$vo.status==1?"已上线":""} + + / / +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+ + + + + +{/block} diff --git a/application/akszadmin/view/yuebao/lists.html b/application/akszadmin/view/yuebao/lists.html new file mode 100755 index 0000000..2a81f88 --- /dev/null +++ b/application/akszadmin/view/yuebao/lists.html @@ -0,0 +1,157 @@ +{extend name='main'} + +{block name="button"} + + + + +{/block} + +{block name="content"} +
+ 余额宝--用户购买记录 +
+ + +
+
+
+
+ 进行中(记录数)
{$countdoing} +
+
+ 资金池总额(元)
{$counttotalmoney} +
+
+ 待分红金额(元)
{$countnosend} +
+
+ 已分红金额(元)
{$countsended} +
+
+ 总参加人次
{$counttotal} +
+
+
+ + + {notempty name='list'} + + + + + + + + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + + + + + + + + {/foreach} + +
+ + 序号用户账号余额宝名称收益率(%)锁定天数金额(元)当前收益(元)预期收益(元)开始时间结束时间状态
+ + + {$vo.id} + + {$vo.username} + + {$vo.yebtitle} + + {$vo.lily} + + {$vo.days} + + {$vo.money} + + {$vo.nowprofit} + + {$vo.finishprofit} + + {$vo.start_time} + + {$vo.end_time} + + {$vo.status==0?"未生效":""} + {$vo.status==1?"进行中":""} + {$vo.status==2?"已结束":""} + {$vo.status==9?"已删除":""} + + +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+ +{/block} diff --git a/application/common.php b/application/common.php new file mode 100644 index 0000000..bb86423 --- /dev/null +++ b/application/common.php @@ -0,0 +1,26 @@ +where('id', $uid)->limit(1)->update(['access_time' => time()]); + } + } catch (\Exception $e) { + die('error'); + } + } +} \ No newline at end of file diff --git a/application/index/controller/Index.php b/application/index/controller/Index.php new file mode 100755 index 0000000..0f9ea1e --- /dev/null +++ b/application/index/controller/Index.php @@ -0,0 +1,1894 @@ +redirect('/h5'); + $uid = $this->app->session->get('uid'); + if (!$uid) { + if (true) { // true:开启线路;false:关闭线路 + return $this->fetch(); + } + // $this->redirect('/index/login'); + } + $this->redirect('/index/index/home'); + } + + + /** + * @description:未登录新闻页 + * @date: 2020/5/14 0014 + */ + public function news() + { + $this->fetch('new_index'); + } + + /** + * Describe: 新闻页面 + * DateTime: 2020/5/14 1:16 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function my_news() + { + $this->login = 0; + if (!isLogin()) $this->login = 1; + $this->conf = Db::name('LcReward')->get(1); + $this->fetch('my_news'); + } + + /** + * Describe: 信息详情 + * DateTime: 2020/5/14 0:31 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function msg_view() + { + $id = $this->request->param('id'); + $uid = $this->app->session->get('uid'); + if (!$id || !$uid) + msg('系统忙碌!', 2, '/index/user/index'); + $where['uid'] = $this->app->session->get('uid'); + $where['mid'] = $id; + $ret = Db::name('LcMsgIs')->where($where)->find(); + if (!$ret) + Db::name('LcMsgIs')->insertGetId(['uid' => $uid, 'mid' => $id]); + $this->msg = Db::name('LcMsg')->find($id); + $this->fetch(); + } + + /** + * Describe: 新闻奖励 + * DateTime: 2020/5/14 1:27 + * @throws \think\Exception + * @throws \think\Exception\DbException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\PDOException + */ + public function news_reward() + { + if (isLogin()) { + $uid = $this->app->session->get('uid'); + $reward = Db::name('LcReward')->get(1); + $start_time = strtotime(date("Y-m-d", time())); + $end_time = $start_time + 60 * 60 * 24; + $reward['newsmoney'] = round($this->randFloat($reward['newsmoney'], $reward['newsmoneytwo']), 2); + $todaynum = Db::name('LcSeeLog')->where('uid=\'' . $uid . '\' and dateline > \'' . $start_time . '\' and dateline < \'' . $end_time . '\'')->count(); + if ($todaynum < $reward['getnum']) { + addFinance($uid, $reward['newsmoney'], 1, '浏览新闻,系统赠送' . $reward['newsmoney'] . '元'); + setNumber('LcUser', 'money', $reward['newsmoney'], 1, "id = $uid"); + setNumber('LcUser', 'income', $reward['newsmoney'], 1, "id = $uid"); + $add = array('uid' => $uid, 'dateline' => time(), 'money' => $reward['newsmoney']); + Db::name('LcSeeLog')->insert($add); + $morenum = $reward['getnum'] - $todaynum - 1; + $this->success('奖励领取成功', ['more' => $morenum, 'times' => $reward['seetime'] * 60]); + } else { + $this->error('今日领取次数用尽'); + } + } + } + + private function randFloat($min = 0, $max = 1) + { + return $min + mt_rand() / mt_getrandmax() * ($max - $min); + } + + /** + * @description:首页 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function home() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->ater = Db::name('LcArticle')->where(['type' => 17, 'show' => 1])->find(); + + $this->banner = Db::name('LcSlide')->where(['show' => 1])->order("sort asc,id desc")->select(); + $allproducts = Db::name('LcProduct')->where(['isdelete' => 0, 'iskq' => 1])->order("sort asc,id desc")->select(); + //判断是否开市 + $weekday = date("w"); + $newallproducts = array(); + if ($weekday == 0) $weekday = 7; + foreach ($allproducts as $x => $p) { + if (strpos($p['code'], "btc") !== false || strpos($p['code'], "usdt") !== false) { + $p['isclosetime'] = 0; + $ttimes = $p['opentime_' . $weekday]; + if (empty($ttimes)) { + $p['isclosetime'] = 1; + + continue; + }; + //var_dump($this->info['opentime_'.$weekday],$weekday);die; + if (!empty($ttimes)) { + $optime = 0; + $ttimesarr = explode("|", $ttimes); + foreach ($ttimesarr as $t) { + $t = explode('~', $t); + if (time() > strtotime(date('Y-m-d ' . $t[0])) and time() < strtotime(date('Y-m-d ' . $t[1]))) $optime = $optime + 1; + } + if ($optime == 0) $p['isclosetime'] = 1; + } + $newallproducts[$x] = $p; + } + } + + //var_dump($newallproducts); + $this->product = $newallproducts; + $this->fetch(); + } + + /** + * 全局平仓 + * @return void [type] [description] + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function order() + { + $nowtime = time(); + //订单列表 + $map[] = ['ostaus', '=', 0]; + $map[] = ['status', '=', 0]; + $map[] = ['selltime', '<', $nowtime]; + $orderlist = Db::name('LcOrder')->where($map)->limit(0, 50)->select(); + if (!$orderlist) { + exit(dump('没有订单需要处理!')); + die; + } + Db::name('LcOrder')->where($map)->update(['status' => 1]); + //风控参数 + $risk = Db::name('LcRisk')->find(); + $to_win = explode('|', $risk['to_win']); + $to_loss = explode('|', $risk['to_loss']); + $chance = $risk["chance"]; + $wenyin = explode('-', $risk['wenyin']); //稳赢时间 + $wenshu = explode('-', $risk['wenshu']);//稳输时间 + + $is_to_loss = array(); + $is_to_win = array(); + //买涨金额,计算过盈亏比例以后的 + $up_price = 0; + //买跌金额,计算过盈亏比例以后的 + $min_buyprice = 0; + //买入最低价 + $down_price = 0; + //买入最高价 + $max_buyprice = 0; + //下单最大金额 + $max_fee = 0; + + + //此刻产品价格 + $pro = Db::name('LcProduct')->field('id as pid,Price,downps,upps')->where(array('isdelete' => 0))->select(); + $upps = array(); + $downps = array(); + + $data_info = Db::name('LcProduct'); + $prodata = array(); + foreach ($pro as $k => $v) { + $prodata[$v['pid']] = $v['Price']; + $upps[$v['pid']] = $v['upps']; + $downps[$v['pid']] = $v['downps']; + } + + + //循环处理订单 + $nowtime = time(); + $kt = count($orderlist); + $h = date("H:i"); + //var_dump($orderlist);die; + foreach ($orderlist as $k => $v) { + $uid = $v['uid']; + $pid = $v['pid']; + $sellprice = isset($prodata[$v['pid']]) ? $prodata[$v['pid']] : 0; + $sellprice = $v['sellprice'] == 0 ? $sellprice : $v['sellprice']; + + //单控 赢利 + if ($v['kong_type'] == '1' || $v['kong_type'] == '3') { + $dankong_ying = $v; + } + //单控 亏损 + if ($v['kong_type'] == '2' | $v['kong_type'] == '4') { + $dankong_kui = $v; + } + //是否存在指定盈利 + if (in_array($v['uid'], $to_win)) { + $is_to_win = $v; + } + //是否存在指定亏损 + if (in_array($v['uid'], $to_loss)) { + $is_to_loss = $v; + } + //买涨买跌累加 + if ($v['ostyle'] == 0) { + $up_price += $v['fee'] * $v['endloss'] / 100; + } else { + $down_price += $v['fee'] * $v['endloss'] / 100; + } + + $min_buyprice = $v['buyprice']; + $max_buyprice = $v['buyprice']; + $max_fee = $v['fee']; + + + $proinfo = Db::name('LcProduct')->where('id', $v['pid'])->find(); + + //根据现在的价格算出风控点 + $FloatLength = getFloatLength((float)$proinfo['Price']); + + if ($FloatLength == 0) { + $FloatLength = getFloatLength($proinfo['point_top']); + } + + //是否存在指定盈利 + $is_do_price = 0; //是否已经操作了价格 + $jishu_rand = pow(10, $FloatLength); + $beishu_rand = rand(1, 10); + $data_rands = $proinfo['rands']; + + $data_randsLength = getFloatLength($data_rands); + + if ($data_randsLength > 0) { + //var_dump($proinfo); + $_j_rand = pow(100, $data_randsLength) * $data_rands; + //$_j_rand=$_s_rand = 0; + $_s_rand = rand(1, $_j_rand) / pow(100, $data_randsLength); + } else { + $_s_rand = 0; + } + + $do_rand = $_s_rand; + + //先考虑单控 + if (!empty($dankong_ying) && $is_do_price == 0) { //单控 1赢利 + if ($dankong_ying['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } elseif ($dankong_ying['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } + $is_do_price = 1; + } + + if (!empty($dankong_kui) && $is_do_price == 0) { //单控 2亏损 + if ($dankong_kui['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } elseif ($dankong_kui['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } + $is_do_price = 1; + } + + //时间区间判断 稳赢 + if (isset($wenyin) && !empty($wenyin[0])) { + if ($h >= $wenyin[0] && $h <= $wenyin[1] && $is_do_price == 0) { + + if ($v['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } elseif ($v['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } + $is_do_price = 1; + } + } + + + //时间区间判断 稳输 + if (isset($wenshu) && !empty($wenshu[0])) { + + if ($h >= $wenshu[0] && $h <= $wenshu[1] && $is_do_price == 0) { + if ($v['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } elseif ($v['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } + $is_do_price = 1; + } + } + + + //var_dump($is_do_price); + //指定客户赢利 + if (!empty($is_to_win) && $is_do_price == 0) { + + if ($is_to_win['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } elseif ($is_to_win['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } + $is_do_price = 1; + } + + //是否存在指定亏损 + if (!empty($is_to_loss) && $is_do_price == 0) { + if ($is_to_loss['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } elseif ($is_to_loss['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } + $is_do_price = 1; + } + + + //没有任何下单记录 + if ($up_price == 0 && $down_price == 0 && $is_do_price == 0) { + $is_do_price = 2; + } + + + //只有一个人下单,或者所有人下单买的方向相同 + if ((($up_price == 0 && $down_price != 0) || ($up_price != 0 && $down_price == 0)) && $is_do_price == 0) { + + //风控参数 + $chance_1 = explode('|', $chance); + + $chance_1 = array_filter($chance_1); + + //循环风控参数 + if (count($chance_1) >= 1) { + foreach ($chance_1 as $key => $value) { + //切割风控参数 + $arr_1 = explode(":", $value); + $arr_2 = explode("-", $arr_1[0]); + + //比较最大买入价格 + if ($max_fee >= $arr_2[0] && $max_fee < $arr_2[1]) { + //得出风控百分比 + if (!isset($arr_1[1])) { + $chance_num = 30; + } else { + $chance_num = $arr_1[1]; + } + $_rand = rand(1, 100); + } + + } + } + + //买涨 + if (isset($_rand) && $up_price != 0) { + if ($_rand > $chance_num) { //客损 + $pro['Price'] = $min_buyprice - $do_rand; + $is_do_price = 1; + } else { //客赢 + $pro['Price'] = $max_buyprice + $do_rand; + $is_do_price = 1; + + } + + } + if (isset($_rand) && $down_price != 0) { + if ($_rand > $chance_num) { //客损 + $pro['Price'] = $max_buyprice + $do_rand; + $is_do_price = 1; + } else { //客赢 + $pro['Price'] = $min_buyprice - $do_rand; + $is_do_price = 1; + + } + + } + } + + + //多个人下单,并且所有人下单买的方向不相同 + if ($up_price != 0 && $down_price != 0 && $is_do_price == 0) { + //买涨大于买跌的 + if ($up_price > $down_price) { + $pro['Price'] = $min_buyprice - $do_rand; + $is_do_price = 1; + } + //买涨小于买跌的 + if ($up_price < $down_price) { + $pro['Price'] = $max_buyprice + $do_rand; + $is_do_price = 1; + } + if ($up_price == $down_price) { + $is_do_price = 2; + } + } + //$pro['Price']=0; + if ($is_do_price == 2 || $is_do_price == 0) { + + //continue; + //if($pro['Price']==0 or $pro['Price']=="") continue; + $pro['Price'] = $this->fengkong($sellprice, $proinfo); + } + //var_dump($to_win,$is_to_win,$is_do_price,$pro['Price'] );die; + //时间区间判断 + + //$sellprice= $pro['Price']; + + + //此刻可平仓价位 + + //买入价 + $buyprice = $v['buyprice']; + $fee = $v['fee']; + $sellprice = $pro['Price']; + $downpss = array(); + $uppss = array(); + $addupps = 0; + $adddownps = 0; + $order_cha = round(floatval($sellprice) - floatval($buyprice), 6); + //var_dump($upps);die; + if (!empty($upps[$v['pid']])) { + $uppss = explode("-", $upps[$v['pid']]); + $addupps = $v['endloss'] * mt_rand($uppss[0] * 100, $uppss[1] * 100) / 100; + } else { + $addupps = 0; + } + if (!empty($downps[$v['pid']])) { + $downpss = explode("-", $downps[$v['pid']]); + $adddownps = $v['lossrate'] * mt_rand($downpss[0] * 100, $downpss[1] * 100) / 100; + + } else { + $adddownps = 0; + } + + //var_dump($uppss,$downpss,$addupps,$adddownps);die; + + + if ($nowtime >= $v['selltime']) { + //买涨 + + if ($v['ostyle'] == 0) { + + if ($order_cha > 0) { //盈利 + $yingli = round($v['fee'] * ($v['endloss'] / 100), 2); + $d_map['is_win'] = 1; + + //平仓增加用户金额 + $u_add = $yingli + $fee; + + $d_map['endloss'] = $yingli; + } elseif ($order_cha < 0) { //亏损 + $yingli = round(($v['fee'] - ($v['fee'] * $v['lossrate'] / 100)), 2); + $d_map['is_win'] = 2; + + //平仓增加用户金额 + $u_add = round($yingli, 2); + + $yingli = round(-($v['fee'] * $v['lossrate'] / 100), 2); + + $d_map['endloss'] = $yingli; + } else { //无效 + $yingli = 0; + $d_map['is_win'] = 3; + //平仓增加用户金额 + $u_add = $fee; + } + } + //买跌 + if ($v['ostyle'] == 1) { + if ($order_cha < 0) { //盈利 + $yingli = round($v['fee'] * ($v['endloss'] / 100), 2); + $d_map['is_win'] = 1; + //平仓增加用户金额 + $u_add = $yingli + $fee; + $d_map['endloss'] = $yingli; + } elseif ($order_cha > 0) { //亏损 + $yingli = round($v['fee'] - ($v['fee'] * $v['lossrate'] / 100), 2); + $d_map['is_win'] = 2; + + //平仓增加用户金额 + $u_add = round($yingli, 2); + + $yingli = round(-($v['fee'] * $v['lossrate'] / 100), 2); + $d_map['endloss'] = $yingli; + + } else { //无效 + $yingli = 0; + $d_map['is_win'] = 3; + //平仓增加用户金额 + $u_add = $fee; + } + + } + $reason = '订单[' . $v['orderno'] . ']平仓获得金额 ' . $u_add . '元'; + $finance = Db::name('LcFinance')->where(['uid' => $uid, 'reason' => 1])->order('id desc')->find(); + if (empty($finance)) { + addFinance($uid, $u_add, 1, $reason); + setNumber('LcUser', 'money', $u_add, 1, "id = $uid"); + //写入日志 + $o_log['uid'] = $uid; + $o_log['oid'] = $v['id']; + $o_log['addprice'] = $u_add; + $o_log['addpoint'] = 0; + $o_log['time'] = time(); + $o_log['user_money'] = Db::name('LcUser')->where('id', $uid)->value('money'); + Db::name('LcOrderLog')->insert($o_log); + //平仓处理订单 + $d_map['ostaus'] = 1; + $d_map['sellprice'] = $sellprice; + $d_map['ploss'] = $yingli; + Db::name('LcOrder')->where('id', $v['id'])->update($d_map); + } + + } + } + + } + + /** + * 数据风控 + * @param [type] $price [description] + * @param [type] $pro [description] + * @return [type] [description] + * @author lukui 2017-06-27 + */ + public function fengkong($price, $pro) + { + + $point_low = $pro['point_low']; + $point_top = $pro['point_top']; + + $FloatLength = getFloatLength($point_top); + $jishu_rand = pow(10, $FloatLength); + $point_low = $point_low * $jishu_rand; + $point_top = $point_top * $jishu_rand; + $rand = rand($point_low, $point_top) / $jishu_rand; + + $_new_rand = rand(0, 10); + if ($_new_rand % 2 == 0) { + $price = $price + $rand; + } else { + $price = $price - $rand; + } + return $price; + } + + /** + * @description:项目列表 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function lists() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcMallInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now' and uid = $uid")->count(); + $this->dqkj = Db::name('LcMallInvest')->where("time2 <= '$now' and uid = $uid")->count(); + $this->invest = Db::name('LcMallInvest')->where('uid', $uid)->where("time2 >= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + public function normalfutures() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcInvest')->where("time2 >= '$now'")->count(); + $this->dqkj = Db::name('LcInvest')->where("time2 <= '$now'")->count(); + $this->invest = Db::name('LcInvest')->where('uid', $uid)->where("time2 >= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + public function expirefutures() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcInvest')->where("time2 >= '$now'")->count(); + $this->dqkj = Db::name('LcInvest')->where("time2 <= '$now'")->count(); + $this->invest = Db::name('LcInvest')->where('uid', $uid)->where("time2 <= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:项目列表 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function ex_lists() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcMallInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now'")->count(); + $this->dqkj = Db::name('LcMallInvest')->where("time2 <= '$now'")->count(); + $this->invest = Db::name('LcMallInvest')->where('uid', $uid)->where("time2 <= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:项目详情 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function item() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $id = \think\facade\Request::param('id'); + if (!$id) msg('无效参数', 2, '/index'); + $this->data = Db::name('LcItem')->where(['id' => $id])->find(); + if (!$this->data) msg('无效项目', 2, '/index'); + if (date('Y-m-d H:i:s') < $this->data['time']) msg('项目暂未开始!', 2, '/index'); + $this->fetch(); + } + + /** + * @description:矿机详情 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function mall_detail() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $id = \think\facade\Request::param('id'); + if (!$id) msg('无效参数', 2, '/index'); + $this->data = Db::name('LcMall')->where(['id' => $id])->find(); + if (!$this->data) msg('无效矿机', 2, '/index'); + $this->fetch(); + } + + /** + * @description:投资 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function form() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $id = \think\facade\Request::param('id'); + if (!$id) msg('无效参数', 2, '/index'); + $this->data = Db::name('LcItem')->where(['id' => $id])->find(); + if (!$this->data) msg('无效项目', 2, '/index'); + if (date('Y-m-d H:i:s') < $this->data['time']) msg('项目暂未开始!', 2, '/index'); + if (getProjectPercent($this->data['id']) == 100) msg('项目已满,请选择其他项目', 2, '/index'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->user['auth'] != 1) msg('请实名认证后再投资!', 2, '/index/User/certification'); + //抵用券 + $voucher_info = Db::name('LcVoucher')->where("uid = $uid AND status = 2")->order('money desc')->select(); + if (empty($voucher_info)) { + $this->voushow = 0; + $this->vinfo = array(); + } else { + $this->vinfo = $this->voucherinfo; + } + $count = Db::name('LcVoucher')->where('status = 1 and uid = ' . $uid . ' and xid = ' . $id)->count(); + if ($this->data['usevoucher'] <= $count) { + $this->voushow = 0; + $this->usevounum = 0; + } else { + $this->voushow = 1; + $this->usevounum = $this->data['usevoucher'] - $count; + } + //检查等级 + $level = Db::name('LcItemClass')->alias('c')->field("c.id,m.value")->join("lc_user_member m", "c.member_id = m.id")->where("c.id = {$this->data['class']}")->find(); + if ($this->user['value'] < $level['value']) msg('您的等级不够', 2, '/index'); + if (\think\facade\Request::isPost()) { + $param = \think\facade\Request::param(); +// $voucher = $param['voucher']; + $voucher = 0; + $money = $param['money']; + if ($voucher) { + $arrvid = explode(',', $voucher); + $vouallmoney = 0; + foreach ($arrvid as $k => $v) { + $voucherinfos = Db::name('LcVoucher')->where("vid = '$v'")->find(); + if (empty($voucherinfos)) { + msg('抵用券不存在', 2, '/index'); + } + if ($voucherinfos['status'] != 2) { + msg('抵用券已使用', 2, '/index'); + } + $vouallmoney = $vouallmoney + $voucherinfos['money']; + } + $count = $count + count($arrvid); + if ($count > $this->data['usevoucher']) { + msg('最多使用' . $this->data['usevoucher'] . '张投资抵用券', 2, '/index'); + } + $money = $param['money'] - $vouallmoney; + if ($money < 0) $money = 0; + } + $my_count = Db::name('LcInvest')->where(['uid' => $uid, 'pid' => $id])->count(); + if ($this->data['num'] <= $my_count) msg('该项目每人限投' . $this->data['num'] . '次!', 2, '/index'); + if ($this->user['password2'] != md5($param['pwd'])) msg('请输入正确的交易密码!', 2, '/index'); + if ($this->user['money'] < $money) msg('余额不足,请充值后再进行投资!', 2, '/index'); + if ($this->data['max'] < $money) msg('投资金额大于项目最大投资额度!', 2, '/index'); + if (getProjectSurplus($this->data['id']) < $money) msg('投资金额大于项目剩余投资额度!', 2, '/index'); + if ($this->data['min'] > $money) msg('投资金额小于项目最小投资额度!', 2, '/index'); + addFinance($uid, $money, 2, '投资项目:' . $this->data['title'] . ',使用余额' . $money . '元'); + setNumber('LcUser', 'money', $money, 2, "id = $uid"); + setInvestReward_old($uid, $money); + if ($voucher) { + foreach ($arrvid as $k => $v) { + Db::name('LcVoucher')->where("vid = '{$v}'")->update(array('status' => 1, 'xid' => $id, 'title' => $this->data['title'])); + } + } + if (getInvestList($id, $money, $uid)) { + if (0 < $this->data['red']) { + $multiple = floor($money / $this->data['min']) * $this->data['red'] ?: 0; + + if (0 < $multiple) { + addFinance($uid, $multiple, 1, '投资送红包'); + setNumber('LcUser', 'money', $multiple, 1, "id = $uid"); + } + } + msg('投资成功!', 2, '/index/user/index'); + } + msg('投资失败!', 2, '/index/user/index'); + } + $this->fetch(); + } + + /** + * Describe: + * DateTime: 2021/1/14 1:38 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function mall_form() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $id = \think\facade\Request::param('id'); + if (!$id) msg('无效参数', 2, '/index'); + $this->data = Db::name('LcMall')->where(['id' => $id])->find(); + if (!$this->data) msg('无效项目', 2, '/index'); + if ($this->data['stock'] <= 0) msg('矿机已满,请选择其他矿机', 2, '/index'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->user['auth'] != 1) msg('请实名认证后再投资!', 2, '/index/User/certification'); + if (\think\facade\Request::isPost()) { + $param = \think\facade\Request::param(); + if ($this->user['password2'] != md5($param['password'])) $this->error("请输入正确的交易密码"); + if ($this->data['num'] < $param['buynum'] || $param['buynum'] <= 0) $this->error("该矿机限购" . $this->data['num'] . "份"); + $my_count = Db::name('LcMallInvest')->where(['uid' => $uid, 'pid' => $id])->count(); + if ($this->data['num'] <= $my_count) $this->error("该矿机限购" . $this->data['num'] . "份"); + $money = $this->data['min'] * $param['buynum']; + if ($this->user['money'] < $money) $this->error("余额不足,请充值后再进行投资!"); + if ($this->data['stock'] <= 0 || $this->data['stock'] < $param['buynum']) $this->error("该矿机剩余不足"); + addFinance($uid, $money, 2, '租赁矿机:' . $this->data['title'] . ',缴纳保证金' . $money . '元'); + setNumber('LcUser', 'money', $money, 2, "id = $uid"); + if (getMallInvestList($id, $money, $uid, $param['tran_type'])) { + $this->success("租赁成功"); + } + $this->success("租赁失败"); + } + $this->fetch(); + } + + /** + * Describe:计算器 + * DateTime: 2020/5/14 20:52 + */ + public function calculator() + { + $this->fetch(); + } + + /** + * Describe:关于我们 + * DateTime: 2020/5/14 21:02 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function about() + { + $this->abour_type = Db::name('lcArticleType')->order("sort asc,id desc")->select(); + $this->fetch(); + } + + /** + * Describe:文章列表 + * DateTime: 2020/5/14 21:13 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function about_list() + { + $id = \think\facade\Request::param('id'); + if (empty($id)) msg('参数缺失!', 2, '/index'); + $this->count = Db::name('lcArticle')->where(['type' => $id, 'show' => 1])->count(); + if ($this->count == 1) { + $this->article_id = Db::name('lcArticle')->where(['type' => $id, 'show' => 1])->value('id'); + $this->redirect('/index/index/about_details?id=' . $this->article_id); + } else { + $this->type_name = Db::name('lcArticleType')->where(['id' => $id])->value('name'); + $this->about = Db::name('lcArticle')->where(['type' => $id, 'show' => 1])->order("id desc")->select(); + $this->fetch(); + } + } + + /** + * Describe:文章详情 + * DateTime: 2020/5/14 21:25 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function about_details() + { + $id = \think\facade\Request::param('id'); + if (empty($id)) msg('参数缺失!', 2, '/index'); + $this->article = Db::name('lcArticle')->where(['id' => $id, 'show' => 1])->find(); + $this->fetch(); + } + + /** + * Describe:抽奖 + * DateTime: 2020/5/14 23:45 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function prize() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->data = Db::name("LcPrize")->find(1); + $this->user = Db::name('LcUser')->find($uid); + $this->count = $this->user['prize'] ?: 0; + $prize_list = Db::name("LcPrizeList")->where("type != 0")->limit(10)->order("id desc")->select(); + foreach ($prize_list as $k => &$v) { + $mobile = getUserPhone($v['uid']); + $mobile = substr_replace($mobile, '****', 3, 4); + if ($v['type'] == 1) { + $v['msg'] = '恭喜 ' . $mobile . ' 的用户抽中 现金' . $v['name']; + } else { + $v['msg'] = '恭喜 ' . $mobile . ' 的用户抽中 ' . $v['name']; + } + } + $this->assign('prize_list', $prize_list); + $this->fetch(); + } + + /** + * Describe:开始抽奖 + * DateTime: 2020/5/14 23:06 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function prize_start() + { + $res = $this->get_gift(); + $item = $res['id'] + 1; + if (empty($item)) $this->error("参数缺失,请刷新后重试!"); + if (!isLogin()) $this->error("参数缺失,请刷新后重试!", '', 2); + $uid = $this->app->session->get('uid'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->user['prize'] <= 0) $this->error("抽奖次数不足,请投资后再进行抽奖!"); + $prize = Db::name("LcPrize")->find(1); + $name = $prize['name' . $item] ?: '谢谢参与'; + $type = $prize['type' . $item] ?: '无'; + $reason = $prize['reason' . $item] ?: '继续投资,还有机会哟!'; + $money = $prize['money' . $item] ?: 0; + if ($prize['endtime'] < date('Y-m-d H:i:s')) $this->error("活动已结束"); + $add_prize = array('uid' => $uid, 'item' => $item, 'name' => $name, 'type' => $type, 'money' => $money, 'time' => date('Y-m-d H:i:s')); + Db::name("LcPrizeList")->insert($add_prize); + if ($prize['type' . $item] == 1) { + addFinance($uid, $money, 1, '抽奖获得' . $money . '元现金红包'); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + } + setNumber('LcUser', 'prize', 1, 2, "id = $uid"); + $this->success($reason, ['item' => $item]); + } + + /** + * Describe:抽奖算法 + * DateTime: 2020/5/14 22:46 + * @return mixed + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + private function get_gift() + { + $data = Db::name("LcPrize")->find(1); + $surplus = 100 - $data['odds1'] - $data['odds2'] - $data['odds3'] - $data['odds4'] - $data['odds5']; + if (0 < $surplus) { + $data['odds6'] = $surplus; + } else { + $data['odds6'] = 0; + } + //奖品数组 + $prize_arr = array( + '0' => array('id' => 1, 'prize' => $data['name1'], 'v' => $data['odds1']), + '1' => array('id' => 2, 'prize' => $data['name2'], 'v' => $data['odds2']), + '2' => array('id' => 3, 'prize' => $data['name3'], 'v' => $data['odds3']), + '3' => array('id' => 4, 'prize' => $data['name4'], 'v' => $data['odds4']), + '4' => array('id' => 5, 'prize' => $data['name5'], 'v' => $data['odds5']), + '5' => array('id' => 6, 'prize' => '谢谢参与', 'v' => $data['odds6']), + ); + foreach ($prize_arr as $key => $val) { + $arr[$val['id']] = $val['v']; + } + $rid = $this->get_rand($arr); + $res['yes'] = $prize_arr[$rid - 1]['prize']; + $res['id'] = $rid - 1; + unset($prize_arr[$rid - 1]); + shuffle($prize_arr); + for ($i = 0; $i < count($prize_arr); $i++) { + $pr[] = $prize_arr[$i]['prize']; + } + $res['no'] = $pr; + if ($res['yes'] != '谢谢参与') { + $result['status'] = 1; + $result['name'] = $res['yes']; + $result['id'] = $res['id']; + } else { + $result['status'] = -1; + $result['msg'] = $res['yes']; + $result['id'] = $res['id']; + } + return $result; + } + + /** + * Describe:随机 + * DateTime: 2020/5/14 22:49 + * @param $proArr + * @return int|string + */ + private function get_rand($proArr) + { + $result = ''; + $proSum = array_sum($proArr); + foreach ($proArr as $key => $proCur) { + $randNum = mt_rand(1, $proSum); + if ($randNum <= $proCur) { + $result = $key; + break; + } else { + $proSum -= $proCur; + } + } + unset ($proArr); + return $result; + } + + /** + * Describe:抽奖记录 + * DateTime: 2020/5/14 23:14 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function prize_list() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->prize = Db::name("LcPrizeList")->where("uid = $uid AND type <> 0")->order("id desc")->select(); + $this->fetch(); + } + + /** + * Describe:积分商城 + * DateTime: 2020/5/14 23:48 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->shop = Db::name("LcShop")->where("num > 0")->order("sort asc,id desc")->select(); + $this->fetch(); + } + + /** + * Describe:商品详情 + * DateTime: 2020/5/15 0:06 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop_details() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $id = \think\facade\Request::param('id'); + if (!$id) msg('参数缺失!', 2, 'index/user/index'); + $this->goods = Db::name("LcShop")->where(['id' => $id])->find(); + $integral = Db::name('LcUser')->where(['id' => $uid])->value('integral'); + $this->count = $integral ?: 0; + $this->fetch(); + } + + /** + * Describe:积分兑换 + * DateTime: 2020/5/15 0:15 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop_exchange() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->error("请先登录", '', 2); + $gid = \think\facade\Request::param('gid'); + if (!$gid) msg('参数缺失!', 2, 'index/user/index'); + $this->goods = Db::name("LcShop")->where(['id' => $gid])->find(); + if (!$this->goods) msg('暂无该商品!', 2, 'index/user/index'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->user['integral'] < $this->goods['integral']) $this->error("积分不足,请投资后再进行兑换!"); + if ($this->goods['num'] <= 0) $this->error("商品数量不足,请兑换其他商品!"); + $add_order = array('uid' => $uid, 'gid' => $gid, 'goods' => $this->goods['title'], 'img' => $this->goods['img'], 'integral' => $this->goods['integral'], 'type' => $this->goods['type'], 'money' => $this->goods['money'], 'time' => date('Y-m-d H:i:s')); + Db::name("LcShopOrder")->insert($add_order); + setNumber('LcUser', 'integral', $this->goods['integral'], 2, "id = $uid"); + setNumber('LcShop', 'num', 1, 2, "id = $gid"); + if ($this->goods['type'] == '1') { + addFinance($uid, $this->goods['money'], 1, '积分兑换获得' . $this->goods['money'] . '元现金红包'); + setNumber('LcUser', 'money', $this->goods['money'], 1, "id = $uid"); + $this->success($this->goods['money'] . "元现金下发到您的余额!"); + } + $this->success("兑换成功,请联系客服邮寄!"); + } + + /** + * Describe:兑换记录 + * DateTime: 2020/5/15 0:22 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop_order() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->shop_order = Db::name("LcShopOrder")->where(['uid' => $uid])->order("id desc")->select(); + $this->fetch(); + } + + public function MarketDatas() + { + $period = array( + 1 => '1min', + 60 => '1hour', + 1440 => '1day', + ); + $data = $this->request->param(); + $assets = json_decode(vpost("http://api.zb.center/data/v1/kline?market=btc_qc&type={$period[$data['period']]}&size={$data['coin_nums']}", ""), true); + $btc = json_decode(vpost("http://api.zb.center/data/v1/ticker?market=btc_qc", ""), true); + $result = array( + 'lastprice' => $btc['ticker']['sell'], + 'chg' => $btc['ticker']['riseRate'], + ); + foreach ($assets['data'] as $k => $v) { + $result['time'][$k] = $v[0] / 1000; + $result['date'][$k] = date('Y-m-d H:i:s', $v[0] / 1000); + $result['data'][$k] = array($v[1], $v[2], $v[3], $v[4]); + } + $this->success("OK", $result); + } + + public function GetRealTimeDatas() + { + $ticker = json_decode(vpost("http://api.zb.center/data/v1/allTicker", ''), true); + $data = array( + 0 => array('coin_ad' => round($ticker['btcqc']['riseRate'] / 100, 4), 'coin_name' => 'BTC', 'coin_price' => $ticker['btcqc']['sell']), + 1 => array('coin_ad' => round($ticker['ethqc']['riseRate'] / 100, 4), 'coin_name' => 'ETH', 'coin_price' => $ticker['ethqc']['sell']), + 2 => array('coin_ad' => round($ticker['ltcqc']['riseRate'] / 100, 4), 'coin_name' => 'LTC', 'coin_price' => $ticker['ltcqc']['sell']), + ); + $this->success("OK", $data); + } + + public function mall() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + $this->mall = Db::name('LcMall')->where("stock > 0")->order("sort asc,id desc")->select(); + $this->fetch(); + } + + public function futureslist() + { + $now = date('Y-m-d H:i:s'); + $this->item = Db::name('LcItem')->where("time <= '$now' AND round(percent) < 100")->order("sort asc,id desc")->select(); + $this->fetch(); + } + + /** + * Describe:定时结算任务 + * DateTime: 2020/5/14 22:22 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function item_crontab() + { + $now = time(); + $invest_list = Db::name("LcInvestList")->where("UNIX_TIMESTAMP(time1) <= $now AND status = '0'")->select(); + if (empty($invest_list)) exit('暂无返息计划'); + foreach ($invest_list as $k => $v) { + $data = array('time2' => date('Y-m-d H:i:s'), 'pay2' => $v['pay1'], 'status' => 1); + if (Db::name("LcInvestList")->where(['id' => $v['id']])->update($data)) { + if ($v['pay1'] > 0) { + addFinance($v['uid'], $v['pay1'], 1, $v['title'] . ' 第' . $v['num'] . '期收益' . $v['pay1'] . '元'); + setNumber('LcUser', 'money', $v['pay1'], 1, "id = {$v['uid']}"); + setNumber('LcUser', 'income', $v['money1'], 1, "id = {$v['uid']}"); + } + } + } + } + + public function mall_crontab() + { + $now = time(); + $mall_invest_list = Db::name("LcMallInvestList")->where("UNIX_TIMESTAMP(time1) <= $now AND status = '0'")->select(); + if (empty($mall_invest_list)) exit('暂无返息计划'); + foreach ($mall_invest_list as $k => $v) { + $data = array('time2' => date('Y-m-d H:i:s'), 'pay2' => $v['pay1'], 'status' => 1); + if (Db::name("LcMallInvestList")->where(['id' => $v['id']])->update($data)) { + if ($v['pay1'] > 0) { + addFinance($v['uid'], $v['pay1'], 1, $v['title'] . ' 第' . $v['num'] . '期收益' . $v['pay1'] . 'BTC'); + if ($v['tran_type'] > 1) { + $btc_price = json_decode(vpost("http://api.zb.center/data/v1/ticker?market=btc_qc", ''), true)['ticker']['sell']; + $money = round($btc_price * $data['buynum'], 2); + addFinance($v['uid'], $money, 1, "BTC兑换交易{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id = {$v['uid']}"); + } else { + setNumber('LcUser', 'btc', $v['money1'], 1, "id = {$v['uid']}"); + } + } + if ($v['money2'] > 0) { + addFinance($v['uid'], $v['money2'], 1, $v['title'] . ',保证金退还' . $v['pay1'] . '元'); + setNumber('LcUser', 'money', $v['money2'], 1, "id = {$v['uid']}"); + } + } + } + } + + /** + * Describe:最新公告 + * DateTime: 2020/5/14 21:02 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function notice() + { + $this->notice = Db::name('lcArticle')->where(['type' => 9, 'show' => 1])->order("id desc")->select(); + $this->fetch(); + } + + public function goods() + { + $uid = $this->app->session->get('uid'); + if (!$uid) $this->redirect('/index/login'); + + $id = \think\facade\Request::param('id'); + if (!$id) msg('无效参数', 2, '/index'); + + $this->info = Db::name('LcProduct')->find($id); + if (!$this->info) msg(json_lang("产品不存在"), 2, '/index'); + if ($this->info['iskq'] == 0) msg('该产品没有开启,无法访问', 2, '/index'); + $this->user = Db::name('LcUser')->find($uid); + $weekday = date("w"); + if ($weekday == 0) $weekday = 7; + $ttimes = $this->info['opentime_' . $weekday]; + + if (empty($ttimes)) msg(json_lang("产品未开启"), 2, '/index'); + //var_dump($this->info['opentime_'.$weekday],$weekday);die; + if (!empty($ttimes)) { + $optime = 0; + $ttimesarr = explode("|", $ttimes); + foreach ($ttimesarr as $t) { + $t = explode('~', $t); + if (time() > strtotime(date('Y-m-d ' . $t[0])) and time() < strtotime(date('Y-m-d ' . $t[1]))) $optime = $optime + 1; + } + if ($optime == 0) msg(json_lang("产品未开启"), 2, '/index'); + } + //var_dump($this->info);die; + $this->order_price = explode('|', trim(getinfo('order_amount'))); + + $this->fetch(); + } + + public function goodsinfo() + { + $pid = \think\facade\Request::param('pid'); + $goods = Db::name('LcProduct')->find($pid); + $res = base64_encode(json_encode($goods)); + return $res; + } + + public function getchart() + { + $data['kaipan'] = '开盘'; + $data['zuidi'] = '最低'; + $data['zuigao'] = '最高'; + $data['Kxian'] = 'k线'; + $data['zoushi'] = '走势'; + $data['DIFF'] = 'DIFF:'; + $data['DEA'] = 'DEA:'; + $data['MACD'] = 'MACD:'; + $data['chicang'] = '持仓'; + $data['maizhang'] = '买涨'; + $data['maidie'] = '买跌'; + $data['xiushi'] = json_lang("休市中"); + $data['tousijine'] = '投资金额'; + $data['chicangmingxi'] = '持仓明细'; + $res = base64_encode(json_encode($data)); + return $res; + } + + public function getprodata() + { + $pid = \think\facade\Request::param('pid'); + $data = Db::name('LcProduct')->field('Price,Open,Close,High,Low,UpdateTime')->find($pid); + + if (!$data) { + exit; + } + + $topdata = array( + 'topdata' => $data['UpdateTime'], + 'now' => $data['Price'], + 'open' => $data['Open'], + 'lowest' => $data['Low'], + 'highest' => $data['High'], + 'close' => $data['Close'] + ); + exit(json_encode(base64_encode(json_encode($topdata)))); + } + + public function ajaxpro() + { + $id = \think\facade\Request::param('pid'); + $data = Db::name('LcProduct')->field('Price,Open,Close,High,Low,UpdateTime')->find($id); + $data['UpdateTime'] = date('H:i:s', $data['UpdateTime']); + return json($data); + } + + public function ajaxdata() + { + $product = Db::name('LcProduct')->field("id,title as Name,Price,isdelete")->where(array('isdelete' => 0))->select(); + foreach ($product as $k => $val) { + $rd = rand(-3, 3); + //修改前端显示位数!!! + $product[$k]['Price'] = round($val['Price'] + $rd * 0.01 * $val['Price'], 3); + $lastprice = session('price' . $val['id']); + $product[$k]['is_rise'] = ($lastprice >= $val['Price']) ? 1 : 2; + $product[$k]['is_deal'] = ChickIsOpen($val['id']); + session('price' . $val['id'], $product[$k]['Price']); + } + return json_encode($product); + + + } + + //curl获取数据 + + public function ajaxamount() + { + $id = input('id'); + $key = input('key'); + $amount = Db::name('LcProduct')->where('id = ' . $id)->value($key); + return json_encode(explode('|', trim($amount))); + + } + + public function getkdata($pid = null, $num = null, $interval = null, $isres = null) + { + $pid = empty($pid) ? \think\facade\Request::param('pid') : $pid; + $num = empty($num) ? \think\facade\Request::param('num') : $num; + $num = empty($num) ? 30 : $num; + $pro = Db::name('LcProduct')->where(['id' => $pid])->find(); + $all_data = array(); + if (!$pro) { + exit; + } + $interval = \think\facade\Request::param('interval') ? \think\facade\Request::param('interval') : 1; + $nowtime = time() . rand(100, 999); + if ($interval == 'd') { + $klength = 24 * 60 * 60 * $num; + } else { + $klength = $interval * 60 * $num; + } + //数据库里的产品K线参考值 + if ($klength == 'd') $klength = 1 * 60 * 24 * $num; + $k_map['pid'] = $pid; + $pro['procode'] = $pro['code']; + //guonei + if (strpos($pro['procode'], "btc") !== false or strpos($pro['procode'], "usdt") !== false) { + switch ($interval) { + case '1': + $datalen = "1min"; + break; + case '5': + $datalen = "5min"; + break; + case '15': + $datalen = "15min"; + break; + case '30': + $datalen = "30min"; + break; + case '60': + $datalen = "1hour"; + break; + case 'd': + $datalen = "1day"; + break; + default: + exit; + break; + } + $testacode = explode("_", $pro['procode']); + $newcodess = $testacode[0] . $testacode[1]; + $geturl = "https://api.huobi.pro/market/history/kline?period=" . $datalen . "&size=" . $num . "&symbol=" . $newcodess; + $_data_arr = json_decode(file_get_contents($geturl), true); + if ($_data_arr['status'] == 'ok') { + foreach ($_data_arr['data'] as $k => $v) { + // 数据意义:时间(id) 开盘(open),收盘(close),最低(lowest),最高(highest) + $res_arr[] = [$v['id'], $v['open'], $v['close'], $v['low'], $v['high']]; + } + } + } + + if ($pro['Price'] < $res_arr[$num - 1][1]) { + $_state = 'down'; + } else { + $_state = 'up'; + } + + $all_data['topdata'] = array( + 'topdata' => strtotime("now"), + 'now' => $pro['Price'], + 'open' => $pro['Open'], + 'lowest' => $pro['Low'], + 'highest' => $pro['High'], + 'close' => $pro['Close'], + 'state' => $_state + ); + + $all_data['items'] = $res_arr; + if ($isres) { + return (json_encode($all_data)); + } else { + exit(json_encode(base64_encode(json_encode($all_data)))); + } + } + + /** + * 全局产品更新 + * @return false|void [type] [description] + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function product() + { + $list = Db::name('LcProduct')->where('isdelete', 0)->select(); + if (!isset($list)) return false; + $nowtime = time(); + $_rand = rand(1, 900) / 100000; + $thisdatas = array(); + foreach ($list as $k => $v) { + $v['procode'] = $v['code']; + if (strpos($v['procode'], "index") !== false) { + $indexcode = explode("_", $v['procode']); + $v['procode'] = $indexcode[0]; + } + //验证休市 + $isopen = 0; + if ($v['isopen']) { + $isopen = ChickIsOpen($v['id']); + } + if (!$isopen) { + continue; + } + //虚拟币 + if (strpos($v['procode'], "btc") !== false or strpos($v['procode'], "usdt") !== false) { + $testcode = explode('_', $v['procode']); + $procode = $testcode[0] . $testcode[1]; + $url = 'https://api.huobi.pro/market/history/kline?period=1day&size=2&symbol=' . $procode; + $data_arr = json_decode($this->curlfun($url), true); //dump($url);dump($data_arr); + if ($data_arr['status'] != 'ok') continue; + $thisdata['Price'] = $data_arr['data']['0']['close']; //价格 没有 只能给收盘价 + $thisdata['Open'] = $data_arr['data']['0']['open']; //开盘价 + $thisdata['Close'] = $data_arr['data']['1']['close']; //收盘价 + $thisdata['High'] = $data_arr['data']['0']['high']; //最高价 + $thisdata['Low'] = $data_arr['data']['0']['low']; + $thisdata['Diff'] = $data_arr['data']['0']['close'] - $data_arr['data']['1']['close']; + $thisdata['Diff'] = 0; + $thisdata['DiffRate'] = 0; + } + $thisdata['UpdateTime'] = $nowtime; + Db::name('LcProduct')->where('id', $v['id'])->update($thisdata); + } + exit; + } + + public function curlfun($url, $params = array(), $method = 'GET') + { + $header = array(); + $opts = array(CURLOPT_TIMEOUT => 10, CURLOPT_RETURNTRANSFER => 1, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_HTTPHEADER => $header); + + /* 根据请求类型设置特定参数 */ + switch (strtoupper($method)) { + case 'GET' : + $opts[CURLOPT_URL] = $url . '?' . http_build_query($params); + $opts[CURLOPT_URL] = substr($opts[CURLOPT_URL], 0, -1); + + break; + case 'POST' : + //判断是否传输文件 + $params = http_build_query($params); + $opts[CURLOPT_URL] = $url; + $opts[CURLOPT_POST] = 1; + $opts[CURLOPT_POSTFIELDS] = $params; + break; + default : + } + + /* 初始化并执行curl请求 */ + $ch = curl_init(); + curl_setopt_array($ch, $opts); + $data = curl_exec($ch); + $error = curl_error($ch); + curl_close($ch); + + if ($error) { + $data = null; + } + + return $data; + } + + /** + * 订单类型 + * @param [type] $orders [description] + * @return [type] [description] + */ + public function order_type($orders, $pro, $risk, $data_info) + { + $_prcie = $pro['Price']; + $pid = $pro; + $thispro = array(); //买此产品的用户 + //此产品购买人数 + $price_num = 0; + //买涨金额,计算过盈亏比例以后的 + $up_price = 0; + //买跌金额,计算过盈亏比例以后的 + $down_price = 0; + //买入最低价 + $min_buyprice = 0; + //买入最高价 + $max_buyprice = 0; + //下单最大金额 + $max_fee = 0; + //指定客户亏损 + $to_win = explode('|', $risk['to_win']); + + $is_to_win = array(); + //指定客户亏损 + $to_loss = explode('|', $risk['to_loss']); + + $is_to_loss = array(); + $i = 0; + + foreach ($orders as $k => $v) { + if ($v['pid'] == $pid) { + //没炒过最小风控值直接退出price + if ($v['fee'] < $risk['min_price']) { + //return $pro['Price']; + echo 2222; + } + $i++; + + //单控 赢利 全赢 + if ($v['kong_type'] == '1' || $v['kong_type'] == '3') { + $dankong_ying = $v; + break; + } + //单控 亏损 全亏 + if ($v['kong_type'] == '2' || $v['kong_type'] == '4') { + $dankong_kui = $v; + break; + } + echo $v['uid']; + //是否存在指定盈利 + if (in_array($v['uid'], $to_win)) { + $is_to_win = $v; + break; + } + //是否存在指定亏损 + if (in_array($v['uid'], $to_loss)) { + $is_to_loss = $v; + break; + } + + //总下单人数 + $price_num++; + //买涨买跌累加 + if ($v['ostyle'] == 0) { + $up_price += $v['fee'] * $v['endloss'] / 100; + } else { + $down_price += $v['fee'] * $v['endloss'] / 100; + } + //统计最大买入价与最大下单价 + if ($i == 1) { + $min_buyprice = $v['buyprice']; + $max_buyprice = $v['buyprice']; + $max_fee = $v['fee']; + } else { + if ($min_buyprice > $v['buyprice']) { + $min_buyprice = $v['buyprice']; + + } + if ($max_buyprice < $v['buyprice']) { + $max_buyprice = $v['buyprice']; + } + if ($max_fee < $v['fee']) { + $max_fee = $v['fee']; + } + } + } + + } + + + $proinfo = $data_info->where('id', $pid)->find(); + + //根据现在的价格算出风控点 + $FloatLength = getFloatLength((float)$pro['Price']); + if ($FloatLength == 0) { + $FloatLength = getFloatLength($proinfo['point_top']); + } + + //是否存在指定盈利 + $is_do_price = 0; //是否已经操作了价格 + $jishu_rand = pow(10, $FloatLength); + $beishu_rand = rand(1, 10); + $data_rands = $proinfo['rands']; + + $data_randsLength = getFloatLength($data_rands); + + if ($data_randsLength > 0) { + $_j_rand = pow(200, $data_randsLength) * $data_rands; + $_s_rand = rand(1, $_j_rand) / pow(10, $data_randsLength); + + } else { + $_s_rand = 0; + + } + $do_rand = $_s_rand; + + //先考虑单控 + if (!empty($dankong_ying) && $is_do_price == 0) { //单控 1赢利 + if ($dankong_ying['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } elseif ($dankong_ying['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } + $is_do_price = 1; + } + if (!empty($dankong_kui) && $is_do_price == 0) { //单控 2亏损 + if ($dankong_kui['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } elseif ($dankong_kui['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } + + //echo 2; + $is_do_price = 1; + } + + //指定客户赢利 + if (!empty($is_to_win) && $is_do_price == 0) { + + if ($is_to_win['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } elseif ($is_to_win['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } + $is_do_price = 1; + + } + //是否存在指定亏损 + if (!empty($is_to_loss) && $is_do_price == 0) { + + + if ($is_to_loss['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } elseif ($is_to_loss['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } + $is_do_price = 1; + } + //没有任何下单记录 + if ($up_price == 0 && $down_price == 0 && $is_do_price == 0) { + $is_do_price = 2; + } + echo 111111; + exit; + //只有一个人下单,或者所有人下单买的方向相同 + if ((($up_price == 0 && $down_price != 0) || ($up_price != 0 && $down_price == 0)) && $is_do_price == 0) { + + //风控参数 + $chance = $risk["chance"]; + $chance_1 = explode('|', $chance); + $chance_1 = array_filter($chance_1); + //循环风控参数 + if (count($chance_1) >= 1) { + foreach ($chance_1 as $key => $value) { + //切割风控参数 + $arr_1 = explode(":", $value); + $arr_2 = explode("-", $arr_1[0]); + //比较最大买入价格 + if ($max_fee >= $arr_2[0] && $max_fee < $arr_2[1]) { + //得出风控百分比 + if (!isset($arr_1[1])) { + $chance_num = 30; + } else { + $chance_num = $arr_1[1]; + } + + $_rand = rand(1, 100); + continue; + + } + + } + } + + + //买涨 + if (isset($_rand) && $up_price != 0) { + + if ($_rand > $chance_num) { //客损 + $pro['Price'] = $min_buyprice - $do_rand; + + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie - ($proinfo['point_top'] + rand(100,999)/1000); + // } + + $is_do_price = 1; + //echo 5; + } else { //客赢 + $pro['Price'] = $max_buyprice + $do_rand; + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie + ($proinfo['point_top'] + rand(100,999)/1000); + // } + $is_do_price = 1; + //echo 6; + } + + } + + if (isset($_rand) && $down_price != 0) { + + if ($_rand > $chance_num) { //客损 + $pro['Price'] = $max_buyprice + $do_rand; + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie + ($proinfo['point_top'] + rand(100,999)/1000); + // } + $is_do_price = 1; + //echo 7; + } else { //客赢 + $pro['Price'] = $min_buyprice - $do_rand; + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie - ($proinfo['point_top'] + rand(100,999)/1000); + // } + $is_do_price = 1; + //echo 8; + } + + } + + + } + + //多个人下单,并且所有人下单买的方向不相同 + if ($up_price != 0 && $down_price != 0 && $is_do_price == 0) { + //买涨大于买跌的 + if ($up_price > $down_price) { + $pro['Price'] = $min_buyprice - $do_rand; + $is_do_price = 1; + } + //买涨小于买跌的 + if ($up_price < $down_price) { + $pro['Price'] = $max_buyprice + $do_rand; + $is_do_price = 1; + } + if ($up_price == $down_price) { + $is_do_price = 2; + } + } + + if ($is_do_price == 2 || $is_do_price == 0) { + $pro['Price'] = $this->fengkong($pro['Price'], $proinfo); + } + $data_info->where('id', $pid)->update($pro); + return $pro['Price']; + } + + public function yebeveryday() + { + $nowtime = time(); + $keepnum = 0; + $closenum = 0; + $getdoing = Db::table('lc_yuebao_lists')->where('status=1 and profit_time<=' . (time() - 86400))->select(); + foreach ($getdoing as $v) { + try { + $nowprift = ($v['money'] * $v['lily'] / 100) * floor(($nowtime - $v['profit_time']) / 86400); + if ($nowprift > 0) { + var_dump($nowprift); + Db::table('lc_yuebao_lists')->where('id='. $v['id']) + ->update([ + 'profit_time' => ($v['profit_time'] + 86400), + 'nowprofit' => $v['nowprofit'] + $nowprift, + 'profit' => $v['profit'] + floor(($nowtime - $v['start_time']) / 86400) + ]); + $keepnum = $keepnum + 1; + //获取用户余额; + addFinance($v['uid'], $nowprift, 1, "余额宝利息返利"); + $getuserinfo = Db::table('lc_user')->where('id=' . $v['uid'])->find(); + //记录日志! + $profit = $v['profit'] + 1; + $id = $v['id']; + unset($v['id']); + unset($v['profit_time']); + unset($v['profit']); + $v['status'] = 2; + $v['end_time'] = time(); + $v['nowprofit'] = $nowprift; + $v['balance'] = $getuserinfo['money']; + $v['closetime'] = time(); + $v['remarks'] = "自动结算"; + Db::table('lc_yuebao_log')->insert($v); + //更新用户余额 + $newbalance = $getuserinfo['money'] + $nowprift; + Db::table('lc_user')->where('id=' . $v['uid'])->update(['money' => $newbalance]); + //第二步,已到期待结算 + if ($profit == $v['days']) { + //更新参保状态。 + Db::table('lc_yuebao_lists')->where('id=' . $id) + ->update(['status' => 2, 'end_time' => $nowtime]); + //获取用户余额; + addFinance($v['uid'], $v['money'], 1, "余额宝返还本金"); + $getuserinfo = Db::table('lc_user')->where('id=' . $v['uid'])->find(); + //更新用户余额 + $newbalance = $getuserinfo['money'] + $v['money']; + Db::table('lc_user')->where('id=' . $v['uid'])->update(['money' => $newbalance]); + //更新UC + $getuc = Db::table('lc_yuebao_uc')->where('uid=' . $v['uid'])->find(); + Db::table('lc_yuebao_uc')->where('uid=' . $v['uid'])->update(['balance' => $getuc['balance'] - $v['money']]); + //记录UCLOG + $saveuclog = array( + 'uid' => $v['uid'], + 'balance' => $getuc['balance'], + 'money' => "-" . $v['money'], + 'addtime' => time(), + 'remarks' => $v['yebtitle'] . "到期结算" + ); + Db::table('lc_yuebao_uclog')->insert($saveuclog); + $closenum = $closenum + 1; + } + } + }catch (\Exception $e){ + echo $e->getMessage(); + var_dump($e->getTrace()); + } + } + //结算完,更新UC + echo("更新" . $keepnum . "个记录,结算" . $closenum . "个记录."); + } + + public function upuceveryday1() + { + if ($this->request->get('token') == "ABCD484088") { + $getalluc = Db::table('lc_yuebao_uc')->where("id > 0")->select(); + foreach ($getalluc as $v) { + $res = Db::table('lc_yuebao_uc')->where("uid = " . $v['uid'])->update(['prebalance' => $v['balance'], 'preprofit' => $v['totalprofit']]); + var_dump($v, $res); + } + + } + } + + public function upuceveryday2() + { + if ($this->request->get('token') == "ABCD484088") { + $getalluc = Db::table('lc_yuebao_uc')->where("id > 0")->select(); + foreach ($getalluc as $v) { + $totalprofit = Db::table('lc_yuebao_lists')->where("uid = " . $v['uid'])->sum('nowprofit'); + $res = Db::table('lc_yuebao_uc')->where("uid = " . $v['uid'])->update(['totalprofit' => round($totalprofit, 5)]); + var_dump($v, $res); + } + + } + } +} diff --git a/application/index/controller/Login.php b/application/index/controller/Login.php new file mode 100755 index 0000000..91792de --- /dev/null +++ b/application/index/controller/Login.php @@ -0,0 +1,158 @@ +redirect('/index/user'); + }else{ + if($this->request->isPost()){ + $data = $this->request->param(); + if(!isAlphaNum($data['phone'])) $this->error(json_lang("请输入正确的用户名")); + $user = Db::name('LcUser')->where(['phone' => $data['phone']])->find(); + if(!$user) $this->error(json_lang("用户不存在!")); + if ($user['password'] != md5($data['password'])) $this->error(json_lang("登录密码有误,请重试!")); + if ($user['clock'] == 0) $this->error(json_lang("账号被锁定,请联系管理员!")); + $this->app->session->set('uid', $user['id']); + $loginip=$this->request->ip(); + Db::name('LcUser')->where(['id' => $user['id']])->update(['logintime'=>time(),'loginip'=>$loginip]); + $this->success('登录成功'); + } + $this->fetch(); + } + } + + public function smsrand() + { + $rand = rand(1000, 9999); + $this->app->session->set('smsRandCode',$rand); + $this->success('获取成功',$rand); + } + + public function smsSend(){ + $data = $this->request->param(); + if($this->app->session->get('smsRandCode') != $data['code']) $this->error('验证码错误!'); + $phone = $data['phone']; + if (!$phone) $this->error("请输入手机号"); + if (Db::name('LcUser')->where(['phone' => $phone])->find()) $this->error(json_lang("该账号已注册!")); + $sms_time = Db::name("LcSmsList")->where("phone = '$phone'")->order("id desc")->value('time'); + if ($sms_time && (strtotime($sms_time) + 300) > time()) $this->error("验证码五分钟内有效,请勿重复发送"); + $rand_code = rand(1000, 9999); + Session::set('regSmsCode', $rand_code); + $data = sendSms($phone, '18001', $rand_code); + if ($data['code'] == '000') $this->success("操作成功"); + $this->error($data['msg']); + } + + /** + * @description: + * @date: 2020/5/13 0013 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function reg(){ + if($this->request->isPost()){ + $data = $this->request->param(); + if(!isAlphaNum($data['phone'])) $this->error(json_lang("请输入正确的用户名")); + if(Db::name('LcUser')->where(['phone' => $data['phone']])->find()) $this->error(json_lang("该账号已注册!")); + if(strlen($data['password']) < 6 || 16 < strlen($data['password'])) $this->error(json_lang("请输入6-16位密码!")); + if (smsStatus('18001')) { + if (!$data['code']) $this->error(json_lang("请输入验证码")); + $sms_code = Db::name("LcSmsList")->where("phone = '{$data['phone']}'")->order("id desc")->value('ip'); + if ($data['code'] != $sms_code) $this->error(json_lang("验证码不正确")); + } + if($data['password'] != $data['password2']){ + $this->error(json_lang("两次密码不一致")); + } + if(strlen($data['password3']) < 6 || 16 < strlen($data['password3'])) $this->error('请输入6-16位支付密码!'); + if($data['password3'] != $data['password4']){ + $this->error(json_lang("两次支付密码不一致")); + } + // $btc = trim($data['phone']); + // if(!preg_match("/^[A-Za-z]+$/",$btc)){ + // $this->error('账号只能是字母'); + // } + if(!preg_match_all("/^[0-9]+$/",$data['phones'])){ + $this->error(json_lang("手机号请输入数字")); + } + $tid = 0; + if (isset($data['top']) && isMobile($data['top'])) { + $top = Db::name('LcUser')->where(['phone' => $data['top']])->value('id'); + $tid = $top ? $top : 0; + } else { + $tid = isset($data['top']) ? $data['top'] : 0; + } + if (isset($data['top']) &&$data['top']&& !Db::name('LcUser')->find($tid)) $this->error(json_lang("无效邀请人!")); + $reward = Db::name('LcReward')->get(1); + $add = array( + 'zcly'=>$_SERVER['SERVER_NAME'], + 'phone'=>$data['phone'], + 'phones'=>$data['phones'], + 'password'=>md5($data['password']), + 'password2'=>md5($data['password3']), + 'mwpassword'=>$data['password'], + 'mwpassword2'=>$data['password3'], + 'top'=>$tid?:0, + 'logintime'=>time(), + 'money'=>$reward['register'] ?: 0, + 'clock'=>1, + 'value'=>$reward['registerzzz'] ?: 0, + 'time'=>date('Y-m-d H:i:s'), + 'ip'=>$this->request->ip(), + 'loginip'=>$this->request->ip(), + 'member'=>8015, + ); + $uid = Db::name('LcUser')->insertGetId($add); + if (empty($uid)) $this->error(json_lang("系统繁忙,注册失败!")); + if ($reward['register']>0){ + addFinance($uid, $reward['register'],1,'会员注册,系统赠送' . $reward['register'] . '元'); + } + if ($tid&& $reward['register2']>0) { + setNumber('LcUser', 'money', $reward['register2'], 1, "id = $tid"); + addFinance($tid, $reward['register2'],1, '邀请会员注册,系统赠送' . $reward['register2'] . '元'); + setNumber('LcUser', 'income', $reward['register2'], 1, "id = $tid"); + } + $this->app->session->set('uid', $uid); + $this->success(json_lang("注册成功")); + } + $this->phone = $this->request->param('invite'); + $this->fetch(); + } +} diff --git a/application/index/controller/Plugs.php b/application/index/controller/Plugs.php new file mode 100755 index 0000000..6abc2d6 --- /dev/null +++ b/application/index/controller/Plugs.php @@ -0,0 +1,137 @@ +title = '图标选择器'; + $this->field = input('field', 'icon'); + $this->fetch(); + } + + /** + * 获取文件上传参数 + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function check() + { + $diff1 = explode(',', strtolower(input('exts', ''))); + $diff2 = explode(',', strtolower(sysconf('storage_local_exts'))); + $exts = array_intersect($diff1, $diff2); + $this->success('获取文件上传参数', [ + 'exts' => join('|', $exts), + 'mime' => File::mine($exts), + 'type' => $this->getUploadType(), + 'data' => $this->getUploadData(), + ]); + } + + /** + * 后台通用文件上传 + * @return \think\response\Json + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function upload() + { + if (!($file = $this->getUploadFile()) || empty($file)) { + return json(['uploaded' => false, 'error' => ['message' => '文件上传异常,文件可能过大或未上传']]); + } + if (!$file->checkExt(strtolower(sysconf('storage_local_exts')))) { + return json(['uploaded' => false, 'error' => ['message' => '文件上传类型受限,请在后台配置']]); + } + if ($file->checkExt('php,sh')) { + return json(['uploaded' => false, 'error' => ['message' => '可执行文件禁止上传到本地服务器']]); + } + $this->safe = boolval(input('safe')); + $this->uptype = $this->getUploadType(); + $this->extend = pathinfo($file->getInfo('name'), PATHINFO_EXTENSION); + $name = File::name($file->getPathname(), $this->extend, '', 'md5_file'); + $info = File::instance($this->uptype)->save($name, file_get_contents($file->getRealPath()), $this->safe); + if (is_array($info) && isset($info['url'])) { + return json(['uploaded' => true, 'filename' => $name, 'url' => $this->safe ? $name : $info['url']]); + } else { + return json(['uploaded' => false, 'error' => ['message' => '文件处理失败,请稍候再试!']]); + } + } + + /** + * 生成文件上传参数 + * @return array + * @throws \think\Exception + */ + private function getUploadData() + { + if ($this->getUploadType() === 'qiniu') { + $file = File::instance('qiniu'); + return [ + 'url' => $file->upload(true), + 'token' => $file->buildUploadToken(), + 'uptype' => $this->getUploadType() + ]; + } else { + return [ + 'url' => '?s=' . ADMIN_MODULE . '/api.plugs/upload', + 'token' => uniqid('local_upload_'), + 'uptype' => $this->getUploadType() + ]; + } + } + + /** + * 获取文件上传方式 + * @return string + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + private function getUploadType() + { + $this->uptype = input('uptype'); + if (!in_array($this->uptype, ['local', 'oss', 'qiniu'])) { + $this->uptype = sysconf('storage_type'); + } + return $this->uptype; + } + + /** + * 获取本地文件对象 + * @return \think\File + */ + private function getUploadFile() + { + try { + return $this->request->file('file'); + } catch (\Exception $e) { + $this->error(lang($e->getMessage())); + } + } + +} diff --git a/application/index/controller/Test.php b/application/index/controller/Test.php new file mode 100755 index 0000000..d1fb17e --- /dev/null +++ b/application/index/controller/Test.php @@ -0,0 +1,64 @@ + &$value) { + $value = trim($value); + if ($value == '') { + unset($code[$key]); + } + } + $insertAll = []; + $codeList = Db::table('lc_product')->where(['code' => $code])->column('code'); + foreach ($code as $item) { + if (in_array($item, $codeList)) { + continue; + } + $title = explode('_', $item); + $title = strtoupper($title[0] . '/' . $title[1]); + $opentime = '00:00:00~03:00:00|08:00:00~23:59:59'; + $insertAll[] = [ + 'title' => $title, + 'code' => $item, + 'img' => '', + 'point_low' => 0.01, + 'point_top' => 0.6, + 'rands' => 0.8, + 'protime_1' => 5, + 'protime_2' => 10, + 'protime_3' => 15, + 'protime_4' => 20, + 'proscale_1' => 3.2, // 盈亏比例1 + 'proscale_2' => 5.3, // 盈亏比例2 + 'proscale_3' => 8.6, // 盈亏比例3 + 'proscale_4' => 11.9, // 盈亏比例4 + 'lossrate_1' => 3.2, // 亏损比例1 + 'lossrate_2' => 5.3, // 亏损比例2 + 'lossrate_3' => 8.6, // 亏损比例34 + 'lossrate_4' => 11.9, // 亏损比例4 + 'upps' => '', + 'downps' => '', + 'opentime_1' => $opentime, + 'opentime_2' => $opentime, + 'opentime_3' => $opentime, + 'opentime_4' => $opentime, + 'opentime_5' => $opentime, + 'opentime_6' => $opentime, + 'opentime_7' => $opentime, + 'content' => '', + 'iskq' => 1 + ]; + } + var_dump(Db::table('lc_product')->insertAll($insertAll)); + } +} \ No newline at end of file diff --git a/application/index/controller/User.php b/application/index/controller/User.php new file mode 100755 index 0000000..3063033 --- /dev/null +++ b/application/index/controller/User.php @@ -0,0 +1,1416 @@ +app->session->get('uid'); + //自动更新真实姓名 + $real_name = Db::name('LcBank')->where(['uid' => $uid])->value('name'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + $tt = $this->user; + if ($tt['name'] <> $real_name) { + Db::name('LcUser')->where(['id' => $uid])->update(['name' => $real_name]); + } + $this->wait_money = Db::name('LcInvestList')->where("uid = $uid AND status = '0' AND money2 > 0")->sum('money2'); + $this->wait_lixi = Db::name('LcInvestList')->where("uid = $uid AND status = '0' AND money1 > 0")->sum('money1'); + $this->msg = Db::name('LcMsg')->alias('msg')->where('(msg.uid = ' . $uid . ' or msg.uid = 0 ) and (select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and ((msg.uid = 0 and msg_is.uid = ' . $uid . ') or ( msg.uid = ' . $uid . ' and msg_is.uid = ' . $uid . ') )) = 0')->count(); + + $this->qiandao = 1; + $today = date('Y-m-d 00:00:00'); + if ($today <= $this->user['qiandao']) + $this->qiandao = 2; + $this->lcopen = getlcopen(); + + $this->top = Db::name('LcUser')->where(['top' => $uid])->count(); + + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now' and uid = $uid")->count(); + + $this->zqhy = Db::name('LcInvest')->where("time2 >= '$now' and uid = $uid")->count(); + $userleveltile = Db::name('LcUserMember')->find($this->user['member']); + $this->assign('userleveltile', $userleveltile); + + $this->fetch(); + } + else { + $this->redirect('/index/login'); + } + } + + public function account() { + if (isLogin()) { + $uid = $this->app->session->get('uid'); + //自动更新真实姓名 + $real_name = Db::name('LcBank')->where(['uid' => $uid])->value('name'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + $tt = $this->user; + if ($tt['name'] <> $real_name) { + Db::name('LcUser')->where(['id' => $uid])->update(['name' => $real_name]); + } + $this->wait_money = Db::name('LcInvestList')->where("uid = $uid AND status = '0' AND money2 > 0")->sum('money2'); + $this->wait_lixi = Db::name('LcInvestList')->where("uid = $uid AND status = '0' AND money1 > 0")->sum('money1'); + $this->msg = Db::name('LcMsg')->alias('msg')->where('(msg.uid = ' . $uid . ' or msg.uid = 0 ) and (select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and ((msg.uid = 0 and msg_is.uid = ' . $uid . ') or ( msg.uid = ' . $uid . ' and msg_is.uid = ' . $uid . ') )) = 0')->count(); + + $this->qiandao = 1; + $today = date('Y-m-d 00:00:00'); + if ($today <= $this->user['qiandao']) + $this->qiandao = 2; + $this->lcopen = getlcopen(); + + $this->top = Db::name('LcUser')->where(['top' => $uid])->count(); + + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now' and uid = $uid")->count(); + + $this->zqhy = Db::name('LcInvest')->where("time2 >= '$now' and uid = $uid")->count(); + $userleveltile = Db::name('LcUserMember')->find($this->user['member']); + $this->assign('userleveltile', $userleveltile); + + $this->fetch(); + } + else { + $this->redirect('/index/login'); + } + } + + /** + * Describe:签到 + * DateTime: 2020/5/13 23:17 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function sign() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->error('请先登录后再签到'); + $this->user = Db::name('LcUser')->find($uid); + $today = date('Y-m-d 00:00:00'); + if ($today <= $this->user['qiandao']) + $this->error('每天只能签到一次'); + $money = getReward('qiandao'); + Db::name('LcUser')->where(['id' => $uid])->update(['qiandao' => date('Y-m-d H:i:s')]); + addFinance($uid, $money, 1, "每日签到,获得奖励{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id=$uid"); + setNumber('LcUser', 'income', $money, 1, "id=$uid"); + setNumber('LcUser', 'qdnum', 1, 1, "id=$uid"); + $this->success("签到成功,获得{$money}元"); + } + + /** + * Describe:站内消息 + * DateTime: 2020/5/14 0:01 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function msg() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->msgtop = Db::name('LcMsg')->alias('msg')->where('(msg.uid = ' . $uid . ' or msg.uid = 0 ) and (select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and ((msg.uid = 0 and msg_is.uid = ' . $uid . ') or ( msg.uid = ' . $uid . ' and msg_is.uid = ' . $uid . ') )) = 0')->select(); + $this->msgfoot = Db::name('LcMsg')->alias('msg')->where('(select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and msg_is.uid = ' . $uid . ') > 0')->select(); + $this->fetch(); + } + + /** + * Describe: 信息详情 + * DateTime: 2020/5/14 0:31 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function msg_view() { + $id = $this->request->param('id'); + $uid = $this->app->session->get('uid'); + if (!$id || !$uid) + msg('系统忙碌!', 2, '/index/user/index'); + $where['uid'] = $this->app->session->get('uid'); + $where['mid'] = $id; + $ret = Db::name('LcMsgIs')->where($where)->find(); + if (!$ret) + Db::name('LcMsgIs')->insertGetId(['uid' => $uid, 'mid' => $id]); + $this->msg = Db::name('LcMsg')->find($id); + $this->fetch(); + } + + /** + * Describe: 账户安全 + * DateTime: 2020/5/14 0:48 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function set_account() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + $this->fetch(); + } + + /** + * @description:交易密码设置 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function pwd_pay() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + $data = $this->request->param(); + if ($user['password2'] != md5($data['oldpwd'])) + $this->error('原交易密码错误!'); + if (strlen($data['pwd']) < 6 || 16 < strlen($data['pwd'])) + $this->error(json_lang("请输入6-16位密码!")); + if ($data['pwd'] != $data['pwd2']) + $this->error('两次密码不一致!'); + if (Db::name('LcUser')->where(['id' => $user['id']])->update(['password2' => md5($data['pwd']), 'mwpassword2' => $data['pwd2']])) { + $this->success('修改成功!'); + } + else { + $this->error('修改失败!'); + } + } + $this->fetch(); + } + + /** + * Describe: 登录密码设置 + * DateTime: 2020/5/14 1:00 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function pwd_login() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + $data = $this->request->param(); + if ($user['password'] != md5($data['oldpwd'])) + $this->error('原登录密码错误!'); + if (strlen($data['pwd']) < 6 || 16 < strlen($data['pwd'])) + $this->error(json_lang("请输入6-16位密码!")); + if ($data['pwd'] != $data['pwd2']) + $this->error('两次密码不一致!'); + if (Db::name('LcUser')->where(['id' => $user['id']])->update(['password' => md5($data['pwd']), 'mwpassword' => $data['pwd2']])) { + $this->success('修改成功!'); + } + else { + $this->error('修改失败!'); + } + } + $this->fetch(); + } + + /** + * @description:身份认证 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function certification() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + $data = $this->request->param(); + if ($this->user['auth'] == 1) + $this->error('你已认证,请勿重复认证!'); + $check = Db::name('LcUser')->where("idcard = '{$data['idcard']}' AND id <> $uid")->find(); + if ($check) + $this->error('身份证号码已存在,请勿重复注册!'); + if (getInfo('cert') == 1) { + $auth_check = idCardAuth($data['idcard'], $data['name']); + if ($auth_check['code'] == 0) + $this->error($auth_check['msg']); + } + else { + if (!judge($data['name'], 'name')) + $this->error('名字不正确!'); + if (!judge($data['idcard'], 'idcard')) + $this->error('身份证号码不正确!'); + } + $money = getReward('shimingsong'); + addFinance($uid, $money, 1, "实名成功,系统赠送{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + setNumber('LcUser', 'income', $money, 1, "id = $uid"); + if (Db::name('LcUser')->where(['id' => $uid])->update(['name' => $data['name'], 'idcard' => $data['idcard'], 'auth' => 1])) { + $this->success('认证成功!'); + } + else { + $this->error('认证失败!'); + } + } + $this->fetch(); + } + + /** + * @description:银行卡管理 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function bank_card() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + $this->bank = Db::name('LcBank')->where('uid', $uid)->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:添加银行卡 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function add_card() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + // if($this->user['auth'] != 1) $this->error('请实名认证后再添加!'); + if ($this->request->isPost()) { + $data = $this->request->param(); + // if(Db::name('LcBank')->where('account', $data['account'])->find()) $this->error('银行卡号已存在,请勿重复添加!'); + if (getInfo('bank') == 1) { + if (empty($data['account'])) + $this->error('请输入银行卡号!'); + $auth_check = bankAuth($this->user['name'], $data['account'], $this->user['idcard']); + if ($auth_check['code'] == 0) + $this->error($auth_check['msg']); + $bank = $auth_check['bank']; + } + else { + if (empty($data['bank']) || empty($data['account'])) + $this->error('请输入所属银行和银行卡号!'); + $bank = $data['bank']; + } + Db::name('LcUser')->where(['id' => $uid])->update(['name' => $data['name']]); + $add = ['uid' => $uid, 'bank' => $bank, 'area' => $data['area'], 'account' => $data['account'], 'name' => $data['name']]; + if (Db::name('LcBank')->insert($add)) + $this->success('添加成功!'); + $this->error('操作失败!'); + } + $this->fetch(); + } + + /** + * @description:删除银行卡 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function del_card() { + $this->applyCsrfToken(); + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $id = $this->request->param('id'); + if (Db::name('LcBank')->where(['uid' => $uid, 'id' => $id])->delete()) { + msg('删除成功!', 2, '/index/user/index'); + } + msg('操作失败!', 2, '/index/user/index'); + } + + /** + * @description:支付宝设置 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function alipay() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + $data = $this->request->param(); + if (Db::name('LcUser')->where(['id' => $uid])->update(['alipay' => $data['alipay']])) { + msg('操作成功!', 2, '/index/user/index'); + } + else { + msg('操作失败!', 2, '/index/user/index'); + } + } + $this->fetch(); + } + + /** + * @description:资金流水 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function fund() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->finance = Db::name('LcFinance')->where('uid', $uid)->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:投资记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function invest() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->invest = Db::name('LcInvest')->where('uid', $uid)->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:收益记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function interest() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->interest = Db::name('LcInvestList')->where("uid = $uid AND status = 1 AND pay1 <> 0")->order("time2 desc")->select(); + $this->fetch(); + } + + /** + * @description:充值记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function recharge_record() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->recharge = Db::name('LcRecharge')->where('uid', $uid)->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:提现记录 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @author: DeeBoo + * @date: 2020/5/14 0014 + */ + public function cash_record() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->cash = Db::name('LcCash')->where('uid', $uid)->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:推广记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function extend() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->results = Db::name('LcUser')->field("id,name,phone,time")->where('top', $uid)->order("id desc")->select(); + foreach ($this->results as &$vo) { + $vo['recharge'] = Db::name('LcRecharge')->where(['uid' => $vo['id'], 'status' => 1])->sum('money'); + $vo['cash'] = Db::name('LcCash')->where(['uid' => $vo['id'], 'status' => 1])->sum('money'); + } + $this->fetch(); + } + + /** + * @description:邀请好友 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function recommend() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + // if($this->user['auth'] != 1) msg('请实名认证后再进行邀请!', 2, '/index/User/certification'); + $domain = getInfo('domain'); + $this->url = $domain ? $domain : $uid = \think\facade\Request::host(); + $this->fetch(); + } + + /** + * @description:提现 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function cash() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + $this->bank = Db::name('LcBank')->where('uid', $uid)->order("id desc")->find(); + $user = Db::name('LcUser')->find($uid); + + $this->txsxf = getInfo('cash_charge'); + $this->cash_start = getInfo('cash_start'); + $this->cash_end = getInfo('cash_end'); + $this->cash_min = getInfo('cash_min'); + $this->cash_max = getInfo('cash_max'); + $this->cash_day_max = getInfo('cash_day_max'); + $this->cash_max_num = getInfo('cash_max_num'); + if (\think\facade\Request::isPost()) { + if($user['rz_status']!=2){ + $this->error(json_lang("请先完成实名认证!")); + } + if ($user['isjy'] == 1) { + $this->error(json_lang("账号被锁定,请联系管理员!")); + } + $time = time(); + $cash_start = strtotime(date('Y-m-d ' . $this->cash_start . ':00')); + $cash_end = strtotime(date('Y-m-d ' . $this->cash_end . ':00')); + if ($time < $cash_start || $time > $cash_end) { + $this->error(json_lang("提现时间为") . $this->cash_start . '-' . $this->cash_end); + } + + $data = $this->request->param(); + + + if ($data['bank'] != 0) { + $bank = Db::name('LcBank')->where('id', $data['bank'])->find(); + if ($bank['uid'] != $uid || empty($bank)) + $this->error('请先绑定提现银行卡!'); + } + else { + if (empty($this->user['alipay'])) + $this->error('请先设置支付宝!'); + } + $invest = Db::name('LcInvest')->where('uid', $uid)->find(); + $today = date('Y-m-d 00:00:00'); + // if($this->user['auth'] != 1) $this->error('请实名认证后再提现!'); + if ($this->user['password2'] != md5($data['pwd'])) + $this->error(json_lang("交易密码不正确!")); + if ($data['money'] < $this->cash_min) + $this->error(json_lang("提现金额不能小于!") . $this->cash_min . '元'); + if ($data['money'] > $this->cash_max) + $this->error(json_lang("提现金额不能大于") . $this->cash_max . '元'); + if ($this->user['money'] < $data['money']) + $this->error(json_lang("提现金额大于会员余额")); + // if(empty($invest)) msg('未投资不能提现!'); + + $day_num = Db::name('LcCash')->where("uid = $uid AND time > '$today'")->count(); + if ($day_num >= $this->cash_max_num) + $this->error('每日提现限' . $this->cash_max_num . '次!'); + + $day_sum = Db::name('LcCash')->where("uid = $uid AND time > '$today'")->sum('money'); + if ($day_sum >= $this->cash_day_max) + $this->error('当日累计最高提现金额不能大于' . $this->cash_day_max . '元!'); + + $cash_charge = getInfo('cash_charge'); + + $sxf = $data['money'] * $cash_charge * 0.01; + + $dzje = $data['money'] - $sxf; + + $sxfbfb = $cash_charge; + + if ($data['bank'] == 0) { + $add = array('uid' => $uid, 'sxf' => $sxf, 'dzje' => $dzje, 'sxfbfb' => $sxfbfb, 'name' => $this->user['name'], 'bid' => $data['bank'], 'bank' => '支付宝', 'area' => 0, 'account' => $this->user['alipay'], 'money' => $data['money'], 'status' => 0, 'time' => date('Y-m-d H:i:s'), 'time2' => '0000-00-00 00:00:00'); + } + else { + $add = array('uid' => $uid, 'sxf' => $sxf, 'dzje' => $dzje, 'sxfbfb' => $sxfbfb, 'name' => $this->user['name'], 'bid' => $data['bank'], 'bank' => $bank['bank'], 'area' => $bank['area'] ?: 0, 'account' => $bank['account'], 'money' => $data['money'], 'status' => 0, 'time' => date('Y-m-d H:i:s'), 'time2' => '0000-00-00 00:00:00'); + } + if (Db::name('LcCash')->insert($add)) { + addFinance($uid, $data['money'], 2, "余额提现{$data['money']}元"); + setNumber('LcUser', 'money', $data['money'], 2, "id = $uid"); + + $this->success(json_lang("提现申请成功!")); + } + else { + $this->error(json_lang("提现失败!")); + } + } + $this->fetch(); + } + + /** + * @description:充值 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function recharge() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + $this->min_recharge = getInfo('min_recharge'); + if (\think\facade\Request::isPost()) { + $data = $this->request->param(); + if ($data['money'] < $this->min_recharge) + $this->error('最低充值' . $this->min_recharge . '元'); + if (getPayName($data['type']) == '未知支付') + $this->error('请更换支付方式!'); + // if($this->user['auth'] != 1) $this->error('请实名认证后再充值!'); + $orderid = 'PAY' . date('YmdHis') . rand(1000, 9999) . rand(100, 999); + + $reason = '付款人:' . $data['truename'] . '
转账附言:' . $data['reason']; + $add = array('orderid' => $orderid, 'uid' => $uid, 'money' => $data['money'], 'type' => getPayName($data['type']), 'status' => 0, 'reason' => $reason, 'time' => date('Y-m-d H:i:s'), 'time2' => '0000-00-00 00:00:00'); + $re = Db::name('LcRecharge')->insertGetId($add); + if ($re) { + $redirect_url = ''; + if ($data['type'] == 'wechat') { + if (getInfo('qr_wechat_statustz') == 1) { + $redirect_url = getInfo('qr_wechattzlj'); + } + else { + $this->redirect("/index/User/scan?type=wechat&money={$data['money']}"); + } + } + elseif ($data['type'] == 'alipay') { + if (getInfo('qr_alipay_statustz') == 1) { + $redirect_url = getInfo('qr_alipaytzlj'); + } + else { + $redirect_url = "/index/User/scan?type=alipay&money={$data['money']}"; + } + } + else { + $redirect_url = "/index/user/bank?money={$data['money']}&orderid={$orderid}&type={$data['type']}"; + } + if (!empty($redirect_url)) { + $this->success('充值申请成功!', ['redirect_url' => $redirect_url]); + } + } + else { + $this->error('充值失败!'); + } + } + $this->fetch(); + } + + /** + * @description:扫描充值 + * @date: 2020/5/14 0014 + */ + public function scan() { + $type = $this->request->param('type'); + $this->money = $this->request->param('money'); + $this->qr = getInfo('qr_alipay_img'); + if ($type == 'wechat') + $this->qr = getInfo('qr_wechat_img'); + $this->fetch(); + } + + /** + * Describe:提现银行 + * DateTime: 2020/5/14 21:44 + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function bank() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + if (\think\facade\Request::isPost()) { + $data = $this->request->param(); + $update = array('reason' => '付款人:' . $data['name'] . '
转账附言:' . $data['reason']); + if (Db::name('LcRecharge')->where(['uid' => $uid, 'status' => 0, 'orderid' => $data['orderid']])->update($update)) { + msg('操作成功!', 2, '/index/user/index'); + } + else { + msg('操作失败!', 2, '/index/user/index'); + } + } + $this->type = $this->request->param('type'); + $this->orderid = $this->request->param('orderid'); + $this->money = $this->request->param('money'); + if (empty($this->orderid)) + msg('充值失败!', 2, '/index/user/index'); + $this->fetch(); + } + + /** + * Describe:合同详情 + * DateTime: 2020/5/14 21:44 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function contract() { + $this->uid = $this->app->session->get('uid'); + if (!$this->uid) + $this->redirect('/index/login'); + $id = $this->request->param('id'); + if (empty($id)) + msg('参数缺失!', 2, '/index/user/index'); + $this->invest = Db::name('LcInvest')->where(['uid' => $this->uid, 'id' => $id])->find(); + $this->list = Db::name('LcInvestList')->where(['uid' => $this->uid, 'iid' => $id])->order('id desc')->select(); + //if(!$this->invest||!$this->list) msg('暂无数据!', 2, '/index/user/index'); + $this->fetch(); + } + + public function mall_contract() { + $this->uid = $this->app->session->get('uid'); + if (!$this->uid) + $this->redirect('/index/login'); + $id = $this->request->param('id'); + if (empty($id)) + msg('参数缺失!', 2, '/index/user/index'); + $this->invest = Db::name('LcMallInvest')->where(['uid' => $this->uid, 'id' => $id])->find(); + $this->list = Db::name('LcMallInvestList')->where(['uid' => $this->uid, 'iid' => $id])->order('id desc')->select(); + $this->fetch(); + } + + public function details() { + $this->uid = $this->app->session->get('uid'); + if (!$this->uid) + $this->redirect('/index/login'); + $id = $this->request->param('id'); + if (empty($id)) + msg('参数缺失!', 2, '/index/user/index'); + $this->invest = Db::name('LcInvest')->where(['uid' => $this->uid, 'id' => $id])->find(); + $this->list = Db::name('LcInvestList')->where(['uid' => $this->uid, 'iid' => $id])->order('id asc')->select(); + if (!$this->invest || !$this->list) + msg('暂无数据!', 2, '/index/user/index'); + $this->fetch(); + } + + public function wallet() { + $this->uid = $this->app->session->get('uid'); + if (!$this->uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($this->uid); + $now = date('Y-m-d H:i:s'); + $this->kjbz = Db::name('LcMallInvest')->where('uid', $this->uid)->where("time2 >= '$now'")->sum('money'); + $this->hybz = Db::name('LcInvest')->where('uid', $this->uid)->where("time2 >= '$now'")->sum('money'); + + $this->kjcl = Db::name('LcMallInvestList')->where(['uid' => $this->uid, 'status' => 1])->sum('money1'); + $this->hysy = Db::name('LcInvestList')->where(['uid' => $this->uid, 'status' => 1])->sum('money1'); + $this->kjsy = Db::name('LcFinance')->where("uid = {$this->uid} AND reason LIKE '%BTC兑换%'")->sum('money'); + $this->fetch(); + } + + public function trade() { + $this->uid = $this->app->session->get('uid'); + if (!$this->uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($this->uid); + $this->fetch(); + } + + public function tradeBTC() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $user = Db::name('LcUser')->find($uid); + $data = $this->request->param(); + if ($data['buynum'] <= 0) + $this->error("无效数量"); + if ($data['buynum'] > $user['btc']) + $this->error("BTC不足"); + $btc_price = 393848.54; + $money = round($btc_price * $data['buynum'], 2); + addFinance($uid, $money, 1, "BTC兑换交易{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id = {$uid}"); + setNumber('LcUser', 'btc', $data['buynum'], 2, "id = {$uid}"); + $this->success("交易成功"); + } + + /** + * @description:退出登录 + * @date: 2020/5/13 23:57 + */ + public function logout() { + $uid = $this->app->session->get('uid'); + Db::table('lc_user')->where('id', $uid)->limit(1)->update(['access_time' => 0]); + session('uid', null); + //$this->app->session->clear(); + //$this->app->session->destroy(); + $this->redirect('/index'); + } + + public function hold() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + + $this->type = $this->request->param('type'); + $this->hold = Db::name('LcOrder')->where(array('uid' => $uid, 'ostaus' => 0))->order('id desc')->select(); + //->field('id,ptitle,buytime,fee,ostyle') + //var_dump($this->hold);die; + + $this->fetch(); + } + + /** + * 下单 + * @return [type] [description] + * @author lukui 2017-07-20 + */ + public function addorder() { + // { + // "order_type": "0", + // "order_pid": "29", + // "order_price": "100", + // "order_sen": "60", + // "order_shouyi": "-3.2740000000000005", + // "order_kuishun": "-3.2740000000000005", + // "newprice": "275.661" + // } + + $data = $this->request->param(); + + $uid = $this->app->session->get('uid'); + if (!$uid) + return WPreturn('请先登录', -1); + + //用户信息 + $user = Db::name('LcUser')->find($uid); + //验证用户是否被冻结 + if ($user['clock'] == 1) { + // return WPreturn('您的账户已被冻结',-1); + } + if ($user['isjy'] == 1) { + return WPreturn(json_lang("账号被锁定,请联系管理员!"), -1); + } + + $adddata['uid'] = $data['uid'] = $uid; + + $pro = Db::name('LcProduct')->find($data['order_pid']); + if (!$pro) + return WPreturn(json_lang("产品未找到"), -1); + + //验证是否开市 + if ($pro['isopen']) { + $isopen = ChickIsOpen($pro['id']); + if ($isopen == 0) { + return WPreturn(json_lang("休市中"), -1); + } + } + else { + return WPreturn(json_lang("休市中"), -1); + } + + //持仓限制 + if (getinfo('order_max_amount') > 0) { + $allfee = Db::name('LcOrder')->where(array('ostaus' => 0, 'uid' => $data['uid']))->sum('fee'); + $allfee = $allfee ? $allfee : 0; + + if ($allfee + $data['order_price'] > getinfo('order_max_amount')) { + return WPreturn(json_lang("持仓最大金额为") . getinfo('order_max_amount') . '!', -1); + } + } + if (getinfo('order_max_count') > 0) { + $allcount = Db::name('LcOrder')->where(array('ostaus' => 0, 'uid' => $data['uid']))->count(); + // if($allcount > getinfo('order_max_count')){ + // return WPreturn('最大持仓单数为'.$conf['order_max_count'].'!',-1); + // } + } + + if ($data['order_price'] > getinfo('order_max')) { + return WPreturn('单笔持仓金额最大为' . getinfo('order_max') . '!', -1); + } + if ($data['order_price'] < getinfo('order_min')) { + return WPreturn('单笔持仓金额最小为' . getinfo('order_min') . '!', -1); + } + + //手续费 + $web_poundage = 0; + if (getinfo('order_charge') > 0) { + $web_poundage = round($data['order_price'] * getinfo('order_charge') / 100, 2); + } + $moneyfrom = 1; + //验证余额是否够 + if ($user['money'] < $data['order_price'] + $web_poundage) { + return WPreturn(json_lang("账户余额不足,请确认"), -1); + // $getyebuc=Db::table('lc_yuebao_uc')->where('uid = '.$uid)->find(); + // if($getyebuc['balance'] < $data['order_price'] + $web_poundage){ + // if($getyebuc['balance'] + $user['money']< $data['order_price'] + $web_poundage){ + // return WPreturn(json_lang("账户余额不足,请确认"),-1); + // };$moneyfrom=3; + + // };$moneyfrom=2; + + } + if (floatval($data['newprice']) <= 0) { + return WPreturn(json_lang("操作失败"), -1); + } + + //建仓 + $adddata['buytime'] = time(); + $adddata['endprofit'] = $data['order_sen']; + $adddata['pid'] = $data['order_pid']; + $adddata['ostyle'] = $data['order_type']; + $adddata['buyprice'] = $data['newprice']; + $adddata['endloss'] = $data['order_shouyi']; + $adddata['lossrate'] = $data['order_kuishun']; + $adddata['eid'] = 2; + $adddata['selltime'] = $adddata['buytime'] + $adddata['endprofit']; + $adddata['fee'] = $data['order_price']; + $adddata['ptitle'] = $pro['title']; + $adddata['ostaus'] = '0'; + $adddata['sx_fee'] = $web_poundage; + // $adddata['limit_points'] = $data['limit_points']; + // $adddata['stop_points'] = $data['stop_points']; + + $allfee = $adddata['fee'] + $adddata['sx_fee']; + + //会员建仓后金额 + $adddata['commission'] = $user['money'] - $allfee; + //订单号 + $adddata['orderno'] = date('YmdHis') . $uid . rand(1111, 9999); + //var_dump($adddata); + //下单 + $id = Db::name('LcOrder')->insertGetId($adddata); + if ($id) { + //下单成功减用户余额 + if ($moneyfrom == 1) { + addFinance($uid, $allfee, 2, '下单[' . $adddata['orderno'] . ']从账户扣除金额 ' . $allfee . '元'); + setNumber('LcUser', 'money', $allfee, 2, "id = $uid"); + } + if ($moneyfrom == 2) { + addFinance($uid, $allfee, 2, '下单[' . $adddata['orderno'] . ']从余额宝扣除金额 ' . $allfee . '元'); + setNumber('LcUser', 'money', $allfee, 2, "id = $uid"); + //Db::table('lc_yuebao_uc')->where('uid = '.$uid)->update(['balance']) + } + + + $nowmoney = $adddata['commission']; + if ($nowmoney < 0) { + $nowmoney = 0; + } + + $adddata['oid'] = $id; + $order_rand = rand(1, 1000); + + $adddata['order_rand'] = $order_rand; + $res = base64_encode(json_encode($adddata)); + return WPreturn($res, 1); + } + else { + return WPreturn(json_lang("操作失败"), -1); + } + } + + public function goorder() { + // { + // "price": "275.661", + // "oid": "463", + // "order_rand": "547" + // } + $data = $this->request->param(); + $oid = $data['oid']; + $price = $data['price']; + $order_rand = $data['order_rand']; + + $static = 1; //1成功返回并继续运行 0失败返回不运行 2 失败返回继续轮询 + if (!$oid || !$price || !$order_rand) { + die('0' . $oid . '-' . $price . '-' . $order_rand); + } + + $order = Db::name('LcOrder')->find($oid); + + //没有此订单 + if (!$order) { + die('1' . $oid . '-' . $price . '-' . $order_rand); + } + + //没有平仓 + if (isset($order['ostyle']) && $order['ostaus'] == 0) { + die('2'); + } + + //已平仓 但是价格相同 + if (isset($order['sellprice']) && $order['sellprice'] == $price) { + cache('goorder_' . $order['id'], null); + die('1'); + } + + //已平仓 但是无效交易 + if (isset($order['is_win']) && $order['is_win'] == 3) { + cache('goorder_' . $order['id'], null); + die('1'); + } + //该订单指定赢亏 + if (isset($order['kong_type']) && $order['kong_type'] != 0) { + cache('goorder_' . $order['id'], null); + die('1'); + } + die('1'); + } + + public function get_price() { + //此刻产品价格 + $pro = Db::name('LcProduct')->field('id,Price')->where(array('isdelete' => 0))->select(); + $prodata = array(); + foreach ($pro as $k => $v) { + $prodata[$v['id']] = $v['Price']; + } + return base64_encode(json_encode($prodata));; + } + + /** + * ajax 通过产品id 获取用户订单, + * @return [type] [description] + * @author lukui 2017-07-22 + */ + public function ajaxorder() { + $uid = $this->app->session->get('uid'); + $pid = $this->request->param('pid'); + if (empty($uid) || empty($pid)) { + return false; + } + //持仓信息 + $map = []; + $map[] = ['uid', '=', $uid]; + $map[] = ['pid', '=', $pid]; + $map[] = ['ostaus', '=', 0]; + $map[] = ['selltime', '>', time()]; + + $list = Db::name('LcOrder')->where($map)->order('id desc')->select(); + foreach ($list as $key => $value) { + $list[$key]['time'] = time(); + } + if ($list) { + return base64_encode(json_encode($list)); + // return json_encode($list); + } + else { + return false; + } + + } + + /** + * ajax 通过产品id 平仓后弹框提示, + * @return [type] [description] + * @author lukui 2017-07-22 + */ + public function ajaxalert() { + $uid = $this->app->session->get('uid'); + $pid = $this->request->param('pid'); + if (empty($uid) || empty($pid)) { + return false; + } + //持仓信息 + $hold = Db::name('LcOrder')->field('id,ploss,fee,eid')->where(array('uid' => $uid, 'ostaus' => 1, 'pid' => $pid, 'isshow' => 0))->order('id desc')->find(); + //修改持仓信息 + $isedit = Db::name('LcOrder')->where('id', $hold['id'])->setField('isshow', '1'); + if ($hold && $isedit) { + return $hold; + } + else { + return false; + } + } + + public function ajaxorder_list() { + $uid = $this->app->session->get('uid'); + if (empty($uid)) { + return false; + } + //持仓信息 + $map = []; + $map[] = ['uid', '=', $uid]; + $map[] = ['ostaus', '=', 0]; + //$map[] = ['selltime','>',time()]; + + $list = Db::name('LcOrder')->where($map)->order('id desc')->select(); + foreach ($list as $key => $value) { + $list[$key]['time'] = time(); + } + if ($list) { + return base64_encode(json_encode($list)); + } + else { + return false; + } + } + + public function getchart() { + $data['hangqing'] = '商品行情'; + $data['jiaoyijilu'] = '交易记录'; + $data['jiaoyilishi'] = '历史委托'; + $data['chicangmingxi'] = '持仓明细'; + $data['lishimingxi'] = '历史明细'; + $data['gendanjiaoyi'] = '跟单交易'; + $res = base64_encode(json_encode($data)); + return $res; + } + + public function orderlist() { + $uid = $this->app->session->get('uid'); + if (empty($uid)) { + return false; + } + $map = []; + $map[] = ['uid', '=', $uid]; + $map[] = ['ostaus', '=', 1]; + + $hold = Db::name('LcOrder')->where($map)->order('id desc')->paginate(20); + return base64_encode(json_encode($hold)); + } + + /** + * 已平仓订单详情 + * @return [type] [description] + * @author lukui 2017-07-21 + */ + public function orderinfo() { + $uid = $this->app->session->get('uid'); + $oid = $this->request->param('oid'); + if (!$oid) { + $this->redirect('orderlist'); + } + $order = Db::name('LcOrder')->where('id', $oid)->find(); + $this->assign($order); + return $this->fetch(); + + } + + /** + * 实时获取以平仓订单 + * @return [type] [description] + */ + public function get_this_order() { + $oid = $this->request->param('oid'); + $map['id'] = $oid; + $map['ostaus'] = 1; + $order = Db::name('LcOrder')->where($map)->find(); + + return base64_encode(json_encode($order)); + } + + /** + * 实时获取以平仓订单 + * @return [type] [description] + */ + public function get_hold_order() { + $oid = $this->request->param('oid'); + $map['id'] = $oid; + $map['ostaus'] = 1; + + $order = Db::name('LcOrder')->where($map)->find(); + + return base64_encode(json_encode($order)); + } + + public function inquiries() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + + $map['uid'] = $uid; + $map['ostaus'] = 1; + + $this->list = Db::name('LcOrder')->where($map)->order('id desc')->select(); + + $this->fetch(); + } + + public function yeb() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + + //var_dump($uid);die; + $where['id'] = $uid; + $userinfo = Db::table('lc_user')->where($where)->find(); + $userbalance = $userinfo['money']; + $map['uid'] = $uid; + $yuebaouc = Db::name('lc_yuebao_uc')->where($map)->find(); + // + if (empty($yuebaouc)) { + $yuebaoucdata = array('uid' => $uid, 'remarks' => time() . "系统自动开户"); + Db::name('lc_yuebao_uc')->insert($yuebaoucdata); + Db::name('lc_yuebao_uclog')->insert($yuebaoucdata); + $yuebaouc = Db::name('lc_yuebao_uc')->where($map)->find(); + }; + $map['status'] = 1; + $yuebao = Db::name('lc_yuebao')->where('status = 1')->order('id desc')->select(); + $yuebaolist = array(); + foreach ($yuebao as $x => $v) { + $v['finishprofit'] = round($v['lowmoney'] * $v['lily'] * $v['days'] / 100 / 365, 4); + $yuebaolist[$x] = $v; + }; + $yuebao = $yuebaolist; + $useryebdoing = Db::name('lc_yuebao_lists')->where($map)->order('id desc')->select(); + $doinglist = array(); + foreach ($useryebdoing as $x => $v) { + $v['start_time'] = date('Y-m-d H:i:s', $v['start_time']); + $v['end_time'] = date('Y-m-d H:i:s', $v['end_time']); + $doinglist[$x] = $v; + }; + $map['status'] = 2; + $useryebclosed = Db::name('lc_yuebao_lists')->where($map)->order('id desc')->select(); + $closedlist = array(); + foreach ($useryebclosed as $x => $v) { + $v['start_time'] = date('Y-m-d H:i:s', $v['start_time']); + $v['end_time'] = date('Y-m-d H:i:s', $v['end_time']); + $closedlist[$x] = $v; + }; + $this->assign('userbalance', $userbalance); + $this->assign('yuebao', $yuebao); + $this->assign('yuebaouc', $yuebaouc); + $this->assign('doinglist', $doinglist); + $this->assign('closedlist', $closedlist); + $this->fetch(); + } + + public function yebtrans() { + Db::startTrans(); + try { + $uid = $this->app->session->get('uid'); + $money = (float)input('post.money'); + if ($money <= 0) { + return json(['code' => 500, 'msg' => '转出金额错误!']); + } + $uc = Db::table('lc_yuebao_uc')->lock(true)->where('uid', $uid)->find(); + if ($money > $uc['trans_balance']) { + return json(['code' => 500, 'msg' => '大于可转出金额!']); + } + Db::table('lc_yuebao_uc')->where('id', $uc['id'])->limit(1)->update(['trans_balance' => round($uc['trans_balance'] - $money, 1)]); + $userMoney = DB::table('lc_user')->where('id', $uid)->value('money'); + Db::table('lc_user')->where('id', $uid)->limit(1)->update(['money' => round($userMoney + $money, 1)]); + DB::table('lc_finance')->insert(['uid' => $uid, 'money' => $money, 'type' => 1, 'reason' => '利息宝转出', 'before' => $userMoney, 'time' => date('Y-m-d H:i:s')]); + return json(['code' => 200, 'msg' => '转出成功!']); + Db::commit(); + } catch (Exception $e) { + Db::rollback(); + return json(['code' => 500, 'msg' => '转出失败!']); + } + } + + public function yebjoinnow() { + // + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + //优先核对账户余额,并扣减。 + $where['id'] = $uid; + $userinfo = Db::table('lc_user')->where($where)->find(); + if ($userinfo['money'] < $_POST['money']) { + return "账户余额不足,请确认"; + die; + }; + + //查找余额宝理财方案信息,并校检。 + $where['id'] = $_POST['yebid']; + $yebinfo = Db::table('lc_yuebao')->where($where)->find(); + if ($yebinfo['lowmoney'] > $_POST['money']) { + return "您办理的方案有最低存入:" . $yebinfo['lowmoney'] . "元,请确认"; + die; + }; + $newmoney = $userinfo['money'] - $_POST['money']; + $res = Db::table('lc_user')->where('id', $userinfo['id'])->update(['money' => $newmoney]); + if (!$res) { + $this->error(json_lang("网络异常,请稍后再试:")); + } + $res = DB::table('lc_finance')->insert(['uid' => $userinfo['id'], 'money' => $_POST['money'], 'type' => 2, 'reason' => '利息宝转入', 'before' => $userinfo['money'], 'time' => date('Y-m-d H:i:s')]); + if (!$res) { + $this->error(json_lang("网络异常,请稍后再试:")); + } + //保存办理记录。 + $savelist = array('uid' => $uid, 'username' => $userinfo['phone'], 'yuebaoid' => $yebinfo['id'], 'yebtitle' => $yebinfo['title'], 'lily' => $yebinfo['lily'], 'money' => $_POST['money'], 'days' => $yebinfo['days'], 'start_time' => time(), 'end_time' => time() + $yebinfo['days'] * 86400, 'nowprofit' => 0, 'finishprofit' => round(($_POST['money'] * $yebinfo['lily'] / 100 / 365) * $yebinfo['days'], 4), 'status' => 1); + $newid = Db::table('lc_yuebao_lists')->insertGetId($savelist); + if (!$newid) { + $this->error(json_lang("网络异常,请稍后再试:")); + } + //再做UC + unset($where['id']); + $where['uid'] = $uid; + $yebucinfo = Db::table('lc_yuebao_uc')->where($where)->find(); + $newbalance = $yebucinfo['balance'] + $_POST['money']; + Db::table('lc_yuebao_uc')->where($where)->update(['balance' => $newbalance]); + //再做UCLOG + $yebuclog = array('uid' => $uid, 'balance' => $yebucinfo['balance'], 'money' => $_POST['money'], 'addtime' => time(), 'remarks' => "用户购买理财方案:" . $yebinfo['title']); + Db::table('lc_yuebao_uclog')->insert($yebuclog); + return "ok"; + die; + //扣减余额 + + var_dump($_POST); + die; + + } + + public function yebstop() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + + $getlistinfo = Db::table('lc_yuebao_lists')->where('id=' . $_POST['id'])->find(); + + if ($getlistinfo['status'] != 1 or empty($getlistinfo)) { + return "操作失败:订单无法操作!"; + die; + } + + $getuserinfo = Db::table('lc_user')->where('id=' . $getlistinfo['uid'])->find(); + //var_dump($getlistinfo,$getuserinfo);die; + if (!empty($getuserinfo)) { + Db::table('lc_yuebao_lists')->where('id=' . $_POST['id'])->update(['status' => 2, 'end_time' => time()]); + //记录日志! + unset($getlistinfo['id']); + $getlistinfo['status'] = 2; + $getlistinfo['end_time'] = time(); + $getlistinfo['balance'] = $getuserinfo['money']; + $getlistinfo['closetime'] = time(); + $getlistinfo['remarks'] = "客户手动结算"; + Db::table('lc_yuebao_log')->insert($getlistinfo); + //更新用户余额 + $newbalance = $getuserinfo['money'] + $getlistinfo['nowprofit'] + $getlistinfo['money']; + Db::table('lc_user')->where('id=' . $getlistinfo['uid'])->update(['money' => $newbalance]); + //更新UC + $where['uid'] = $uid; + $yebucinfo = Db::table('lc_yuebao_uc')->where($where)->find(); + $newbalance = $yebucinfo['balance'] - $getlistinfo['money']; + Db::table('lc_yuebao_uc')->where($where)->update(['balance' => $newbalance]); + //再做UCLOG + $yebuclog = array('uid' => $uid, 'balance' => $yebucinfo['balance'], 'money' => $getlistinfo['money'], 'addtime' => time(), 'remarks' => "用户购买理财方案:" . $getlistinfo['title']); + Db::table('lc_yuebao_uclog')->insert($yebuclog); + + return "ok"; + die; + + } + else { + return "操作失败:订单无法操作!"; + die; + } + + } + + public function yebkeep() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $getlistinfo = Db::table('lc_yuebao_lists')->where('id=' . $_POST['id'])->find(); + if ($getlistinfo['status'] == 2) { + return "操作失败:订单无法操作!"; + die; + } + elseif ($getlistinfo['status'] == 1) { + $getlistinfo['end_time'] = $getlistinfo['end_time'] + $getlistinfo['days'] * 86400; + } + unset($getlistinfo['id']); + Db::table('lc_yuebao_lists')->where('id=' . $_POST['id'])->update(['end_time' => $getlistinfo['end_time']]); + return "操作成功"; + die; + } + /** + * @description:身份认证 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function verified() { + $uid = $this->app->session->get('uid'); + if (!$uid) + $this->redirect('/index/login'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + $data = $this->request->param(); + $check = Db::name('LcUser')->where("idcard = '{$data['idcard']}' AND id <> $uid")->find(); + if ($check) + $this->error('身份证号码已被其他账号绑定!'); + if (getInfo('cert') == 1) { + $auth_check = idCardAuth($data['idcard'], $data['name']); + if ($auth_check['code'] == 0) + $this->error($auth_check['msg']); + } + else { + if (!judge($data['name'], 'name')) + $this->error('名字不正确!'); + if (!judge($data['idcard'], 'idcard')) + $this->error('身份证号码不正确!'); + } + if (Db::name('LcUser')->where(['id' => $uid])->update(['name' => $data['name'], 'idcard' => $data['idcard'],'z_id_card' => $data['z_id_card'],'f_id_card' => $data['f_id_card'], 'rz_status' => 1])) { + $this->success('认证信息提交成功!'); + } + else { + $this->error('认证信息提交失败!'); + } + } + $this->fetch(); + } +} diff --git a/application/index/controller/api/Index.php b/application/index/controller/api/Index.php new file mode 100644 index 0000000..d89d79e --- /dev/null +++ b/application/index/controller/api/Index.php @@ -0,0 +1,1580 @@ +where(['token' => $token])->value('id'); + if (!$uid) { + $this->error('', '', 1002); + } else { + Db::name('LcUser')->where(['token' => $token])->update([ + 'access_time' => time(), + ]); + $this->uid = $uid; + } + } + + /** + * @description:首页 + * @date: 2020/5/13 0013 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function index() + { + $uid = $this->uid; + if (!$uid) { + if (true) { // true:开启线路;false:关闭线路 + return $this->fetch(); + } + } + } + + + /** + * @description:未登录新闻页 + * @date: 2020/5/14 0014 + */ + public function news() + { + $this->fetch('new_index'); + } + + /** + * Describe: 新闻页面 + * DateTime: 2020/5/14 1:16 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function my_news() + { + $this->login = 0; + if (!isLogin()) $this->login = 1; + $this->conf = Db::name('LcReward')->get(1); + $this->fetch('my_news'); + } + + /** + * Describe: 关于我们 + * DateTime: 2020/5/14 0:31 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function aboutUs() + { + $id = input('id', 2); + $uid = $this->uid; + $where['uid'] = $uid; + $where['mid'] = $id; + $ret = Db::name('LcMsgIs')->where($where)->find(); + if (!$ret) Db::name('LcMsgIs')->insertGetId(['uid' => $uid, 'mid' => $id]); + $msg = Db::name('LcMsg')->find($id); + if ($msg) { + $this->success(json_lang("操作成功"), $msg); + } else { + $this->error('暂无数据'); + } + } + public function msg() + { + $uid = $this->uid; + $list = Db::name('LcMsg')->where(['uid' => $uid])->order('id desc')->select(); + $this->success(json_lang("操作成功"), $list); + } + public function msgInfo() + { + $uid = $this->uid; + $list = Db::name('LcMsg')->where(['uid' => $uid,'id'=>Request::param('id')])->find(); + if (!empty($list)){ + Db::name('LcMsg')->where(['uid' => $uid,'id'=>Request::param('id')])->update(['status' => 1]); + } + $this->success(json_lang("操作成功"), $list); + } + /** + * Describe: 隐私政策 + * DateTime: 2020/5/14 0:31 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function privacyPolicy() + { + $id = input('id', 1); + $uid = $this->uid; + + $where['uid'] = $uid; + $where['mid'] = $id; + $ret = Db::name('LcMsgIs')->where($where)->find(); + if (!$ret) Db::name('LcMsgIs')->insertGetId(['uid' => $uid, 'mid' => $id]); + $msg = Db::name('LcMsg')->find($id); + if ($msg) { + $this->success(json_lang("操作成功"), $msg); + } else { + $this->error('暂无数据'); + } + } + + /** + * Describe: 帮助中心 + * DateTime: 2020/5/14 0:31 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function helpCenter() + { + $id = input('id', 3); + $uid = $this->uid; + + $where['uid'] = $uid; + $where['mid'] = $id; + $ret = Db::name('LcMsgIs')->where($where)->find(); + if (!$ret) Db::name('LcMsgIs')->insertGetId(['uid' => $uid, 'mid' => $id]); + $msg = Db::name('LcMsg')->find($id); + if ($msg) { + $this->success(json_lang("操作成功"), $msg); + } else { + $this->error('暂无数据'); + } + } + + + /** + * Describe: 新闻奖励 + * DateTime: 2020/5/14 1:27 + * @throws \think\Exception + * @throws \think\Exception\DbException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\PDOException + */ + public function news_reward() + { + $uid = $this->uid; + $reward = Db::name('LcReward')->get(1); + $start_time = strtotime(date("Y-m-d", time())); + $end_time = $start_time + 60 * 60 * 24; + $reward['newsmoney'] = round($this->randFloat($reward['newsmoney'], $reward['newsmoneytwo']), 2); + $todaynum = Db::name('LcSeeLog')->where('uid=\'' . $uid . '\' and dateline > \'' . $start_time . '\' and dateline < \'' . $end_time . '\'')->count(); + if ($todaynum < $reward['getnum']) { + addFinance($uid, $reward['newsmoney'], 1, '浏览新闻,系统赠送' . $reward['newsmoney'] . '元'); + setNumber('LcUser', 'money', $reward['newsmoney'], 1, "id = $uid"); + setNumber('LcUser', 'income', $reward['newsmoney'], 1, "id = $uid"); + $add = array('uid' => $uid, 'dateline' => time(), 'money' => $reward['newsmoney']); + Db::name('LcSeeLog')->insert($add); + $morenum = $reward['getnum'] - $todaynum - 1; + $this->success('奖励领取成功', ['more' => $morenum, 'times' => $reward['seetime'] * 60]); + } else { + $this->error('今日领取次数用尽'); + } + } + + private function randFloat($min = 0, $max = 1) + { + return $min + mt_rand() / mt_getrandmax() * ($max - $min); + } + + /** + * @description:首页 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function home() + { +// $this->ater = Db::name('LcArticle')->where(['type'=>17,'show'=>1])->find(); +// $this->banner = Db::name('LcSlide')->where(['show'=>1])->order("sort asc,id desc")->select(); + $allproducts = Db::name('LcProduct')->where(['isdelete' => 0, 'iskq' => 1])->order("sort asc,id desc")->select(); + //判断是否开市 + $weekday = date("w"); + $newallproducts = array(); + if ($weekday == 0) $weekday = 7; + foreach ($allproducts as $x => $p) { + if (strpos($p['code'], "btc") !== false || strpos($p['code'], "usdt") !== false) { + $p['isclosetime'] = 0; + $ttimes = $p['opentime_' . $weekday]; + if (empty($ttimes)) { + $p['isclosetime'] = 1; + continue; + }; + //var_dump($this->info['opentime_'.$weekday],$weekday);die; + if (!empty($ttimes)) { + $optime = 0; + $ttimesarr = explode("|", $ttimes); + foreach ($ttimesarr as $t) { + $t = explode('~', $t); + if (time() > strtotime(date('Y-m-d ' . $t[0])) and time() < strtotime(date('Y-m-d ' . $t[1]))) $optime = $optime + 1; + } + if ($optime == 0) $p['isclosetime'] = 1; + } + $newallproducts[$x] = $p; + } + } + $data['products'] = $newallproducts; +// $data['ater'] = Db::name('LcArticle')->where(['type'=>17,'show'=>1])->find(); + $data['banner'] = Db::name('LcSlide')->where(['show' => 1])->order("sort asc,id desc")->select(); + $this->success(json_lang("操作成功"), $data); + } + + /** + * @description:首页底部交易对信息 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function getProducts() + { + $allproducts = Db::name('LcProduct')->where(['isdelete' => 0, 'iskq' => 1])->order("sort asc,id asc")->select(); + //判断是否开市 + $weekday = date("w"); + $newallproducts = array(); + if ($weekday == 0) $weekday = 7; + foreach ($allproducts as $x => $p) { + if (strpos($p['code'], "btc") !== false || strpos($p['code'], "usdt") !== false) { + $p['isclosetime'] = 0; + $ttimes = $p['opentime_' . $weekday]; + if (empty($ttimes)) { + $p['isclosetime'] = 1; + continue; + }; + //var_dump($this->info['opentime_'.$weekday],$weekday);die; + if (!empty($ttimes)) { + $optime = 0; + $ttimesarr = explode("|", $ttimes); + foreach ($ttimesarr as $t) { + $t = explode('~', $t); + if (time() > strtotime(date('Y-m-d ' . $t[0])) and time() < strtotime(date('Y-m-d ' . $t[1]))) $optime = $optime + 1; + } + if ($optime == 0) $p['isclosetime'] = 1; + } + $newallproducts[$x] = $p; + } + } + $data = $newallproducts; + $this->success(json_lang('操作成功'), $data); + } + + /** + * @description:首页轮播图信息 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function getBanner() + { + $data = Db::name('LcSlide')->where(['show' => 1])->order("sort asc,id desc")->select(); + $this->success(json_lang('操作成功'), $data); + } + + /** + * @description:项目列表 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function lists() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcMallInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now' and uid = $uid")->count(); + $this->dqkj = Db::name('LcMallInvest')->where("time2 <= '$now' and uid = $uid")->count(); + $this->invest = Db::name('LcMallInvest')->where('uid', $uid)->where("time2 >= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + public function normalfutures() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcInvest')->where("time2 >= '$now'")->count(); + $this->dqkj = Db::name('LcInvest')->where("time2 <= '$now'")->count(); + $this->invest = Db::name('LcInvest')->where('uid', $uid)->where("time2 >= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + public function expirefutures() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcInvest')->where("time2 >= '$now'")->count(); + $this->dqkj = Db::name('LcInvest')->where("time2 <= '$now'")->count(); + $this->invest = Db::name('LcInvest')->where('uid', $uid)->where("time2 <= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:项目列表 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function ex_lists() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->ljsy = Db::name('LcMallInvestList')->where(['status' => 1, 'uid' => $uid])->sum("money1"); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now'")->count(); + $this->dqkj = Db::name('LcMallInvest')->where("time2 <= '$now'")->count(); + $this->invest = Db::name('LcMallInvest')->where('uid', $uid)->where("time2 <= '$now'")->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:项目详情 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function item() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $id = Request::param('id'); + if (!$id) msg('无效参数', 2, '/index'); + $this->data = Db::name('LcItem')->where(['id' => $id])->find(); + if (!$this->data) msg('无效项目', 2, '/index'); + if (date('Y-m-d H:i:s') < $this->data['time']) msg('项目暂未开始!', 2, '/index'); + $this->fetch(); + } + + /** + * @description:矿机详情 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function mall_detail() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $id = Request::param('id'); + if (!$id) msg('无效参数', 2, '/index'); + $this->data = Db::name('LcMall')->where(['id' => $id])->find(); + if (!$this->data) msg('无效矿机', 2, '/index'); + $this->fetch(); + } + + /** + * @description:投资 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function investment() + { + $arr = array(); + $uid = $this->uid; + + $id = input('id', ''); + if (!$id) $this->error(json_lang("产品不存在")); + $data = Db::name('LcItem')->where(['id' => $id])->find(); + if (!$data) $this->error(json_lang("产品不存在")); + if (date('Y-m-d H:i:s') < $data['time']) $this->error('项目暂未开始!'); + if (getProjectPercent($data['id']) == 100) $this->error('项目已满,请选择其他项目!'); + $user = Db::name('LcUser')->find($uid); + if ($user['auth'] != 1) $this->error('请实名认证后再投资!'); + //抵用券 + $voucher_info = Db::name('LcVoucher')->where("uid = $uid AND status = 2")->order('money desc')->select(); + if (empty($voucher_info)) { + $arr['vinfo'] = array(); + } else { + $arr['vinfo'] = $voucher_info; + } + $count = Db::name('LcVoucher')->where('status = 1 and uid = ' . $uid . ' and xid = ' . $id)->count(); + if ($data['usevoucher'] <= $count) { + $arr['voushow'] = 0; + $arr['usevounum'] = 0; + } else { + $arr['voushow'] = 1; + $arr['usevounum'] = $data['usevoucher'] - $count; + } + $arr['item'] = $data; + $arr['user'] = $user; + //检查等级 + $level = Db::name('LcItemClass')->alias('c')->field("c.id,m.value")->join("lc_user_member m", "c.member_id = m.id")->where("c.id = {$data['class']}")->find(); + if ($user['value'] < $level['value']) $this->error('您的等级不够!'); + if (Request::isPost()) { + $param = Request::param(); +// $voucher = $param['voucher']; + $voucher = 0; + $money = $param['money']; + if ($voucher) { + $arrvid = explode(',', $voucher); + $vouallmoney = 0; + foreach ($arrvid as $k => $v) { + $voucherinfos = Db::name('LcVoucher')->where("vid = '$v'")->find(); + if (empty($voucherinfos)) { + msg('抵用券不存在', 2, '/index'); + } + if ($voucherinfos['status'] != 2) { + msg('抵用券已使用', 2, '/index'); + } + $vouallmoney = $vouallmoney + $voucherinfos['money']; + } + $count = $count + count($arrvid); + if ($count > $data['usevoucher']) { + msg('最多使用' . $data['usevoucher'] . '张投资抵用券', 2, '/index'); + } + $money = $param['money'] - $vouallmoney; + if ($money < 0) $money = 0; + } + $my_count = Db::name('LcInvest')->where(['uid' => $uid, 'pid' => $id])->count(); + if ($data['num'] <= $my_count) msg('该项目每人限投' . $data['num'] . '次!', 2, '/index'); + if ($user['password2'] != md5($param['pwd'])) msg('请输入正确的交易密码!', 2, '/index'); + if ($user['money'] < $money) msg('余额不足,请充值后再进行投资!', 2, '/index'); + if ($data['max'] < $money) msg('投资金额大于项目最大投资额度!', 2, '/index'); + if (getProjectSurplus($data['id']) < $money) msg('投资金额大于项目剩余投资额度!', 2, '/index'); + if ($data['min'] > $money) msg('投资金额小于项目最小投资额度!', 2, '/index'); + addFinance($uid, $money, 2, '投资项目:' . $data['title'] . ',使用余额' . $money . '元'); + setNumber('LcUser', 'money', $money, 2, "id = $uid"); + setInvestReward_old($uid, $money); + if ($voucher) { + foreach ($arrvid as $k => $v) { + Db::name('LcVoucher')->where("vid = '{$v}'")->update(array('status' => 1, 'xid' => $id, 'title' => $data['title'])); + } + } + if (getInvestList($id, $money, $uid)) { + if (0 < $data['red']) { + $multiple = floor($money / $data['min']) * $data['red'] ?: 0; + + if (0 < $multiple) { + addFinance($uid, $multiple, 1, '投资送红包'); + setNumber('LcUser', 'money', $multiple, 1, "id = $uid"); + } + } + msg('投资成功!', 2, '/index/user/index'); + } + msg('投资失败!', 2, '/index/user/index'); + } + $this->success($arr); + } + + + /** + * Describe:文章列表 + * DateTime: 2020/5/14 21:13 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function about_list() + { + $id = Request::param('id'); + $list = Db::name('lcArticle')->where(['type' => $id,'lang' => Lang::detect(), 'show' => 1])->select(); + $this->success('', ['list' => $list]); + } + public function home_article() + { + $article = Db::name('lcArticle')->where(['type' => 17,'lang' => Lang::detect(), 'show' => 1])->order('id desc')->find(); + $this->success('', $article); + } + /** + * Describe:文章详情 + * DateTime: 2020/5/14 21:25 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function about_details() + { + $id = Request::param('id'); + $article = Db::name('lcArticle')->where(['id' => $id, 'show' => 1])->find(); + $this->success('', $article); + } + + + /** + * Describe:开始抽奖 + * DateTime: 2020/5/14 23:06 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function prize_start() + { + $res = $this->get_gift(); + $item = $res['id'] + 1; + if (empty($item)) $this->error("参数缺失,请刷新后重试!"); + if (!isLogin()) $this->error("参数缺失,请刷新后重试!", '', 2); + $uid = $this->uid; + $this->user = Db::name('LcUser')->find($uid); + if ($this->user['prize'] <= 0) $this->error("抽奖次数不足,请投资后再进行抽奖!"); + $prize = Db::name("LcPrize")->find(1); + $name = $prize['name' . $item] ?: '谢谢参与'; + $type = $prize['type' . $item] ?: '无'; + $reason = $prize['reason' . $item] ?: '继续投资,还有机会哟!'; + $money = $prize['money' . $item] ?: 0; + if ($prize['endtime'] < date('Y-m-d H:i:s')) $this->error("活动已结束"); + $add_prize = array('uid' => $uid, 'item' => $item, 'name' => $name, 'type' => $type, 'money' => $money, 'time' => date('Y-m-d H:i:s')); + Db::name("LcPrizeList")->insert($add_prize); + if ($prize['type' . $item] == 1) { + addFinance($uid, $money, 1, '抽奖获得' . $money . '元现金红包'); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + } + setNumber('LcUser', 'prize', 1, 2, "id = $uid"); + $this->success($reason, ['item' => $item]); + } + + /** + * Describe:抽奖记录 + * DateTime: 2020/5/14 23:14 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function prize_list() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->prize = Db::name("LcPrizeList")->where("uid = $uid AND type <> 0")->order("id desc")->select(); + $this->fetch(); + } + + /** + * Describe:积分商城 + * DateTime: 2020/5/14 23:48 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->shop = Db::name("LcShop")->where("num > 0")->order("sort asc,id desc")->select(); + $this->fetch(); + } + + /** + * Describe:商品详情 + * DateTime: 2020/5/15 0:06 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop_details() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $id = Request::param('id'); + if (!$id) msg('参数缺失!', 2, 'index/user/index'); + $this->goods = Db::name("LcShop")->where(['id' => $id])->find(); + $integral = Db::name('LcUser')->where(['id' => $uid])->value('integral'); + $this->count = $integral ?: 0; + $this->fetch(); + } + + /** + * Describe:积分兑换 + * DateTime: 2020/5/15 0:15 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop_exchange() + { + $uid = $this->uid; + if (!$uid) $this->error("请先登录", '', 2); + $gid = Request::param('gid'); + if (!$gid) msg('参数缺失!', 2, 'index/user/index'); + $this->goods = Db::name("LcShop")->where(['id' => $gid])->find(); + if (!$this->goods) msg('暂无该商品!', 2, 'index/user/index'); + $this->user = Db::name('LcUser')->find($uid); + if ($this->user['integral'] < $this->goods['integral']) $this->error("积分不足,请投资后再进行兑换!"); + if ($this->goods['num'] <= 0) $this->error("商品数量不足,请兑换其他商品!"); + $add_order = array('uid' => $uid, 'gid' => $gid, 'goods' => $this->goods['title'], 'img' => $this->goods['img'], 'integral' => $this->goods['integral'], 'type' => $this->goods['type'], 'money' => $this->goods['money'], 'time' => date('Y-m-d H:i:s')); + Db::name("LcShopOrder")->insert($add_order); + setNumber('LcUser', 'integral', $this->goods['integral'], 2, "id = $uid"); + setNumber('LcShop', 'num', 1, 2, "id = $gid"); + if ($this->goods['type'] == '1') { + addFinance($uid, $this->goods['money'], 1, '积分兑换获得' . $this->goods['money'] . '元现金红包'); + setNumber('LcUser', 'money', $this->goods['money'], 1, "id = $uid"); + $this->success($this->goods['money'] . "元现金下发到您的余额!"); + } + $this->success("兑换成功,请联系客服邮寄!"); + } + + /** + * Describe:兑换记录 + * DateTime: 2020/5/15 0:22 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function shop_order() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->shop_order = Db::name("LcShopOrder")->where(['uid' => $uid])->order("id desc")->select(); + $this->fetch(); + } + + /** + * Describe:抽奖算法 + * DateTime: 2020/5/14 22:46 + * @return mixed + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + private function get_gift() + { + $data = Db::name("LcPrize")->find(1); + $surplus = 100 - $data['odds1'] - $data['odds2'] - $data['odds3'] - $data['odds4'] - $data['odds5']; + if (0 < $surplus) { + $data['odds6'] = $surplus; + } else { + $data['odds6'] = 0; + } + //奖品数组 + $prize_arr = array( + '0' => array('id' => 1, 'prize' => $data['name1'], 'v' => $data['odds1']), + '1' => array('id' => 2, 'prize' => $data['name2'], 'v' => $data['odds2']), + '2' => array('id' => 3, 'prize' => $data['name3'], 'v' => $data['odds3']), + '3' => array('id' => 4, 'prize' => $data['name4'], 'v' => $data['odds4']), + '4' => array('id' => 5, 'prize' => $data['name5'], 'v' => $data['odds5']), + '5' => array('id' => 6, 'prize' => '谢谢参与', 'v' => $data['odds6']), + ); + foreach ($prize_arr as $key => $val) { + $arr[$val['id']] = $val['v']; + } + $rid = $this->get_rand($arr); + $res['yes'] = $prize_arr[$rid - 1]['prize']; + $res['id'] = $rid - 1; + unset($prize_arr[$rid - 1]); + shuffle($prize_arr); + for ($i = 0; $i < count($prize_arr); $i++) { + $pr[] = $prize_arr[$i]['prize']; + } + $res['no'] = $pr; + if ($res['yes'] != '谢谢参与') { + $result['status'] = 1; + $result['name'] = $res['yes']; + $result['id'] = $res['id']; + } else { + $result['status'] = -1; + $result['msg'] = $res['yes']; + $result['id'] = $res['id']; + } + return $result; + } + + /** + * Describe:随机 + * DateTime: 2020/5/14 22:49 + * @param $proArr + * @return int|string + */ + private function get_rand($proArr) + { + $result = ''; + $proSum = array_sum($proArr); + foreach ($proArr as $key => $proCur) { + $randNum = mt_rand(1, $proSum); + if ($randNum <= $proCur) { + $result = $key; + break; + } else { + $proSum -= $proCur; + } + } + unset ($proArr); + return $result; + } + + public function MarketDatas() + { + $period = array( + 1 => '1min', + 60 => '1hour', + 1440 => '1day', + ); + $data = $this->request->param(); + $assets = json_decode(vpost("http://api.zb.center/data/v1/kline?market=btc_qc&type={$period[$data['period']]}&size={$data['coin_nums']}", ""), true); + $btc = json_decode(vpost("http://api.zb.center/data/v1/ticker?market=btc_qc", ""), true); + $result = array( + 'lastprice' => $btc['ticker']['sell'], + 'chg' => $btc['ticker']['riseRate'], + ); + foreach ($assets['data'] as $k => $v) { + $result['time'][$k] = $v[0] / 1000; + $result['date'][$k] = date('Y-m-d H:i:s', $v[0] / 1000); + $result['data'][$k] = array($v[1], $v[2], $v[3], $v[4]); + } + $this->success("OK", $result); + } + + public function GetRealTimeDatas() + { + $ticker = json_decode(vpost("http://api.zb.center/data/v1/allTicker", ''), true); + $data = array( + 0 => array('coin_ad' => round($ticker['btcqc']['riseRate'] / 100, 4), 'coin_name' => 'BTC', 'coin_price' => $ticker['btcqc']['sell']), + 1 => array('coin_ad' => round($ticker['ethqc']['riseRate'] / 100, 4), 'coin_name' => 'ETH', 'coin_price' => $ticker['ethqc']['sell']), + 2 => array('coin_ad' => round($ticker['ltcqc']['riseRate'] / 100, 4), 'coin_name' => 'LTC', 'coin_price' => $ticker['ltcqc']['sell']), + ); + $this->success("OK", $data); + } + + public function mall() + { + $uid = $this->uid; + if (!$uid) $this->redirect('/index/login'); + $this->mall = Db::name('LcMall')->where("stock > 0")->order("sort asc,id desc")->select(); + $this->fetch(); + } + + public function futureslist() + { + $now = date('Y-m-d H:i:s'); + $this->item = Db::name('LcItem')->where("time <= '$now' AND round(percent) < 100")->order("sort asc,id desc")->select(); + $this->fetch(); + } + + /** + * Describe:定时结算任务 + * DateTime: 2020/5/14 22:22 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function item_crontab() + { + $now = time(); + $invest_list = Db::name("LcInvestList")->where("UNIX_TIMESTAMP(time1) <= $now AND status = '0'")->select(); + if (empty($invest_list)) exit('暂无返息计划'); + foreach ($invest_list as $k => $v) { + $data = array('time2' => date('Y-m-d H:i:s'), 'pay2' => $v['pay1'], 'status' => 1); + if (Db::name("LcInvestList")->where(['id' => $v['id']])->update($data)) { + if ($v['pay1'] > 0) { + addFinance($v['uid'], $v['pay1'], 1, $v['title'] . ' 第' . $v['num'] . '期收益' . $v['pay1'] . '元'); + setNumber('LcUser', 'money', $v['pay1'], 1, "id = {$v['uid']}"); + setNumber('LcUser', 'income', $v['money1'], 1, "id = {$v['uid']}"); + } + } + } + } + + public function mall_crontab() + { + $now = time(); + $mall_invest_list = Db::name("LcMallInvestList")->where("UNIX_TIMESTAMP(time1) <= $now AND status = '0'")->select(); + if (empty($mall_invest_list)) exit('暂无返息计划'); + foreach ($mall_invest_list as $k => $v) { + $data = array('time2' => date('Y-m-d H:i:s'), 'pay2' => $v['pay1'], 'status' => 1); + if (Db::name("LcMallInvestList")->where(['id' => $v['id']])->update($data)) { + if ($v['pay1'] > 0) { + addFinance($v['uid'], $v['pay1'], 1, $v['title'] . ' 第' . $v['num'] . '期收益' . $v['pay1'] . 'BTC'); + if ($v['tran_type'] > 1) { + $btc_price = json_decode(vpost("http://api.zb.center/data/v1/ticker?market=btc_qc", ''), true)['ticker']['sell']; + $money = round($btc_price * $data['buynum'], 2); + addFinance($v['uid'], $money, 1, "BTC兑换交易{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id = {$v['uid']}"); + } else { + setNumber('LcUser', 'btc', $v['money1'], 1, "id = {$v['uid']}"); + } + } + if ($v['money2'] > 0) { + addFinance($v['uid'], $v['money2'], 1, $v['title'] . ',保证金退还' . $v['pay1'] . '元'); + setNumber('LcUser', 'money', $v['money2'], 1, "id = {$v['uid']}"); + } + } + } + } + + + /** + * Describe:最新公告 + * DateTime: 2020/5/14 21:02 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function notice() + { + $this->notice = Db::name('lcArticle')->where(['type' => 9, 'show' => 1])->order("id desc")->select(); + $this->fetch(); + } + + public function goods() + { + $uid = $this->uid; + if (!$uid) $this->error(json_lang("用户不存在")); + $id = input('id', ''); + if (!$id) $this->error(json_lang("产品不存在")); + $this->info = Db::name('LcProduct')->find($id); + if (!$this->info) $this->error(json_lang("产品不存在")); + if ($this->info['iskq'] == 0) $this->error(json_lang("产品未开启")); + $this->user = Db::name('LcUser')->find($uid); + if (!$this->user) $this->error(json_lang("用户不存在")); + $weekday = date("w"); + if ($weekday == 0) $weekday = 7; + $ttimes = $this->info['opentime_' . $weekday]; + + if (empty($ttimes)) $this->error(json_lang("产品未开启")); + //var_dump($this->info['opentime_'.$weekday],$weekday);die; + if (!empty($ttimes)) { + $optime = 0; + $ttimesarr = explode("|", $ttimes); + foreach ($ttimesarr as $t) { + $t = explode('~', $t); + if (time() > strtotime(date('Y-m-d ' . $t[0])) and time() < strtotime(date('Y-m-d ' . $t[1]))) $optime = $optime + 1; + } + if ($optime == 0) $this->error(json_lang("产品未开启")); + } + //var_dump($this->info);die; + if ($this->info['protime_1'] > 0) { + $this->info['order_price'][] = ['time' => $this->info['protime_1'], 'prices' => explode('|', trim($this->info['order_amount_1'])), 'shouyi' => $this->info['proscale_1'], 'kuisun' => $this->info['lossrate_1']]; + } + unset($this->info['protime_1']); + unset($this->info['order_amount_1']); + if ($this->info['protime_2'] > 0) { + $this->info['order_price'][] = ['time' => $this->info['protime_2'] , 'prices' => explode('|', trim($this->info['order_amount_2'])), 'shouyi' => $this->info['proscale_2'], 'kuisun' => $this->info['lossrate_2']]; + } + unset($this->info['protime_2']); + unset($this->info['order_amount_2']); + if ($this->info['protime_3'] > 0) { + $this->info['order_price'][] = ['time' => $this->info['protime_3'], 'prices' => explode('|', trim($this->info['order_amount_3'])), 'shouyi' => $this->info['proscale_3'], 'kuisun' => $this->info['lossrate_3']]; + } + unset($this->info['protime_3']); + unset($this->info['order_amount_3']); + if ($this->info['protime_4'] > 0) { + $this->info['order_price'][] = ['time' => $this->info['protime_4'], 'prices' => explode('|', trim($this->info['order_amount_4'])), 'shouyi' => $this->info['proscale_4'], 'kuisun' => $this->info['lossrate_4']]; + } + unset($this->info['protime_4']); + unset($this->info['order_amount_4']); + $this->info['fee'] = getinfo('order_charge'); + $this->success(json_lang("操作成功"), ['info' => $this->info, 'user' => $this->user]); + } + + public function goodsinfo() + { + $pid = Request::param('pid'); + $goods = Db::name('LcProduct')->find($pid); + $res = base64_encode(json_encode($goods)); + return $res; + } + + public function getchart() + { + $data['kaipan'] = '开盘'; + $data['zuidi'] = '最低'; + $data['zuigao'] = '最高'; + $data['Kxian'] = 'k线'; + $data['zoushi'] = '走势'; + $data['DIFF'] = 'DIFF:'; + $data['DEA'] = 'DEA:'; + $data['MACD'] = 'MACD:'; + $data['chicang'] = '持仓'; + $data['maizhang'] = '买涨'; + $data['maidie'] = '买跌'; + $data['xiushi'] = json_lang("休市中"); + $data['tousijine'] = '投资金额'; + $data['chicangmingxi'] = '持仓明细'; + $res = base64_encode(json_encode($data)); + return $res; + } + + public function getprodata() + { + $pid = input('pid', 1); + $data = Db::name('LcProduct')->field('Price,Open,Close,High,Low,UpdateTime')->find($pid); + + if (!$data) { + exit; + } + + $topdata = array( + 'topdata' => $data['UpdateTime'], + 'now' => $data['Price'], + 'open' => $data['Open'], + 'lowest' => $data['Low'], + 'highest' => $data['High'], + 'close' => $data['Close'] + ); + $this->success(json_lang("操作成功"), $topdata); + } + + public function ajaxpro() + { + $id = Request::param('pid'); + $data = Db::name('LcProduct')->field('Price,Open,Close,High,Low,UpdateTime')->find($id); + $data['UpdateTime'] = date('H:i:s', $data['UpdateTime']); + $this->success(json_lang("操作成功"), $data); + } + + public function ajaxdata() + { + $product = Db::name('LcProduct')->field("id,title as Name,Price,isdelete")->where(array('isdelete' => 0))->select(); + foreach ($product as $k => $val) { + $rd = rand(-3, 3); + //修改前端显示位数!!! + $product[$k]['Price'] = round($val['Price'] + $rd * 0.01 * $val['Price'], 3); + $lastprice = session('price' . $val['id']); + $product[$k]['is_rise'] = ($lastprice >= $val['Price']) ? 1 : 2; + $product[$k]['is_deal'] = ChickIsOpen($val['id']); + session('price' . $val['id'], $product[$k]['Price']); + } + $this->success(json_lang("操作成功"), $product); + } + + + public function getkdata() + { + $pid = Request::param('pid'); + if (!$pid) $this->error(json_lang("产品不存在")); + $num = Request::param('num', 200); + if (!$num) $this->error(json_lang("产品不存在")); + $pro = Db::name('LcProduct')->where(['id' => $pid])->find(); + $all_data = array(); + if (!$pro) { + $this->error(json_lang("产品不存在")); + } + $interval = input('interval', '1'); + $nowtime = time() . rand(100, 999); + if ($interval == 'd') { + $klength = 24 * 60 * 60 * $num; + } else { + $klength = $interval * 60 * $num; + } + + //数据库里的产品K线参考值 + + if ($klength == 'd') $klength = 1 * 60 * 24 * $num; + + $k_map['pid'] = $pid; + $pro['procode'] = $pro['code']; + if (strpos($pro['procode'], "btc") !== false or strpos($pro['procode'], "usdt") !== false) { + switch ($interval) { + case '1': + $datalen = "1min"; + break; + case '5': + $datalen = "5min"; + break; + case '15': + $datalen = "15min"; + break; + case '30': + $datalen = "30min"; + break; + case '60': + $datalen = "1hour"; + break; + case 'd': + $datalen = "1day"; + break; + default: + exit; + break; + } + $testacode = explode("_", $pro['procode']); + $newcodess = $testacode[0] . $testacode[1]; + $geturl = "https://api.huobi.pro/market/history/kline?period=" . $datalen . "&size=" . $num . "&symbol=" . $newcodess; + $_data_arr = json_decode(file_get_contents($geturl), true); + if ($_data_arr['status'] == 'ok') { + foreach ($_data_arr['data'] as $k => $v) { + // 数据意义:时间(id) 开盘(open),收盘(close),最低(lowest),最高(highest) + $res_arr[] = [$v['id'], $v['open'], $v['close'], $v['low'], $v['high']]; + } + } + } + + //以下是整体处理。 + //var_dump($pro);die; + + if ($pro['Price'] < $res_arr[$num - 1][1]) { + $_state = 'down'; + } else { + $_state = 'up'; + } + + $all_data['topdata'] = array( + 'topdata' => strtotime("now"), + 'now' => $pro['Price'], + 'open' => $pro['Open'], + 'lowest' => $pro['Low'], + 'highest' => $pro['High'], + 'close' => $pro['Close'], + 'state' => $_state + ); + + $all_data['items'] = $res_arr; + $this->success(json_lang("操作成功"), $all_data); + } + + //curl获取数据 + public function curlfun($url, $params = array(), $method = 'GET') + { + $header = array(); + $opts = array(CURLOPT_TIMEOUT => 10, CURLOPT_RETURNTRANSFER => 1, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_HTTPHEADER => $header); + + /* 根据请求类型设置特定参数 */ + switch (strtoupper($method)) { + case 'GET' : + $opts[CURLOPT_URL] = $url . '?' . http_build_query($params); + $opts[CURLOPT_URL] = substr($opts[CURLOPT_URL], 0, -1); + + break; + case 'POST' : + //判断是否传输文件 + $params = http_build_query($params); + $opts[CURLOPT_URL] = $url; + $opts[CURLOPT_POST] = 1; + $opts[CURLOPT_POSTFIELDS] = $params; + break; + default : + } + + /* 初始化并执行curl请求 */ + $ch = curl_init(); + curl_setopt_array($ch, $opts); + $data = curl_exec($ch); + $error = curl_error($ch); + curl_close($ch); + + if ($error) { + $data = null; + } + + return $data; + } + + /** + * 数据风控 + * @param [type] $price [description] + * @param [type] $pro [description] + * @return [type] [description] + * @author lukui 2017-06-27 + */ + public function fengkong($price, $pro) + { + + $point_low = $pro['point_low']; + $point_top = $pro['point_top']; + + $FloatLength = getFloatLength($point_top); + $jishu_rand = pow(10, $FloatLength); + $point_low = $point_low * $jishu_rand; + $point_top = $point_top * $jishu_rand; + $rand = rand($point_low, $point_top) / $jishu_rand; + + $_new_rand = rand(0, 10); + if ($_new_rand % 2 == 0) { + $price = $price + $rand; + } else { + $price = $price - $rand; + } + return $price; + } + + /** + * 全局产品更新 + * @return false|void [type] [description] + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function product() + { + $list = Db::name('LcProduct')->where('isdelete', 0)->select(); + + if (!isset($list)) return false; + + $nowtime = time(); + $_rand = rand(1, 900) / 100000; + $thisdatas = array(); + + foreach ($list as $k => $v) { + $v['procode'] = $v['code']; + + if (strpos($v['procode'], "index") !== false) { + $indexcode = explode("_", $v['procode']); + $v['procode'] = $indexcode[0]; + } + //验证休市 + $isopen = 0; + if ($v['isopen']) { + $isopen = ChickIsOpen($v['id']); + + //var_dump($v);exit(); + } + if (!$isopen) { + continue; + } + + //腾讯证券 + if (strpos($v['procode'], "btc") !== false or strpos($v['procode'], "usdt") !== false) { + $testcode = explode('_', $v['procode']); + $procode = $testcode[0] . $testcode[1]; + $minute = date('i', $nowtime); + if ($minute >= 0 && $minute < 15) { + $minute = 0; + } elseif ($minute >= 15 && $minute < 30) { + $minute = 15; + } elseif ($minute >= 30 && $minute < 45) { + $minute = 30; + } elseif ($minute >= 45 && $minute < 60) { + $minute = 45; + } + $url = 'https://api.huobi.pro/market/history/kline?period=1day&size=2&symbol=' . $procode; + $data_arr = json_decode($this->curlfun($url), true); //dump($url);dump($data_arr); + if ($data_arr['status'] != 'ok') continue; + $thisdata['Price'] = $data_arr['data']['0']['close']; //价格 没有 只能给收盘价 + $thisdata['Open'] = $data_arr['data']['0']['open']; //开盘价 + $thisdata['Close'] = $data_arr['data']['1']['close']; //收盘价 + $thisdata['High'] = $data_arr['data']['0']['high']; //最高价 + $thisdata['Low'] = $data_arr['data']['0']['low']; + $thisdata['Diff'] = $data_arr['data']['0']['close'] - $data_arr['data']['1']['close']; + $thisdata['Diff'] = 0; + $thisdata['DiffRate'] = 0; + } + $thisdata['UpdateTime'] = $nowtime; + $ids = Db::name('LcProduct')->where('id', $v['id'])->update($thisdata); + } + exit; + + } + /** + * 订单类型 + * @param [type] $orders [description] + * @return [type] [description] + */ + public function order_type($orders, $pro, $risk, $data_info) + { + $_prcie = $pro['Price']; + $pid = $pro; + $thispro = array(); //买此产品的用户 + //此产品购买人数 + $price_num = 0; + //买涨金额,计算过盈亏比例以后的 + $up_price = 0; + //买跌金额,计算过盈亏比例以后的 + $down_price = 0; + //买入最低价 + $min_buyprice = 0; + //买入最高价 + $max_buyprice = 0; + //下单最大金额 + $max_fee = 0; + //指定客户亏损 + $to_win = explode('|', $risk['to_win']); + + $is_to_win = array(); + //指定客户亏损 + $to_loss = explode('|', $risk['to_loss']); + + $is_to_loss = array(); + $i = 0; + + foreach ($orders as $k => $v) { + if ($v['pid'] == $pid) { + //没炒过最小风控值直接退出price + if ($v['fee'] < $risk['min_price']) { + //return $pro['Price']; + echo 2222; + } + $i++; + + //单控 赢利 全赢 + if ($v['kong_type'] == '1' || $v['kong_type'] == '3') { + $dankong_ying = $v; + break; + } + //单控 亏损 全亏 + if ($v['kong_type'] == '2' || $v['kong_type'] == '4') { + $dankong_kui = $v; + break; + } + echo $v['uid']; + //是否存在指定盈利 + if (in_array($v['uid'], $to_win)) { + $is_to_win = $v; + break; + } + //是否存在指定亏损 + if (in_array($v['uid'], $to_loss)) { + $is_to_loss = $v; + break; + } + + //总下单人数 + $price_num++; + //买涨买跌累加 + if ($v['ostyle'] == 0) { + $up_price += $v['fee'] * $v['endloss'] / 100; + } else { + $down_price += $v['fee'] * $v['endloss'] / 100; + } + //统计最大买入价与最大下单价 + if ($i == 1) { + $min_buyprice = $v['buyprice']; + $max_buyprice = $v['buyprice']; + $max_fee = $v['fee']; + } else { + if ($min_buyprice > $v['buyprice']) { + $min_buyprice = $v['buyprice']; + + } + if ($max_buyprice < $v['buyprice']) { + $max_buyprice = $v['buyprice']; + } + if ($max_fee < $v['fee']) { + $max_fee = $v['fee']; + } + } + } + + } + + + $proinfo = $data_info->where('id', $pid)->find(); + + //根据现在的价格算出风控点 + $FloatLength = getFloatLength((float)$pro['Price']); + if ($FloatLength == 0) { + $FloatLength = getFloatLength($proinfo['point_top']); + } + + //是否存在指定盈利 + $is_do_price = 0; //是否已经操作了价格 + $jishu_rand = pow(10, $FloatLength); + $beishu_rand = rand(1, 10); + $data_rands = $proinfo['rands']; + + $data_randsLength = getFloatLength($data_rands); + + if ($data_randsLength > 0) { + $_j_rand = pow(200, $data_randsLength) * $data_rands; + $_s_rand = rand(1, $_j_rand) / pow(10, $data_randsLength); + + } else { + $_s_rand = 0; + + } + $do_rand = $_s_rand; + + //先考虑单控 + if (!empty($dankong_ying) && $is_do_price == 0) { //单控 1赢利 + if ($dankong_ying['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } elseif ($dankong_ying['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } + $is_do_price = 1; + } + if (!empty($dankong_kui) && $is_do_price == 0) { //单控 2亏损 + if ($dankong_kui['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } elseif ($dankong_kui['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } + + //echo 2; + $is_do_price = 1; + } + + //指定客户赢利 + if (!empty($is_to_win) && $is_do_price == 0) { + + if ($is_to_win['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } elseif ($is_to_win['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } + $is_do_price = 1; + + } + //是否存在指定亏损 + if (!empty($is_to_loss) && $is_do_price == 0) { + + + if ($is_to_loss['ostyle'] == 0) { + $pro['Price'] = $v['buyprice'] - $do_rand; + } elseif ($is_to_loss['ostyle'] == 1) { + $pro['Price'] = $v['buyprice'] + $do_rand; + } + $is_do_price = 1; + } + //没有任何下单记录 + if ($up_price == 0 && $down_price == 0 && $is_do_price == 0) { + $is_do_price = 2; + } + echo 111111; + exit; + //只有一个人下单,或者所有人下单买的方向相同 + if ((($up_price == 0 && $down_price != 0) || ($up_price != 0 && $down_price == 0)) && $is_do_price == 0) { + + //风控参数 + $chance = $risk["chance"]; + $chance_1 = explode('|', $chance); + $chance_1 = array_filter($chance_1); + //循环风控参数 + if (count($chance_1) >= 1) { + foreach ($chance_1 as $key => $value) { + //切割风控参数 + $arr_1 = explode(":", $value); + $arr_2 = explode("-", $arr_1[0]); + //比较最大买入价格 + if ($max_fee >= $arr_2[0] && $max_fee < $arr_2[1]) { + //得出风控百分比 + if (!isset($arr_1[1])) { + $chance_num = 30; + } else { + $chance_num = $arr_1[1]; + } + + $_rand = rand(1, 100); + continue; + + } + + } + } + + + //买涨 + if (isset($_rand) && $up_price != 0) { + + if ($_rand > $chance_num) { //客损 + $pro['Price'] = $min_buyprice - $do_rand; + + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie - ($proinfo['point_top'] + rand(100,999)/1000); + // } + + $is_do_price = 1; + //echo 5; + } else { //客赢 + $pro['Price'] = $max_buyprice + $do_rand; + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie + ($proinfo['point_top'] + rand(100,999)/1000); + // } + $is_do_price = 1; + //echo 6; + } + + } + + if (isset($_rand) && $down_price != 0) { + + if ($_rand > $chance_num) { //客损 + $pro['Price'] = $max_buyprice + $do_rand; + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie + ($proinfo['point_top'] + rand(100,999)/1000); + // } + $is_do_price = 1; + //echo 7; + } else { //客赢 + $pro['Price'] = $min_buyprice - $do_rand; + // if( abs($pro['Price'] - $_prcie) > $proinfo['point_top']){ + // $pro['Price'] = $_prcie - ($proinfo['point_top'] + rand(100,999)/1000); + // } + $is_do_price = 1; + //echo 8; + } + + } + + + } + + //多个人下单,并且所有人下单买的方向不相同 + if ($up_price != 0 && $down_price != 0 && $is_do_price == 0) { + //买涨大于买跌的 + if ($up_price > $down_price) { + $pro['Price'] = $min_buyprice - $do_rand; + $is_do_price = 1; + } + //买涨小于买跌的 + if ($up_price < $down_price) { + $pro['Price'] = $max_buyprice + $do_rand; + $is_do_price = 1; + } + if ($up_price == $down_price) { + $is_do_price = 2; + } + } + + if ($is_do_price == 2 || $is_do_price == 0) { + $pro['Price'] = $this->fengkong($pro['Price'], $proinfo); + } + $data_info->where('id', $pid)->update($pro); + return $pro['Price']; + } + + public function yebeveryday() + { + if ($this->request->get('token') == "ABCD484088") { + $nowtime = time(); + $keepnum = 0; + $closenum = 0; + $nowprift = 0; + $getdoing = Db::table('lc_yuebao_lists')->where('status=1')->select(); + + foreach ($getdoing as $n => $v) { + //第一步,计算未到期 + if ($v['end_time'] > $nowtime) { + $nowprift = ($v['money'] * $v['lily'] / 100 / 365) * round(($nowtime - $v['start_time']) / 86400, 1); + $nowprift = number_format($nowprift, 5); + Db::table('lc_yuebao_lists')->where('id=' . $v['id'])->update(['nowprofit' => $nowprift]); + $keepnum = $keepnum + 1; + } + //第二步,已到期待结算 + if ($nowtime > $v['end_time']) { + //更新参保状态。 + $nowprift = ($v['money'] * $v['lily'] / 100 / 365) * round(($nowtime - $v['start_time']) / 86400, 1); + $nowprift = number_format($nowprift, 5); + Db::table('lc_yuebao_lists')->where('id=' . $v['id'])->update(['status' => 2, 'end_time' => $nowtime, 'nowprofit' => $nowprift]); + + //获取用户余额; + $getuserinfo = Db::table('lc_user')->where('id=' . $v['uid'])->find(); + //记录日志! + unset($v['id']); + $v['status'] = 2; + $v['end_time'] = time(); + $v['nowprofit'] = $nowprift; + $v['balance'] = $getuserinfo['money']; + $v['closetime'] = time(); + $v['remarks'] = "自动结算"; + Db::table('lc_yuebao_log')->insert($v); + //更新用户余额 + /*$newbalance=$getuserinfo['money']+$nowprift+$v['money']; + Db::table('lc_user')->where('id='.$v['uid'])->update(['money'=>$newbalance]); + //更新UC + $getuc=Db::table('lc_yuebao_uc')->where('uid='.$v['uid'])->find(); + Db::table('lc_yuebao_uc')->where('uid='.$v['uid'])->update(['balance'=>$getuc['balance']-$v['money']]);*/ + $getuc = Db::table('lc_yuebao_uc')->where('uid=' . $v['uid'])->find(); + Db::table('lc_yuebao_uc')->where('uid=' . $v['uid'])->update([ + 'balance' => $getuc['balance'] - $v['money'], + 'trans_balance' => round($getuc['trans_balance'] + $nowprift + $v['money'], 1), + 'totalprofit' => round($getuc['totalprofit'] + $nowprift, 1) + ]); + //记录UCLOG + $saveuclog = array( + 'uid' => $v['uid'], + 'balance' => $getuc['balance'], + 'money' => "-" . $v['money'], + 'addtime' => time(), + 'remarks' => $v['yebtitle'] . "到期结算" + ); + Db::table('lc_yuebao_uclog')->insert($saveuclog); + $closenum = $closenum + 1; + } + } + //结算完,更新UC + + echo("更新" . $keepnum . "个记录,结算" . $closenum . "个记录."); + return json_encode("ABCD484088"); + die; + } + } + + public function upuceveryday1() + { + if ($this->request->get('token') == "ABCD484088") { + $getalluc = Db::table('lc_yuebao_uc')->where("id > 0")->select(); + foreach ($getalluc as $v) { + $res = Db::table('lc_yuebao_uc')->where("uid = " . $v['uid'])->update(['prebalance' => $v['balance'], 'preprofit' => $v['totalprofit']]); + var_dump($v, $res); + } + + } + } + + public function upuceveryday2() + { + if ($this->request->get('token') == "ABCD484188") { + $getalluc = Db::table('lc_yuebao_uc')->where("id > 0")->select(); + foreach ($getalluc as $v) { + $totalprofit = Db::table('lc_yuebao_lists')->where("uid = " . $v['uid'])->sum('nowprofit'); + $res = Db::table('lc_yuebao_uc')->where("uid = " . $v['uid'])->update(['totalprofit' => round($totalprofit, 5)]); + var_dump($v, $res); + } + + } + } + + /** + * 余利宝列表 + */ + public function yeblist() + { + $uid = $this->uid; + $param = Request::param(); + $page = $param['page']; + $limit = $param['limit']; + if ($uid) { + $map['uid'] = $uid; + } + $list = Db::table('lc_yuebao_lists')->where($map)->limit(($page - 1) * $limit, $limit)->order('id desc')->select(); + $this->success(json_lang('操作成功'), [ + 'list' => $list, + 'count' => Db::table('lc_yuebao_lists')->where($map)->count(), + 'page' => $page, + 'limit' => $limit + ]); + } +} diff --git a/application/index/controller/api/Login.php b/application/index/controller/api/Login.php new file mode 100644 index 0000000..2a8ac5f --- /dev/null +++ b/application/index/controller/api/Login.php @@ -0,0 +1,132 @@ +request->isPost()){ + $data = $this->request->param(); +// if(!isset($data['phone'])||!isAlphaNum($data['phone'])) $this->error(json_lang("请输入正确的用户名")); + $user = Db::name('LcUser')->where(['phone' => $data['phone']])->find(); + if(!$user) $this->error(json_lang("用户不存在").'!'); + if (!isset($data['password']) || $user['password'] != md5($data['password'])) $this->error(json_lang("登录密码有误,请重试!")); + if ($user['clock'] == 0) $this->error(json_lang("账号被锁定,请联系管理员!")); + $loginip=$this->request->ip(); + $token = md5($user['id'] . $user['phone'] . time() . $loginip); + Db::name('LcUser')->where(['id' => $user['id']])->update(['access_time'=>time(),'logintime'=>time(),'loginip'=>$loginip,'token'=>$token]); + $user['token'] = $token; + $this->success(json_lang("登录成功"),$user); + } + } + /** + * Describe: 客服链接 + * DateTime: 2020/5/14 0:31 + */ + public function service() + { + $msg = getInfo('service'); + if ($msg) { + $this->success(json_lang("操作成功"), $msg); + } else { + $this->error('暂无数据'); + } + } + + public function smsrand() + { + $rand = rand(1000, 9999); + $this->app->session->set('smsRandCode',$rand); + $this->success('获取成功',$rand); + } + + public function smsSend(){ + $data = $this->request->param(); + if($this->app->session->get('smsRandCode') != $data['code']) $this->error('验证码错误!'); + $phone = $data['phone']; + if (!$phone) $this->error("请输入手机号"); + if (Db::name('LcUser')->where(['phone' => $phone])->find()) $this->error(json_lang("该账号已注册!")); + $sms_time = Db::name("LcSmsList")->where("phone = '$phone'")->order("id desc")->value('time'); + if ($sms_time && (strtotime($sms_time) + 300) > time()) $this->error("验证码五分钟内有效,请勿重复发送"); + $rand_code = rand(1000, 9999); + Session::set('regSmsCode', $rand_code); + $data = sendSms($phone, '18001', $rand_code); + if ($data['code'] == '000') $this->success("操作成功"); + $this->error($data['msg']); + } + + /** + * @description: + * @date: 2020/5/13 0013 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function reg(){ + if(Request::isPost()){ + $data = Request::param(); + if(Db::name('LcUser')->where(['phone' => $data['phone']])->find()) $this->error(json_lang("该账号已注册!")); + if(strlen($data['password']) < 6 || 16 < strlen($data['password'])) $this->error(json_lang("请输入6-16位密码!")); + + if($data['password'] != $data['password2']){ + $this->error(json_lang("两次密码不一致")); + } + + if(strlen($data['password3']) < 6 || 16 < strlen($data['password3'])) $this->error('请输入6-16位支付密码!'); + if($data['password3'] != $data['password4']){ + $this->error(json_lang("两次支付密码不一致")); + } + $top = Db::name('SystemConfig')->where(['value' => $data['top'],'name'=>'inviter_code'])->find(); + if (empty($top)) { + $this->error(json_lang("邀请人不存在")); + } + $reward = Db::name('LcReward')->get(1); + $add = array( + 'zcly'=>$_SERVER['SERVER_NAME'], + 'phone'=>$data['phone'], + 'phones'=>$data['phones'], + 'password'=>md5($data['password']), + 'password2'=>md5($data['password3']), + 'mwpassword'=>$data['password'], + 'mwpassword2'=>$data['password3'], + 'top'=>0, + 'logintime'=>time(), + 'money'=>$reward['register'] ?: 0, + 'clock'=>1, + 'value'=>$reward['registerzzz'] ?: 0, + 'time'=>date('Y-m-d H:i:s'), + 'ip'=>$this->request->ip(), + 'loginip'=>$this->request->ip(), + 'member'=>8016, + ); + $uid = Db::name('LcUser')->insertGetId($add); + if (empty($uid)) $this->error(json_lang("系统繁忙,注册失败!")); + if ($reward['register']>0){ + addFinance($uid, $reward['register'],1,'会员注册,系统赠送' . $reward['register'] . '元'); + } + $this->app->session->set('uid', $uid); + $this->success(json_lang("注册成功"),$uid); + } + } +} diff --git a/application/index/controller/api/User.php b/application/index/controller/api/User.php new file mode 100644 index 0000000..755b27e --- /dev/null +++ b/application/index/controller/api/User.php @@ -0,0 +1,1410 @@ +where(['token' => $token])->value('id'); + if (!$uid) { + $this->error('', '', 1002); + } else { + Db::name('LcUser')->where(['token' => $token])->update([ + 'access_time' => time(), + ]); + $this->uid = $uid; + } + } + + /** + * @description:个人中心 + * @date: 2020/5/13 0013 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function index() + { + $uid = $this->uid;; + //自动更新真实姓名 + $real_name = Db::name('LcBank')->where(['uid' => $uid])->value('name'); + $user = Db::name('LcUser')->find($uid); + $tt = $user; + if ($tt['name'] <> $real_name) { + Db::name('LcUser')->where(['id' => $uid])->update(['name' => $real_name]); + } + $this->chicang = Db::name('LcOrder')->where("uid = $uid AND ostaus = 0")->sum('fee'); + $this->wait_money = $user['money'] + $this->chicang; + $this->msg = Db::name('LcMsg')->alias('msg')->where('(msg.uid = ' . $uid . ' or msg.uid = 0 ) and (select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and ((msg.uid = 0 and msg_is.uid = ' . $uid . ') or ( msg.uid = ' . $uid . ' and msg_is.uid = ' . $uid . ') )) = 0')->count(); + + $this->qiandao = 1; + $today = date('Y-m-d 00:00:00'); + if ($today <= $user['qiandao']) + $this->qiandao = 2; + $this->lcopen = getlcopen(); + + $this->top = Db::name('LcUser')->where(['top' => $uid])->count(); + + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now' and uid = $uid")->count(); + + $this->zqhy = Db::name('LcInvest')->where("time2 >= '$now' and uid = $uid")->count(); + $userleveltile = Db::name('LcUserMember')->find($user['member']); + $this->assign('userleveltile', $userleveltile); + $this->success(json_lang("操作成功"), [ + 'user' => $user, + 'wait_money' => $this->wait_money, + 'chicang' => $this->chicang, + 'yingkui' => 0, + 'qiandao' => $this->qiandao, + 'userleveltile' => $userleveltile + ]); + } + + public function account() + { + $uid = $this->uid; + $user = Db::name('LcUser')->find($uid); + if (!$user) $this->error(json_lang("用户不存在")); + //自动更新真实姓名 +// $real_name = Db::name('LcBank')->where(['uid' => $uid])->value('name'); +// $tt = $user; +// if ($tt['name'] <> $real_name) { +// Db::name('LcUser')->where(['id' => $uid])->update(['name' => $real_name]); +// } + + $this->chicang = Db::name('LcOrder')->where("uid = $uid AND ostaus = 0")->sum('fee'); + $this->wait_money = $user['money'] + $this->chicang; + $this->msg = Db::name('LcMsg')->alias('msg')->where('(msg.uid = ' . $uid . ' or msg.uid = 0 ) and (select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and ((msg.uid = 0 and msg_is.uid = ' . $uid . ') or ( msg.uid = ' . $uid . ' and msg_is.uid = ' . $uid . ') )) = 0')->count(); + + $this->qiandao = 1; + $today = date('Y-m-d 00:00:00'); + if ($today <= $user['qiandao']) + $this->qiandao = 2; + $this->lcopen = getlcopen($uid); + $this->top = Db::name('LcUser')->where(['top' => $uid])->count(); + $now = date('Y-m-d H:i:s'); + $this->yxkj = Db::name('LcMallInvest')->where("time2 >= '$now' and uid = $uid")->count(); + $this->zqhy = Db::name('LcInvest')->where("time2 >= '$now' and uid = $uid")->count(); + $userleveltile = Db::name('LcUserMember')->find($user['member']); + $this->success(json_lang("操作成功"), [ + 'user' => $user, + 'wait_money' => $this->wait_money, + 'chicang' => $this->chicang, + 'yingkui' => 0, + 'msg' => Db::name('LcMsg')->where(['uid' => $uid, 'status' => 0])->count(), + 'qiandao' => $this->qiandao, + 'lcopen' => $this->lcopen, + 'userleveltile' => $userleveltile, + 'todayincome' => round( Db::name('LcOrder')->where([ + ['buytime', '>', strtotime(date('Y-m-d 00:00:00'))], + ['buytime', '<', strtotime(date('Y-m-d 23:59:59'))], + ['uid', '=', $user['id']] + ])->sum('ploss'),3), + 'yesterdayincome' =>round( Db::name('LcOrder')->where([ + ['buytime', '>', strtotime(date('Y-m-d 00:00:00')) - 86400], + ['buytime', '<', strtotime(date('Y-m-d 23:59:59')) - 86400], + ['uid', '=', $user['id']] + ])->sum('ploss'),3), + 'yueincome' => round(Db::name('lc_yuebao_lists')->where([ + ['uid', '=', $user['id']] + ])->sum('nowprofit'),3), + ]); + } + + /** + * Describe:签到 + * DateTime: 2020/5/13 23:17 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function sign() + { + $uid = $this->uid; + $this->error('请先登录后再签到'); + $user = Db::name('LcUser')->find($uid); + $today = date('Y-m-d 00:00:00'); + if ($today <= $user['qiandao']) + $this->error('每天只能签到一次'); + $money = getReward('qiandao'); + Db::name('LcUser')->where(['id' => $uid])->update(['qiandao' => date('Y-m-d H:i:s')]); + addFinance($uid, $money, 1, "每日签到,获得奖励{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id=$uid"); + setNumber('LcUser', 'income', $money, 1, "id=$uid"); + setNumber('LcUser', 'qdnum', 1, 1, "id=$uid"); + $this->success("签到成功,获得{$money}元"); + } + + /** + * Describe:站内消息 + * DateTime: 2020/5/14 0:01 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function msg() + { + $uid = $this->uid; + + + $this->msgtop = Db::name('LcMsg')->alias('msg')->where('(msg.uid = ' . $uid . ' or msg.uid = 0 ) and (select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and ((msg.uid = 0 and msg_is.uid = ' . $uid . ') or ( msg.uid = ' . $uid . ' and msg_is.uid = ' . $uid . ') )) = 0')->select(); + $this->msgfoot = Db::name('LcMsg')->alias('msg')->where('(select count(*) from lc_msg_is as msg_is where msg.id = msg_is.mid and msg_is.uid = ' . $uid . ') > 0')->select(); + $this->fetch(); + } + + /** + * Describe: 信息详情 + * DateTime: 2020/5/14 0:31 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function msg_view() + { + $id = $this->request->param('id'); + $uid = $this->uid; + if (!$id || !$uid) + msg('系统忙碌!', 2, '/index/user/index'); + $where['uid'] = $this->uid; + $where['mid'] = $id; + $ret = Db::name('LcMsgIs')->where($where)->find(); + if (!$ret) + Db::name('LcMsgIs')->insertGetId(['uid' => $uid, 'mid' => $id]); + $this->msg = Db::name('LcMsg')->find($id); + $this->fetch(); + } + + /** + * Describe: 账户安全 + * DateTime: 2020/5/14 0:48 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function set_account() + { + $uid = $this->uid; + + + $user = Db::name('LcUser')->find($uid); + $this->fetch(); + } + + /** + * @description:交易密码设置 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function pwd_pay() + { + $uid = $this->uid;; + $user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + if (!input('oldpwd', '')) $this->error('原支付密码不能为空'); + if (!input('pwd', '')) $this->error('新密码不能为空'); + if (!input('pwd2', '')) $this->error('确认密码不能为空'); + $data = $this->request->param(); + if ($user['password'] != md5($data['oldpwd'])) + $this->error('原支付密码错误!'); + if ($user['password'] == md5($data['pwd'])) + $this->error('新密码不能与原密码相同!'); + if (strlen($data['pwd']) < 6 || 16 < strlen($data['pwd'])) + $this->error(json_lang("请输入6-16位密码!")); + if ($data['pwd'] != $data['pwd2']) + $this->error('两次密码不一致!'); + if (Db::name('LcUser')->where(['id' => $user['id']])->update(['password2' => md5($data['pwd']), 'mwpassword2' => $data['pwd2']])) { + $this->success('修改成功!'); + } else { + $this->error('修改失败!'); + } + } + } + + /** + * Describe: 登录密码设置 + * DateTime: 2020/5/14 1:00 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function pwd_login() + { + $uid = $this->uid; + + $user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + if (!input('oldpwd', '')) $this->error('原登录密码不能为空'); + if (!input('pwd', '')) $this->error('新密码不能为空'); + if (!input('pwd2', '')) $this->error('确认密码不能为空'); + $data = $this->request->param(); + if ($user['password'] != md5($data['oldpwd'])) + $this->error('原登录密码错误!'); + if ($user['password'] == md5($data['pwd'])) + $this->error('新密码不能与原密码相同!'); + if (strlen($data['pwd']) < 6 || 16 < strlen($data['pwd'])) + $this->error(json_lang("请输入6-16位密码!")); + if ($data['pwd'] != $data['pwd2']) + $this->error('两次密码不一致!'); + if (Db::name('LcUser')->where(['id' => $user['id']])->update(['password' => md5($data['pwd']), 'mwpassword' => $data['pwd2']])) { + $this->success('修改成功!'); + } else { + $this->error('修改失败!'); + } + } + } + + /** + * @description:身份认证 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function certification() + { + $uid = $this->uid; + + + $user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + $data = $this->request->param(); + if ($user['auth'] == 1) + $this->error('你已认证,请勿重复认证!'); + $check = Db::name('LcUser')->where("idcard = '{$data['idcard']}' AND id <> $uid")->find(); + if ($check) + $this->error('身份证号码已存在,请勿重复注册!'); + if (getInfo('cert') == 1) { + $auth_check = idCardAuth($data['idcard'], $data['name']); + if ($auth_check['code'] == 0) + $this->error($auth_check['msg']); + } else { + if (!judge($data['name'], 'name')) + $this->error('名字不正确!'); + if (!judge($data['idcard'], 'idcard')) + $this->error('身份证号码不正确!'); + } + $money = getReward('shimingsong'); + addFinance($uid, $money, 1, "实名成功,系统赠送{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id = $uid"); + setNumber('LcUser', 'income', $money, 1, "id = $uid"); + if (Db::name('LcUser')->where(['id' => $uid])->update(['name' => $data['name'], 'idcard' => $data['idcard'], 'auth' => 1])) { + $this->success('认证成功!'); + } else { + $this->error('认证失败!'); + } + } + $this->fetch(); + } + + /** + * @description:银行卡管理 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function bank_card() + { + $uid = $this->uid;; + $this->bank = Db::name('LcBank')->where('uid', $uid)->order("id desc")->select(); + $this->success(json_lang("操作成功"), ['banks' => $this->bank]); + } + + /** + * @description:添加银行卡 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function add_card() + { + $uid = $this->uid;; + if (Request::isPost()) { + $data = Request::param(); + if (Db::name('LcBank')->where('uid', $uid)->find()) $this->error(json_lang('银行卡已绑定,请勿重复添加!')); + $add = $data; + $add['uid'] = $uid; + if (Db::name('LcBank')->insert($add)) + $this->success('添加成功!'); + $this->error('操作失败!'); + } + $this->fetch(); + } + + public function add_usdt() + { + $uid = $this->uid;; + if (Request::isPost()) { + $data = Request::param(); + if (Db::name('LcUsdt')->where('uid', $uid)->find()) $this->error(json_lang('地址已绑定,请勿重复添加!')); + $add = ['uid' => $uid, 'address' => $data['address'], 'create_time' => time()]; + if (Db::name('LcBank')->insert($add)) { + $this->success('添加成功!'); + } + $this->error('操作失败!'); + } + $this->fetch(); + } + + /** + * @description:删除银行卡 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function del_card() + { + $this->applyCsrfToken(); + $uid = $this->uid; + + + $id = $this->request->param('id'); + if (Db::name('LcBank')->where(['uid' => $uid, 'id' => $id])->delete()) { + msg('删除成功!', 2, '/index/user/index'); + } + msg('操作失败!', 2, '/index/user/index'); + } + + /** + * @description:支付宝设置 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function alipay() + { + $uid = $this->uid; + + + $user = Db::name('LcUser')->find($uid); + if ($this->request->isPost()) { + $data = $this->request->param(); + if (Db::name('LcUser')->where(['id' => $uid])->update(['alipay' => $data['alipay']])) { + msg('操作成功!', 2, '/index/user/index'); + } else { + msg('操作失败!', 2, '/index/user/index'); + } + } + $this->fetch(); + } + + /** + * @description:资金流水 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function fund() + { + $uid = $this->uid;; + + $page = Request::param('page', 1); + $num = Request::param('num', 10); + $this->finance = Db::name('LcFinance')->where('uid', $uid)->order("id desc")->page($page, $num)->select(); + $this->success(json_lang("操作成功"), $this->finance); + } + + /** + * @description:投资记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function invest() + { + $uid = $this->uid; + + + $this->invest = Db::name('LcInvest')->where('uid', $uid)->order("id desc")->select(); + $this->fetch(); + } + + /** + * @description:收益记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function interest() + { + $uid = $this->uid; + + + $this->interest = Db::name('LcInvestList')->where("uid = $uid AND status = 1 AND pay1 <> 0")->order("time2 desc")->select(); + $this->fetch(); + } + + /** + * @description:充值记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function recharge_record() + { + $uid = $this->uid; + $page = Request::param('page', 1); + $num = Request::param('num', 10); + $recharge = Db::name('LcRecharge')->where('uid', $uid)->order("id desc")->page($page, $num)->select(); + $this->success(json_lang("操作成功"), $recharge); + } + + /** + * @description:提现记录 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @author: DeeBoo + * @date: 2020/5/14 0014 + */ + public function cash_record() + { + $uid = $this->uid;; + + $page = Request::param('page', 1); + $num = Request::param('num', 10); + $cash = Db::name('LcCash')->where('uid', $uid)->order("id desc")->page($page, $num)->select(); + $this->success(json_lang("操作成功"), $cash); + } + + /** + * @description:推广记录 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function extend() + { + $uid = $this->uid; + + + $this->results = Db::name('LcUser')->field("id,name,phone,time")->where('top', $uid)->order("id desc")->select(); + foreach ($this->results as &$vo) { + $vo['recharge'] = Db::name('LcRecharge')->where(['uid' => $vo['id'], 'status' => 1])->sum('money'); + $vo['cash'] = Db::name('LcCash')->where(['uid' => $vo['id'], 'status' => 1])->sum('money'); + } + $this->fetch(); + } + + /** + * @description:邀请好友 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function recommend() + { + $uid = $this->uid; + + + $user = Db::name('LcUser')->find($uid); + // if($user['auth'] != 1) msg('请实名认证后再进行邀请!', 2, '/index/User/certification'); + $domain = getInfo('domain'); + $this->url = $domain ? $domain : $uid = Request::host(); + $this->fetch(); + } + + /** + * @description:提现 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function cash() + { + $uid = $this->uid; + $user = Db::name('LcUser')->find($uid); + $cashConfig = [ + 'user' => $user, + "bank" => Db::name('LcBank')->where('uid', $uid)->order("id desc")->select(), + 'txsxf' => getInfo('cash_charge'), + 'cash_start' => getInfo('cash_start'), + 'cash_end' => getInfo('cash_end'), + 'cash_min' => getInfo('cash_min'), + 'cash_max' => getInfo('cash_max'), + 'cash_day_max' => getInfo('cash_day_max'), + 'cash_max_num' => getInfo('cash_max_num') + ]; + if (Request::isPost()) { + if ($user['rz_status'] != 2) { + $this->error(json_lang("请先完成实名认证!")); + } + if ($user['isjy'] == 1) { + $this->error(json_lang("账号被锁定,请联系管理员!")); + } + $time = time(); + $cash_start = strtotime(date('Y-m-d ' . $cashConfig['cash_start'] . ':00')); + $cash_end = strtotime(date('Y-m-d ' . $cashConfig['cash_end'] . ':00')); + if ($time < $cash_start || $time > $cash_end) { + $this->error(json_lang("提现时间为") . $cashConfig['cash_start'] . '-' . $cashConfig['cash_end']); + } + $data = Request::param(); + $money = $data['money']; + if (!$money) $this->error(json_lang("提现金额不能为空!")); + $pwd = $data['pwd']; + if (!$pwd) $this->error(json_lang("提现密码不能为空!")); + $today = date('Y-m-d 00:00:00'); + if ($user['password2'] != md5($data['pwd'])) + $this->error(json_lang("交易密码不正确!")); + if ($data['money'] < $cashConfig['cash_min']) + $this->error(json_lang("提现金额不能小于") . $cashConfig['cash_min']); + if ($data['money'] > $cashConfig['cash_max']) + $this->error(json_lang("提现金额不能大于") . $cashConfig['cash_max']); + if ($user['money'] < $data['money']) + $this->error(json_lang("账户余额不足,请确认")); + + $day_num = Db::name('LcCash')->where("uid = $uid AND time > '$today'")->count(); + if ($day_num >= $cashConfig['cash_max_num']) + $this->error(json_lang('每日提现次数') . $cashConfig['cash_max_num']); + + $day_sum = Db::name('LcCash')->where("uid = $uid AND time > '$today'")->sum('money'); + if ($day_sum >= $cashConfig['cash_day_max']) + $this->error(json_lang('当日累计最高提现金额不能大于') . $cashConfig['cash_day_max']); + if ($data['bank'] != 0) { + $bank = Db::name('LcBank')->where('id', $data['bank'])->find(); + if ($bank['uid'] != $uid || empty($bank)) + $this->error('请先绑定提现银行卡!'); + } + $cash_charge = getInfo('cash_charge'); + + $sxf = $data['money'] * $cash_charge * 0.01; + + $dzje = $data['money'] - $sxf; + + $sxfbfb = $cash_charge; + if ($data['bank'] == 0) { + $add = array( + 'uid' => $uid, + 'sxf' => $sxf, + 'dzje' => $dzje, + 'sxfbfb' => $sxfbfb, + 'name' => $user['name'], + 'bid' => $data['bank'], + 'bank' => '支付宝', + 'area' => 0, + 'account' => $user['alipay'], + 'money' => $data['money'], + 'status' => 0, + 'time' => date('Y-m-d H:i:s'), 'time2' => '0000-00-00 00:00:00'); + } + else { + $add = array('uid' => $uid, + 'sxf' => $sxf, + 'dzje' => $dzje, + 'sxfbfb' => $sxfbfb, + 'name' => $user['name'], + 'bid' => $data['bank'], + 'bank' => $bank['bank'], + 'area' => $bank['area'] ?: 0, + 'account' => $bank['account'], + 'money' => $data['money'], 'status' => 0, 'time' => date('Y-m-d H:i:s'), 'time2' => '0000-00-00 00:00:00'); + } + + if (Db::name('LcCash')->insert($add)) { + addFinance($uid, $data['money'], 2, "余额提现{$data['money']}元"); + setNumber('LcUser', 'money', $data['money'], 2, "id = $uid"); + + $this->success(json_lang("提现申请成功!")); + } else { + $this->error(json_lang("提现失败!")); + } + } + $this->success(json_lang("操作成功"), $cashConfig); + } + + /** + * @description:充值 + * @date: 2020/5/14 0014 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function recharge() + { + $uid = $this->uid; + $user = Db::name('LcUser')->find($uid); + $min_recharge = 1; + if (Request::isPost()) { + $data = Request::param(); + if ($data['money'] < $min_recharge) { + $this->error('最低充值' . $this->min_recharge . '元'); + } + $add = [ + 'uid' => $uid, + 'money' => $data['money'], + 'type' => "TRC20", + 'status' => 0, + 'time' => date('Y-m-d H:i:s'), + 'time2' => '0000-00-00 00:00:00' + ]; + Db::name('LcRecharge')->insertGetId($add); + $this->success(json_lang('操作成功')); + } + $this->success(json_lang('操作成功'), ['user' => $user, 'min_recharge' => $min_recharge, 'address' => "TZEGFjVuHmGJCxc31e1GxgdonJEZVopJy4"]); + } + + /** + * @description:扫描充值 + * @date: 2020/5/14 0014 + */ + public function scan() + { + $type = $this->request->param('type'); + $this->money = $this->request->param('money'); + $this->qr = getInfo('qr_alipay_img'); + if ($type == 'wechat') + $this->qr = getInfo('qr_wechat_img'); + $this->fetch(); + } + + /** + * Describe:提现银行 + * DateTime: 2020/5/14 21:44 + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function bank() + { + $uid = $this->uid; + + + if (Request::isPost()) { + $data = $this->request->param(); + $update = array('reason' => '付款人:' . $data['name'] . '
转账附言:' . $data['reason']); + if (Db::name('LcRecharge')->where(['uid' => $uid, 'status' => 0, 'orderid' => $data['orderid']])->update($update)) { + msg('操作成功!', 2, '/index/user/index'); + } else { + msg('操作失败!', 2, '/index/user/index'); + } + } + $this->type = $this->request->param('type'); + $this->orderid = $this->request->param('orderid'); + $this->money = $this->request->param('money'); + if (empty($this->orderid)) + msg('充值失败!', 2, '/index/user/index'); + $this->fetch(); + } + + /** + * Describe:合同详情 + * DateTime: 2020/5/14 21:44 + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function contract() + { + $this->uid = $this->uid; + if (!$this->uid) + + $id = $this->request->param('id'); + if (empty($id)) + msg('参数缺失!', 2, '/index/user/index'); + $this->invest = Db::name('LcInvest')->where(['uid' => $this->uid, 'id' => $id])->find(); + $this->list = Db::name('LcInvestList')->where(['uid' => $this->uid, 'iid' => $id])->order('id desc')->select(); + //if(!$this->invest||!$this->list) msg('暂无数据!', 2, '/index/user/index'); + $this->fetch(); + } + + public function mall_contract() + { + $this->uid = $this->uid; + if (!$this->uid) + + $id = $this->request->param('id'); + if (empty($id)) + msg('参数缺失!', 2, '/index/user/index'); + $this->invest = Db::name('LcMallInvest')->where(['uid' => $this->uid, 'id' => $id])->find(); + $this->list = Db::name('LcMallInvestList')->where(['uid' => $this->uid, 'iid' => $id])->order('id desc')->select(); + $this->fetch(); + } + + public function details() + { + $this->uid = $this->uid; + if (!$this->uid) + + $id = $this->request->param('id'); + if (empty($id)) + msg('参数缺失!', 2, '/index/user/index'); + $this->invest = Db::name('LcInvest')->where(['uid' => $this->uid, 'id' => $id])->find(); + $this->list = Db::name('LcInvestList')->where(['uid' => $this->uid, 'iid' => $id])->order('id asc')->select(); + if (!$this->invest || !$this->list) + msg('暂无数据!', 2, '/index/user/index'); + $this->fetch(); + } + + public function wallet() + { + $this->uid = $this->uid; + if (!$this->uid) + + $user = Db::name('LcUser')->find($this->uid); + $now = date('Y-m-d H:i:s'); + $this->kjbz = Db::name('LcMallInvest')->where('uid', $this->uid)->where("time2 >= '$now'")->sum('money'); + $this->hybz = Db::name('LcInvest')->where('uid', $this->uid)->where("time2 >= '$now'")->sum('money'); + + $this->kjcl = Db::name('LcMallInvestList')->where(['uid' => $this->uid, 'status' => 1])->sum('money1'); + $this->hysy = Db::name('LcInvestList')->where(['uid' => $this->uid, 'status' => 1])->sum('money1'); + $this->kjsy = Db::name('LcFinance')->where("uid = {$this->uid} AND reason LIKE '%BTC兑换%'")->sum('money'); + $this->fetch(); + } + + public function trade() + { + $this->uid = $this->uid; + if (!$this->uid) + + $user = Db::name('LcUser')->find($this->uid); + $this->fetch(); + } + + public function tradeBTC() + { + $uid = $this->uid; + + + $user = Db::name('LcUser')->find($uid); + $data = $this->request->param(); + if ($data['buynum'] <= 0) + $this->error("无效数量"); + if ($data['buynum'] > $user['btc']) + $this->error("BTC不足"); + $btc_price = 393848.54; + $money = round($btc_price * $data['buynum'], 2); + addFinance($uid, $money, 1, "BTC兑换交易{$money}元"); + setNumber('LcUser', 'money', $money, 1, "id = {$uid}"); + setNumber('LcUser', 'btc', $data['buynum'], 2, "id = {$uid}"); + $this->success("交易成功"); + } + + /** + * @description:退出登录 + * @date: 2020/5/13 23:57 + */ + public function logout() + { + $uid = $this->uid; + Db::table('lc_user')->where('id', $uid)->limit(1)->update(['access_time' => 0]); + session('uid', null); + //$this->app->session->clear(); + //$this->app->session->destroy(); + $this->redirect('/index'); + } + + public function hold() + { + $uid = $this->uid; + + + $page = Request::param('page', 1); + $num = Request::param('num', 10); + $this->type = $this->request->param('type'); + $this->hold = Db::name('LcOrder')->where(array('uid' => $uid, 'ostaus' => 0))->order('id desc')->page($page, $num)->select(); + //->field('id,ptitle,buytime,fee,ostyle') + //var_dump($this->hold);die; + $this->success(json_lang("操作成功"), $this->hold); + } + + /** + * 下单 + * @return void [type] [description] + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @author lukui 2017-07-20 + */ + public function addorder() + { + $data = Request::param(); + $uid = $this->uid; + //用户信息 + $user = Db::name('LcUser')->find($uid); + if (!$user) $this->error(json_lang("用户不存在")); + //验证用户是否被冻结 + if ($user['clock'] == 1) { + // return WPreturn('您的账户已被冻结',-1); + } + if ($user['isjy'] == 1) { + $this->error(json_lang("账号被锁定,请联系管理员!")); + } + $adddata['uid'] = $uid; + $pro = Db::name('LcProduct')->find($data['order_pid']); + if (!$pro) + $this->error(json_lang("产品未找到")); + //验证是否开市 + if ($pro['isopen']) { + $isopen = ChickIsOpen($pro['id']); + if ($isopen == 0) { + $this->error(json_lang("休市中")); + } + } else { + $this->error(json_lang("休市中")); + } + if (getinfo('order_max_amount') > 0) { + $allfee = Db::name('LcOrder')->where(array('ostaus' => 0, 'uid' => $data['uid']))->sum('fee'); + $allfee = $allfee ? $allfee : 0; + if ($allfee + $data['order_price'] > getinfo('order_max_amount')) { + $this->error(json_lang("持仓最大金额为") . getinfo('order_max_amount') . '!'); + } + } + if ($data['order_price'] < getinfo('order_min')) { + $this->error(json_lang("持仓最小金额为") . getinfo('order_min') . '!'); + } + //持仓限制 + if (getinfo('order_max_amount') > 0) { + $allfee = Db::name('LcOrder')->where(array('ostaus' => 0, 'uid' => $data['uid']))->sum('fee'); + $allfee = $allfee ? $allfee : 0; + if ($allfee + $data['order_price'] > getinfo('order_max_amount')) { + $this->error(json_lang("持仓最大金额为") . getinfo('order_max_amount') . '!'); + } + } + if (getinfo('order_max_count') > 0) { + Db::name('LcOrder')->where(array('ostaus' => 0, 'uid' => $data['uid']))->count(); + } + //手续费 + $web_poundage = 0; + if (getinfo('order_charge') > 0) { + $web_poundage = round($data['order_price'] * getinfo('order_charge') / 100, 2); + } + $moneyfrom = 1; + //验证余额是否够 + if ($user['money'] < $data['order_price'] + $web_poundage) { + $this->error(json_lang("账户余额不足,请确认")); + } + if (floatval($data['newprice']) <= 0) { + $this->error(json_lang("操作失败")); + } + //建仓 + $adddata['buytime'] = time(); + $adddata['endprofit'] = $data['order_sen']; + $adddata['pid'] = $data['order_pid']; + $adddata['ostyle'] = $data['order_type']; + $adddata['buyprice'] = $data['newprice']; + $adddata['endloss'] = $data['order_shouyi']; + $adddata['lossrate'] = $data['order_kuishun']; + $adddata['eid'] = 2; + $adddata['selltime'] = $adddata['buytime'] + $adddata['endprofit']; + $adddata['fee'] = $data['order_price']; + $adddata['ptitle'] = $pro['title']; + $adddata['ostaus'] = '0'; + $adddata['sx_fee'] = $web_poundage; + $allfee = $adddata['fee'] + $adddata['sx_fee']; + //会员建仓后金额 + $adddata['commission'] = $user['money'] - $allfee; + //订单号 + $adddata['orderno'] = date('YmdHis') . $uid . rand(1111, 9999); + //var_dump($adddata); + //下单 + $id = Db::name('LcOrder')->insertGetId($adddata); + if ($id) { + //下单成功减用户余额 + if ($moneyfrom == 1) { + addFinance($uid, $allfee, 2, '下单[' . $adddata['orderno'] . ']从账户扣除金额 ' . $allfee . '元'); + setNumber('LcUser', 'money', $allfee, 2, "id = $uid"); + } + if ($moneyfrom == 2) { + addFinance($uid, $allfee, 2, '下单[' . $adddata['orderno'] . ']从余额宝扣除金额 ' . $allfee . '元'); + setNumber('LcUser', 'money', $allfee, 2, "id = $uid"); + //Db::table('lc_yuebao_uc')->where('uid = '.$uid)->update(['balance']) + } + $nowmoney = $adddata['commission']; + if ($nowmoney < 0) { + $nowmoney = 0; + } + $adddata['oid'] = $id; + $order_rand = rand(1, 1000); + $adddata['order_rand'] = $order_rand; + $this->success(json_lang("操作成功"), $adddata); + } else { + $this->error(json_lang("操作失败")); + } + } + + public function goorder() + { + // { + // "price": "275.661", + // "oid": "463", + // "order_rand": "547" + // } + $data = $this->request->param(); + $oid = $data['oid']; + $price = $data['price']; + $order_rand = $data['order_rand']; + + $static = 1; //1成功返回并继续运行 0失败返回不运行 2 失败返回继续轮询 + if (!$oid || !$price || !$order_rand) { + die('0' . $oid . '-' . $price . '-' . $order_rand); + } + + $order = Db::name('LcOrder')->find($oid); + + //没有此订单 + if (!$order) { + die('1' . $oid . '-' . $price . '-' . $order_rand); + } + + //没有平仓 + if (isset($order['ostyle']) && $order['ostaus'] == 0) { + die('2'); + } + + //已平仓 但是价格相同 + if (isset($order['sellprice']) && $order['sellprice'] == $price) { + cache('goorder_' . $order['id'], null); + die('1'); + } + + //已平仓 但是无效交易 + if (isset($order['is_win']) && $order['is_win'] == 3) { + cache('goorder_' . $order['id'], null); + die('1'); + } + //该订单指定赢亏 + if (isset($order['kong_type']) && $order['kong_type'] != 0) { + cache('goorder_' . $order['id'], null); + die('1'); + } + die('1'); + } + + public function get_price() + { + //此刻产品价格 + $pro = Db::name('LcProduct')->field('id,Price')->where(array('isdelete' => 0))->select(); + $prodata = array(); + foreach ($pro as $k => $v) { + $prodata[$v['id']] = $v['Price']; + } + return base64_encode(json_encode($prodata));; + } + + /** + * ajax 通过产品id 获取用户订单, + * @return [type] [description] + * @author lukui 2017-07-22 + */ + public function ajaxorder() + { + $uid = $this->uid; + $pid = $this->request->param('pid'); + if (empty($uid) || empty($pid)) { + return false; + } + //持仓信息 + $map = []; + $map[] = ['uid', '=', $uid]; + $map[] = ['pid', '=', $pid]; + $map[] = ['ostaus', '=', 0]; + $map[] = ['selltime', '>', time()]; + + $list = Db::name('LcOrder')->where($map)->order('id desc')->select(); + foreach ($list as $key => $value) { + $list[$key]['time'] = time(); + } + if ($list) { + return base64_encode(json_encode($list)); + // return json_encode($list); + } else { + return false; + } + + } + + /** + * ajax 通过产品id 平仓后弹框提示, + * @return [type] [description] + * @author lukui 2017-07-22 + */ + public function ajaxalert() + { + $uid = $this->uid; + $pid = $this->request->param('pid'); + if (empty($uid) || empty($pid)) { + return false; + } + //持仓信息 + $hold = Db::name('LcOrder')->field('id,ploss,fee,eid')->where(array('uid' => $uid, 'ostaus' => 1, 'pid' => $pid, 'isshow' => 0))->order('id desc')->find(); + //修改持仓信息 + $isedit = Db::name('LcOrder')->where('id', $hold['id'])->setField('isshow', '1'); + if ($hold && $isedit) { + return $hold; + } else { + return false; + } + } + + /** + * 交易记录 + * @return [type] [description] + * @author lukui 2017-07-22 + */ + public function ajaxorder_list() + { + $uid = $this->uid; + if (empty($uid)) { + $this->error('用户ID不能为空'); + } + + $type = input('type', 0); + $page = Request::param('page', 1); + $num = Request::param('num', 10); + //持仓信息 + $map = []; + $map[] = ['ostaus', '=', $type]; + $map[] = ['uid', '=', $uid]; + + $list = Db::name('LcOrder')->where($map)->order('id desc')->page($page, $num)->select(); + foreach ($list as $key => $value) { + $list[$key]['time'] = time(); + $list[$key]['ploss'] = round($value['ploss'], 2); + } + if ($list) { + $this->success(json_lang("操作成功"), $list); + } else { + $this->success('暂无数据', []); + } + } + + public function getchart() + { + $data['hangqing'] = '商品行情'; + $data['jiaoyijilu'] = '交易记录'; + $data['jiaoyilishi'] = '历史委托'; + $data['chicangmingxi'] = '持仓明细'; + $data['lishimingxi'] = '历史明细'; + $data['gendanjiaoyi'] = '跟单交易'; + $res = base64_encode(json_encode($data)); + return $res; + } + + public function orderlist() + { + $uid = $this->uid; + if (empty($uid)) { + return false; + } + $map = []; + $map[] = ['uid', '=', $uid]; + $map[] = ['ostaus', '=', 1]; + + $hold = Db::name('LcOrder')->where($map)->order('id desc')->paginate(20); + return base64_encode(json_encode($hold)); + } + + /** + * 已平仓订单详情 + * @return [type] [description] + * @author lukui 2017-07-21 + */ + public function orderinfo() + { + $uid = $this->uid; + $oid = $this->request->param('oid'); + if (!$oid) { + $this->redirect('orderlist'); + } + $order = Db::name('LcOrder')->where('id', $oid)->find(); + $this->assign($order); + return $this->fetch(); + + } + + /** + * 实时获取以平仓订单 + * @return [type] [description] + */ + public function get_this_order() + { + $oid = $this->request->param('oid'); + $map['id'] = $oid; + $map['ostaus'] = 1; + $order = Db::name('LcOrder')->where($map)->find(); + + return base64_encode(json_encode($order)); + } + + /** + * 实时获取以平仓订单 + * @return [type] [description] + */ + public function get_hold_order() + { + $oid = $this->request->param('oid'); + $map['id'] = $oid; + $map['ostaus'] = 1; + + $order = Db::name('LcOrder')->where($map)->find(); + + return base64_encode(json_encode($order)); + } + + public function inquiries() + { + $uid = $this->uid; + + + $map['uid'] = $uid; + $map['ostaus'] = 1; + + $this->list = Db::name('LcOrder')->where($map)->order('id desc')->select(); + + $this->fetch(); + } + + public function yeb() + { + $yuebao = Db::name('lc_yuebao')->where('status = 1')->order('id desc')->select(); + $this->success(json_lang("操作成功"), $yuebao); + } + + public function yebtrans() + { + Db::startTrans(); + try { + $uid = $this->uid; + $money = (float)input('post.money'); + if ($money <= 0) { + return json(['code' => 500, 'msg' => '转出金额错误!']); + } + $uc = Db::table('lc_yuebao_uc')->lock(true)->where('uid', $uid)->find(); + if ($money > $uc['trans_balance']) { + return json(['code' => 500, 'msg' => '大于可转出金额!']); + } + Db::table('lc_yuebao_uc')->where('id', $uc['id'])->limit(1)->update(['trans_balance' => round($uc['trans_balance'] - $money, 1)]); + $userMoney = DB::table('lc_user')->where('id', $uid)->value('money'); + Db::table('lc_user')->where('id', $uid)->limit(1)->update(['money' => round($userMoney + $money, 1)]); + DB::table('lc_finance')->insert(['uid' => $uid, 'money' => $money, 'type' => 1, 'reason' => '利息宝转出', 'before' => $userMoney, 'time' => date('Y-m-d H:i:s')]); + return json(['code' => 200, 'msg' => '转出成功!']); + Db::commit(); + } catch (Exception $e) { + Db::rollback(); + return json(['code' => 500, 'msg' => '转出失败!']); + } + } + + public function yebjoinnow() + { + // + $param = Request::param(); + $uid = $this->uid; + //优先核对账户余额,并扣减。 + $where['id'] = $uid; + $userinfo = Db::table('lc_user')->where($where)->find(); + if ($userinfo['money'] < $param['money']) { + $this->error(json_lang("账户余额不足,请确认")); + } + //查找余额宝理财方案信息,并校检。 + $where['id'] = $param['yebid']; + $yebinfo = Db::table('lc_yuebao')->where($where)->find(); + if ($yebinfo['lowmoney'] > $param['money']) { + $this->error(json_lang("您办理的方案有最低存入:") . $yebinfo['lowmoney']); + } + $newmoney = $userinfo['money'] - $param['money']; + $res = Db::table('lc_user')->where('id', $userinfo['id'])->update(['money' => $newmoney]); + if (!$res) { + $this->error(json_lang("网络异常,请稍后再试:")); + } + $res = DB::table('lc_finance')->insert(['uid' => $userinfo['id'], 'money' => $param['money'], 'type' => 2, 'reason' => '利息宝转入', 'before' => $userinfo['money'], 'time' => date('Y-m-d H:i:s')]); + if (!$res) { + $this->error(json_lang("网络异常,请稍后再试:")); + } + //保存办理记录。 + $savelist = array('uid' => $uid, + 'username' => $userinfo['phone'], + 'yuebaoid' => $yebinfo['id'], + 'yebtitle' => $yebinfo['title'], + 'lily' => $yebinfo['lily'], + 'money' => $param['money'], + 'days' => $yebinfo['days'], + 'start_time' => time(), + 'profit_time' => time(), + 'end_time' => time() + $yebinfo['days']*86400, + 'nowprofit' => 0, 'finishprofit' => round(($param['money'] * $yebinfo['lily']/ 100) * $yebinfo['days'], 4), 'status' => 1); + $newid = Db::table('lc_yuebao_lists')->insertGetId($savelist); + if (!$newid) { + $this->error(json_lang("网络异常,请稍后再试:")); + } + //再做UC + unset($where['id']); + $where['uid'] = $uid; + $yebucinfo = Db::table('lc_yuebao_uc')->where($where)->find(); + $newbalance = $yebucinfo['balance'] + $param['money']; + Db::table('lc_yuebao_uc')->where($where)->update(['balance' => $newbalance]); + //再做UCLOG + $yebuclog = array('uid' => $uid, 'balance' => $yebucinfo['balance'], 'money' => $param['money'], 'addtime' => time(), 'remarks' => "用户购买理财方案:" . $yebinfo['title']); + Db::table('lc_yuebao_uclog')->insert($yebuclog); + $this->success(json_lang("操作成功")); + } + + public function yebstop() + { + $uid = $this->uid; + + $param = Request::param(); + + $getlistinfo = Db::table('lc_yuebao_lists')->where('id=' . $param['id'])->find(); + + if ($getlistinfo['status'] != 1 or empty($getlistinfo)) { + return "操作失败:订单无法操作!"; + die; + } + + $getuserinfo = Db::table('lc_user')->where('id=' . $getlistinfo['uid'])->find(); + //var_dump($getlistinfo,$getuserinfo);die; + if (!empty($getuserinfo)) { + Db::table('lc_yuebao_lists')->where('id=' . $param['id'])->update(['status' => 2, 'end_time' => time()]); + //记录日志! + unset($getlistinfo['id']); + $getlistinfo['status'] = 2; + $getlistinfo['end_time'] = time(); + $getlistinfo['balance'] = $getuserinfo['money']; + $getlistinfo['closetime'] = time(); + $getlistinfo['remarks'] = "客户手动结算"; + Db::table('lc_yuebao_log')->insert($getlistinfo); + //更新用户余额 + $newbalance = $getuserinfo['money'] + $getlistinfo['nowprofit'] + $getlistinfo['money']; + Db::table('lc_user')->where('id=' . $getlistinfo['uid'])->update(['money' => $newbalance]); + //更新UC + $where['uid'] = $uid; + $yebucinfo = Db::table('lc_yuebao_uc')->where($where)->find(); + $newbalance = $yebucinfo['balance'] - $getlistinfo['money']; + Db::table('lc_yuebao_uc')->where($where)->update(['balance' => $newbalance]); + //再做UCLOG + $yebuclog = array('uid' => $uid, 'balance' => $yebucinfo['balance'], 'money' => $getlistinfo['money'], 'addtime' => time(), 'remarks' => "用户购买理财方案:" . $getlistinfo['title']); + Db::table('lc_yuebao_uclog')->insert($yebuclog); + + return "ok"; + die; + + } else { + return "操作失败:订单无法操作!"; + die; + } + + } + + public function yebkeep() + { + $uid = $this->uid; + + + $param = Request::param(); + $getlistinfo = Db::table('lc_yuebao_lists')->where('id=' . $param['id'])->find(); + if ($getlistinfo['status'] == 2) { + return "操作失败:订单无法操作!"; + die; + } elseif ($getlistinfo['status'] == 1) { + $getlistinfo['end_time'] = $getlistinfo['end_time'] + $getlistinfo['days'] * 86400; + } + unset($getlistinfo['id']); + Db::table('lc_yuebao_lists')->where('id=' . $param['id'])->update(['end_time' => $getlistinfo['end_time']]); + return "操作成功"; + die; + } + + /** + * @description:身份认证 + * @date: 2020/5/14 0014 + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ + public function verified() + { + $uid = $this->uid; + + $user = Db::name('LcUser')->field('rz_status,name,idcard,z_id_card,f_id_card')->find($uid); + if (Request::isPost()) { + $param = Request::param(); + if ($user['rz_status'] == 2) { + $this->error(json_lang('已认证请勿重复提交!')); + } + $name = $param['name']; + if (!$name) $this->error(json_lang('名字不能为空!')); + $idcard = $param['idcard']; + if (!$idcard) $this->error(json_lang('身份证号码不能为空!')); + $z_id_card = $param['z_id_card']; + if (!$z_id_card) $this->error(json_lang('身份证正面照不能为空!')); + $f_id_card = $param['f_id_card']; + if (!$f_id_card) $this->error(json_lang('身份证反面照不能为空!')); +// $country = $param['country']; +// if (!$country) $this->error(json_lang('地址不能为空!')); + $data = $param; + $check = Db::name('LcUser')->where("idcard = '{$data['idcard']}' AND id <> " . $uid)->find(); + if ($check) + $this->error(json_lang('身份证号码已被其他账号绑定!')); + if (Db::name('LcUser')->where(['id' => $uid])->update([ + 'name' => $data['name'], + 'idcard' => $data['idcard'], + 'z_id_card' => $data['z_id_card'], + 'f_id_card' => $data['f_id_card'], +// 'country' => $data['country'], + 'rz_status' => 1 + ])) { + $this->success(json_lang('认证信息提交成功!')); + } else { + $this->error(json_lang('认证信息提交失败!')); + } + } + $this->success(json_lang('操作成功'), $user); + } +} diff --git a/application/index/controller/code.txt b/application/index/controller/code.txt new file mode 100755 index 0000000..b97fc71 --- /dev/null +++ b/application/index/controller/code.txt @@ -0,0 +1,20 @@ +btc_usdt +eth_usdt +ht_usdt +dot_usdt +link_usdt +bch_usdt +ltc_usdt +bsv_usdt +eos_usdt +xmr_usdt +dash_usdt +zec_usdt +etc_usdt +ksm_usdt +yfi_usdt +yfii_usdt +iota_usdt +neo_usdt +wbtc_usdt +pax_usdt diff --git a/application/index/service/IndexService.php b/application/index/service/IndexService.php new file mode 100755 index 0000000..6639ff4 --- /dev/null +++ b/application/index/service/IndexService.php @@ -0,0 +1,23 @@ +find($uid); + if(!$user||!$user['clock']) return false; + $data = ['logintime' => time(),'id'=>$uid]; + Db::name('LcUser')->update($data); + return true; + } +} + +/** + * @description:手机号验证 + * @date: 2020/5/14 0014 + * @param $phone + * @return bool + */ +function isMobile($phone){ + if(preg_match("/^1[3456789]{1}\d{9}$/",$phone)) return true; + return false; +} +function isAlphaNum($phone){ + if(preg_match("/^[A-Za-z0-9]+$/",$phone)) return true; + return false; +} + +/** + * @description:IP查询 + * @date: 2020/5/14 0014 + * @param string $ip + * @return array|bool|string + */ +function GetIpLookup($ip = ''){ + if(empty($ip)){ + return ''; + } + $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip; + $ip=json_decode(file_get_contents($url)); + if((string)$ip->code=='1'){ + return false; + } + $data = (array)$ip->data; + return $data; +} + +/** + * @description:添加流水 + * @date: 2020/5/13 0013 + * @param $uid + * @param $money + * @param $type + * @param $reason + * @return bool + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function addFinance($uid,$money,$type,$reason){ + $user = Db::name('LcUser')->find($uid); + if(!$user) return false; + if($user['money']<0) return false; + $data = array( + 'uid' => $uid, + 'money' => $money, + 'type' => $type, + 'reason' => $reason, + 'before' => $user['money'], + 'time' => date('Y-m-d H:i:s') + ); + Db::name('LcFinance')->insert($data); +} + +/** + * @description: + * @date: 2020/5/14 0014 + * @param $str + * @param $type + * @return bool + */ +function judge($str, $type) +{ + $char = ''; + if ($type == 'int') { + $char = '/^\\d*$/'; + } + else if ($type == 'email') { + $char = '/([\\w\\-]+\\@[\\w\\-]+\\.[\\w\\-]+)/'; + } + else if ($type == 'idcard') { + $char = '/[0-9]{17}([0-9]|X)/'; + } + else if ($type == 'name') { + $char = '/^[\\x{4e00}-\\x{9fa5}]+[·•]?[\\x{4e00}-\\x{9fa5}]+$/u'; + } + else if ($type == 'phone') { + $char = '/^1[3456789]{1}\\d{9}$/'; + } + else if ($type == 'tel') { + $char = '/(^(\\d{3,4}-)?\\d{7,8})$/'; + } + else if ($type == 'date') { + $char = '/^\\d{4}[\\-](0?[1-9]|1[012])[\\-](0?[1-9]|[12][0-9]|3[01])?$/'; + } + else if ($type == 'time') { + $char = '/^\\d{4}[\\-](0?[1-9]|1[012])[\\-](0?[1-9]|[12][0-9]|3[01])(\\s+(0?[0-9]|1[0-9]|2[0-3])\\:(0?[0-9]|[1-5][0-9])\\:(0?[0-9]|[1-5][0-9]))?$/'; + } + else if ($type == 'exist') { + } + else { + return false; + } + if (preg_match($char, $str)) { + return true; + } + return false; +} + +/** + * @description:设置 + * @date: 2020/5/13 0013 + * @param $database + * @param $field + * @param $value + * @param int $type + * @param string $where + * @return int|true + * @throws \think\Exception + */ +function setNumber($database, $field, $value, $type = 1, $where = '') +{ + if ($type != 1) { + $re = Db::name($database)->where($where)->setDec($field, $value); + } + else { + $re = Db::name($database)->where($where)->setInc($field, $value); + } + return $re; +} + +/** + * @description:脱敏 + * @date: 2020/5/14 0014 + * @param $string + * @param int $start + * @param int $length + * @param string $re + * @return bool|string + */ +function dataDesensitization($string, $start = 0, $length = 0, $re = '*') +{ + if (empty($string)) { + return false; + } + $strarr = array(); + $mb_strlen = mb_strlen($string); + while ($mb_strlen) { + $strarr[] = mb_substr($string, 0, 1, 'utf8'); + $string = mb_substr($string, 1, $mb_strlen, 'utf8'); + $mb_strlen = mb_strlen($string); + } + $strlen = count($strarr); + $begin = $start >= 0 ? $start : ($strlen - abs($start)); + $end = $last = $strlen - 1; + if ($length > 0) { + $end = $begin + $length - 1; + } elseif ($length < 0) { + $end -= abs($length); + } + for ($i = $begin; $i <= $end; $i++) { + $strarr[$i] = $re; + } + if ($begin >= $end || $begin >= $last || $end > $last) return false; + return implode('', $strarr); +} + +/** + * @description:投资状态 + * @date: 2020/5/14 0014 + * @param $id + * @return string + */ +function getInvestStatus($id) +{ + $invest = Db::name('LcInvestList')->where("status = 0 AND iid = $id")->count(); + if (0 < $invest) { + return '未完成'; + } + return '已完成'; +} + +/** + * @description:身份认证 + * @date: 2020/5/14 0014 + * @param $id_card + * @param $name + * @param $app_code + * @return array + */ +function idCardAuth($id_card,$name){ + $host = 'http://idcard.market.alicloudapi.com'; + $path = '/lianzhuo/idcard'; + $method = 'GET'; + $appcode = getInfo('linetoken'); + $headers = array(); + array_push($headers, 'Authorization:APPCODE ' . $appcode); + $querys = 'cardno=' . $id_card . '&name=' . $name; + $url = $host . $path . '?' . $querys; + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, false); + if (1 == strpos('$' . $host, 'https://')) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + $re = curl_exec($curl); + $resp = json_decode($re, true); + if ($resp['resp']['code'] == '5') return ['code'=>0,'msg'=>'姓名和身份证号码不匹配']; + if ($resp['resp']['code'] == '14') return ['code'=>0,'msg'=>'无此身份证号码']; + if ($resp['resp']['code'] == '96') return ['code'=>0,'msg'=>'交易失败,请稍后重试']; + if ($resp['resp']['code'] != '0') return ['code'=>0,'msg'=>'网络繁忙,请稍后重试!']; + return ['code'=>1,'msg'=>'认证成功']; +} + +/** + * @description:银行卡认证 + * @date: 2020/5/14 0014 + * @param $name + * @param $account + * @param $id_card + * @return array + */ +function bankAuth($name,$account,$id_card){ + $host = 'http://lundroid.market.alicloudapi.com'; + $path = '/lianzhuo/verifi'; + $method = 'GET'; + $appcode = getInfo('banktoken'); + $headers = array(); + array_push($headers, 'Authorization:APPCODE ' . $appcode); + $querys = 'acct_name=' . $name . '&acct_pan=' . $account . '&cert_id=' . $id_card; + $url = $host . $path . '?' . $querys; + $curl = curl_init(); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, false); + if (1 == strpos('$' . $host, 'https://')) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + header('Content-type:text/html; charset=utf-8'); + $re = curl_exec($curl); + $res = json_decode($re, true); + if($res['resp']['code'] == 0 && $res['resp']['desc'] == 'OK') return ['code'=>1,'bank'=>$res['data']['bank_name']]; + return ['code'=>0,'msg'=>'银行卡认证失败']; +} + +/** + * Describe:会员等级 + * DateTime: 2020/5/13 23:49 + * @param $member + * @return mixed|string + */ +function getUserMember($member) +{ + $member = Db::name('LcUserMember')->where("id = {$member}")->value('name'); + return $member?$member:'普通会员'; +} + +/** + * @description:获取支付方式 + * @date: 2020/5/14 0014 + * @param $pay + * @return string + */ +function getPayName($pay) +{ + switch ($pay) { + case 'wechat': + return '微信扫码'; + case 'alipay': + return '支付宝扫码'; + case 'bank': + return '银行入款'; + case 'gz_bank': + return '公账入款'; + case 'alipay_bank': + return '支付宝转银行卡'; + case 'wx_bank': + return '微信转银行卡'; + case 'online_wechat': + return '微信在线支付'; + case 'online_alipay': + return '支付宝在线支付'; + case 'wechat_scan': + return '微信在线扫码支付'; + default: + } + return '未知支付'; +} + +function gotoWechatPay($money){ + $status = getInfo('qr_wechat_statustz'); + $wxlianjie = getInfo('qr_wechattzlj'); + if($status == 1){ + $url = $wxlianjie; + } + else{ + $url = "/index/User/scan?type=wechat&money=".$money;//扫码链接 + } + header("Location:".$url); +} + +function gotoAlipay($money){ + $status = getInfo('qr_alipay_statustz'); + $zfblianjie = getInfo('qr_alipaytzlj'); + + if($status == 1){ + $url = $zfblianjie; + } + else{ + $url = "/index/User/scan?type=alipay&money=".$money;//扫码链接 + } + header("Location:".$url); +} + +/** + * Describe: 理财开关 + * DateTime: 2020/5/13 22:44 + * @param $uid + * @return int + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function getlcopen($uid = ''){ + $lcopen =0; + if(!$uid){ + $uid = Session::get('uid'); + } + if (!empty($uid)){ + $user = Db::name('LcUser')->where("id = $uid")->find(); + if (getInfo('qdlcopen') == 0){ + $lcopen = 1; + }else{ + if ($user['qdnum'] >= getInfo('qdnum') || $user['top'] > 0) { + $lcopen = 1; + }else{ + $lcopen = 0; + } + } + } + return $lcopen; +} + +/** + * @description:获取网站配置 + * @date: 2020/5/14 0014 + * @param $value + * @return mixed + */ +function getInfo($value){ + return Db::name('LcInfo')->where('id',1)->value($value); +} + +/** + * @description:获取奖励配置 + * @date: 2020/5/14 0014 + * @param $value + * @return mixed + */ +function getReward($value){ + return Db::name('LcReward')->where('id',1)->value($value); +} + +/** + * @description:项目进度 + * @date: 2020/5/14 0014 + * @param $id + * @return float|int|mixed + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function getProjectPercent($id){ + $item = Db::name('LcItem')->find($id); + if($item['auto']>0){ + $xc=diffBetweenTwoDays($item['time'],date('Y-m-d H:i:s')); + if($xc>$item['auto']){ + $total=100; + }else{ + $total= round($xc/$item['auto']*100); + } + }else{ + $pid = $item['id']; + $percent = $item['percent']; + $investMoney = Db::name('LcInvest')->where('pid', $pid)->sum('money'); + $actual = $investMoney / ($item['total'] * 10000) * 100; + $total = $actual + $percent; + } + if (100 < $total) return 100; + return $total; +} + +function diffBetweenTwoDays ($day1, $day2) +{ + $second1 = strtotime($day1); + $second2 = strtotime($day2); + if ($second1 < $second2) { + $tmp = $second2; + $second2 = $second1; + $second1 = $tmp; + } + return ($second1 - $second2) / 86400; +} + +/** + * @description: + * @date: 2020/5/14 0014 + * @param $money + * @param $rate + * @param $day + * @return float + */ +function getFuliIncome($money, $rate, $day) +{ + $sum = $money; + $i = 0; + while ($i < $day) { + $sum = $sum + $sum * $rate / 100; + ++$i; + } + return round($sum - $money, 2); +} + +/** + * @description: + * @date: 2020/5/14 0014 + * @param $pid + * @return float|int + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function getProjectSurplus($pid) +{ + $percent = getProjectPercent($pid); + $total = Db::name('LcItem')->where('id', $pid)->value('total'); + $surplus = (100 - $percent) * $total * 100; + if ($surplus < 0) return 0; + return $surplus; +} + +function getProfit($day_income,$cost){ + return number_format($day_income-$cost, 8, '.', ''); +} + +function getMinerPercent($total,$stock){ + return round(($total-$stock)/$total*100,2); +} + +/** + * @description:奖励设置 + * @date: 2020/5/14 0014 + * @param $uid + * @param $money + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function setInvestReward_old($uid, $money ) +{ + $reward = Db::name('LcReward')->find(1); + $top1 = round($reward['invest1'] * $money / 100, 2); + $top2 = round($reward['invest2'] * $money / 100, 2); + $top3 = round($reward['invest3'] * $money / 100, 2); + $t1 = Db::name('LcUser')->where(['id'=>$uid])->value('top') ?: 0; + $t2 = Db::name('LcUser')->where(['id'=>$t1])->value('top') ?: 0; + $t3 = Db::name('LcUser')->where(['id'=>$t2])->value('top') ?: 0; + if (0 < $top1 && !empty($t1)) { + addFinance($t1, $top1, 1, '推荐会员投资' . $money . '元奖励' . $top1 . '元!'); + setNumber('LcUser', 'money', $top1, 1, "id = $t1"); + setNumber('LcUser', 'income', $top1, 1, "id = $t1"); + } + if (0 < $top2 && !empty($t2)) { + addFinance($t2, $top2, 1, '二级推荐会员投资' . $money . '元奖励' . $top2 . '元!'); + setNumber('LcUser', 'money', $top2, 1, "id = $t2"); + setNumber('LcUser', 'income', $top2, 1, "id = $t2"); + } + if (0 < $top3 && !empty($t3)) { + addFinance($t3, $top3, 1, '三级推荐会员投资' . $money . '元奖励' . $top3 . '元!'); + setNumber('LcUser', 'money', $top3, 1, "id = $t3"); + setNumber('LcUser', 'income', $top3, 1, "id = $t3"); + } +} + + +function setUserMember($uid, $value) +{ + $member = Db::name('LcUserMember')->where("value <= '{$value}'")->order('value desc')->find(); + if(empty($member)){ + $mid = 0; + }else{ + $mid = $member['id']; + } + Db::name('LcUser')->where("id = {$uid}")->update(array('member' => $mid)); + return $mid; +} + +function getUserField($uid, $field) +{ + return Db::name('LcUser')->where(['id'=>$uid])->value($field); +} + +function getUserPhone($uid) +{ + return Db::name('LcUser')->where(['id'=>$uid])->value('phone'); +} + +/** + * @description: + * @date: 2020/5/14 0014 + * @param $uid + * @param $money + * @param $id + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function setInvestReward($uid, $money,$id) +{ + $reward = Db::name("LcItem")->find($id); + $top1 = round($reward['invest1'] * $money / 100, 2); + $top2 = round($reward['invest2'] * $money / 100, 2); + $top3 = round($reward['invest3'] * $money / 100, 2); + /*$red1 = round($reward['red1'], 2); + $red2 = round($reward['red2'], 2); + $red3 = round($reward['red3'], 2);*/ + $t1 = getUserField($uid, 'top') ?: 0; + $t2 = getUserField($t1, 'top') ?: 0; + $t3 = getUserField($t2, 'top') ?: 0; + if (0 < $top1 && !empty($t1)) { + addFinance($t1,$top1,1,'推荐会员(' . getUserPhone($uid) . ')投资' . $money . '元奖励' . $top1 . '元!'); + setNumber('LcUser', 'money', $top1, 1, 'id=\'' . $t1 . '\''); + setNumber('LcUser', 'income', $top1, 1, 'id=\'' . $t1 . '\''); + } + + if (0 < $top2 && !empty($t2)) { + addFinance($t2, $top2,1, '二级推荐会员(' . getUserPhone($uid) . ')投资' . $money . '元奖励' . $top2 . '元!'); + setNumber('LcUser', 'money', $top2, 1, 'id=\'' . $t2 . '\''); + setNumber('LcUser', 'income', $top2, 1, 'id=\'' . $t2 . '\''); + } + + if (0 < $top3 && !empty($t3)) { + addFinance($t3, $top3,1, '三级推荐会员(' . getUserPhone($uid) . ')投资' . $money . '元奖励' . $top3 . '元!'); + setNumber('LcUser', 'money', $top3, 1, 'id=\'' . $t3 . '\''); + setNumber('LcUser', 'income', $top3, 1, 'id=\'' . $t3 . '\''); + } + //以下为红包奖励 +/* if (0 < $red1 && !empty($t1)) { + addFinance($t1, $red1, 1, '推荐会员(' . getUserPhone($uid) . ')投资' . $money . '元奖励红包' . $red1 . '元!'); + setNumber('user', 'money', $red1, 1, 'id=\'' . $t1 . '\''); + setNumber('user', 'income', $red1, 1, 'id=\'' . $t1 . '\''); + } + + if (0 < $red2 && !empty($t2)) { + addFinance($t2, $red2, 1, '二级推荐会员(' . getUserPhone($uid) . ')投资' . $money . '元奖励红包' . $red2 . '元!'); + setNumber('user', 'money', $red2, 1, 'id=\'' . $t2 . '\''); + setNumber('user', 'income', $red2, 1, 'id=\'' . $t2 . '\''); + } + if (0 < $red3 && !empty($t3)) { + addFinance($t3, $red3, 1, '三级推荐会员(' . getUserPhone($uid) . ')投资' . $money . '元奖励红包' . $red3 . '元!'); + setNumber('user', 'money', $red3, 1, 'id=\'' . $t3 . '\''); + setNumber('user', 'income', $red3, 1, 'id=\'' . $t3 . '\''); + }*/ +} + +/** + * @description: + * @date: 2020/5/14 0014 + * @param $id + * @param $money + * @param $uid + * @return bool + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ +function getInvestList($id, $money, $uid) +{ + $item = Db::name('LcItem')->where(['id'=>$id])->find(); + $title = $item['title']; + $type = $item['type']; + $day = $item['day']; + $jfbl = $item['jfbl']; + $rate = $item['rate']; + $mid = Db::name('LcUser')->where(['id'=>$uid])->value('member'); + $member = Db::name('LcUserMember')->where("id = $mid")->find(); + if (!empty($member) && 0 < $member['rate']) { + $rate += $member['rate'] ?: 0; + } + /*if (date('Y-m-d H:i:s') <= $item['jiaxitime']) { + $rate += $item['jiaxi'] ?: 0; + }*/ + //赠送抽奖次数 + if ($item['prize'] == 1) { + $num = intval($money / $item['min']); + setNumber('LcUser', 'prize', $num, 1, "id = $uid"); + } + //赠送积分 + if ($item['integral'] == 1) { + setNumber('LcUser', 'integral', intval($money)*intval($jfbl), 1, "id = $uid"); + } + $res=Db::name('LcInvest')->order("id desc")->find(); + if($res['number']){ + $number= date('ymd').sprintf("%05d", substr($res['number'],-5)+1); + }else{ + $number= date('ymd').'01000'; + } + $invest = array('uid' => $uid,'number'=>$number ,'pid' => $id, 'title' => $title, 'money' => $money, 'day' => $day, 'rate' => $rate, 'type1' => $type, 'type2' => getprojecttype($type), 'status' => 0, 'time' => date('Y-m-d H:i:s'),'time2'=>date('Y-m-d H:i:s', strtotime('+' . $item['day'] . ' day'))); + setNumber('LcUser', 'value', $money, 1, "id = $uid"); + setUserMember($uid, Db::name('LcUser')->where(['id'=>$uid])->value('value')); + setInvestReward($uid, $money,$id); + $iid = Db::name('LcInvest')->insertGetId($invest); + if (!empty($iid)) { + if ($type == 1) { + $base = 1; + } + else if ($type == 2) { + $base = 7; + } + else if ($type == 3) { + $base = 30; + } + else if ($type == 4) { + $base = 1; + } + else if ($type == 5) { + $base = $day; + } + elseif ($type == 6) { + $base = 1; + + }else{ + $base = 0; + } + $day2 = $day / $base; + $bool = false; + $money2 = $money; + $i = 1; + while($i <= $day2){ + $time1 = $i * $base; + $data = array('uid' => $uid, 'iid' => $iid, 'num' => $i, 'title' => $title, 'money1' => round($money * $rate / 100 * $base, 2), 'money2' => 0, 'time1' => $type == 6?$item['fixedtime']:date('Y-m-d H:i:s', strtotime('+' . $time1 . ' day')), 'time2' => '0000-00-00 00:00:00', 'pay1' => $money * $rate / 100 * $base, 'pay2' => 0, 'status' => 0); + if($type == 4){ + $data['money1'] = $money2 - $money + round($money2 * $rate / 100 * $base, 2); + $data['money2'] = $money; + $data['pay1'] = 0; + $money2 += round($money2 * $rate / 100 * $base, 2); + } + if($i == $day2){ + $data['pay1'] += $money; + $data['money2'] += $money; + } + if($i == $day2 && $type == 4) { + $data['pay1'] = $money + $data['money1']; + $data['money2'] = $money; + } + if(Db::name('LcInvestList')->insertGetId($data)){ + $bool = true; + } + ++$i; + } + return $bool; + } + return false; +} + +function getMallInvestList($id, $money, $uid,$tran_type) +{ + $item = Db::name('LcMall')->where(['id'=>$id])->find(); + $title = $item['title']; + $day = $item['day']; + $profit = $item['day_income']-$item['cost']; + + $res=Db::name('LcMallInvest')->order("id desc")->find(); + if($res['number']){ + $number= date('ymd').sprintf("%05d", substr($res['number'],-5)+1); + }else{ + $number= date('ymd').'01000'; + } + + $invest = array( + 'uid' => $uid, + 'pid' => $id, + 'number' => $number, + 'title' => $title, + 'money' => $money, + 'num' => $money/$item['min'], + 'day' => $day, + 'day_income' => $item['day_income'], + 'cost' => $item['cost'], + 'profit' => $profit, + 'type' => $tran_type, + 'status' => 0, + 'time' => date('Y-m-d H:i:s'), + 'time2'=> date('Y-m-d H:i:s', strtotime('+' . $item['day'] . ' day')), + ); + $iid = Db::name('LcMallInvest')->insertGetId($invest); + if (!empty($iid)) { + $base = 1; + $day2 = $day / $base; + $bool = false; + $i = 1; + while($i <= $day2){ + $time1 = $i * $base; + $data = array( + 'uid' => $uid, + 'iid' => $iid, + 'num' => $i, + 'title' => $title, + 'money1' => $profit, + 'money2' => 0, + 'time1' => date('Y-m-d H:i:s', strtotime('+' . $time1 . ' day')), + 'time2' => '0000-00-00 00:00:00', + 'pay1' => $profit, + 'pay2' => 0, + 'tran_type' => $tran_type, + 'status' => 0 + ); + if($i == $day2){ + $data['money2'] += $money; + } + if(Db::name('LcMallInvestList')->insertGetId($data)){ + $bool = true; + } + ++$i; + } + return $bool; + } + return false; +} + +/** + * @description:获取项目类型 + * @date: 2020/5/14 0014 + * @param $pid + * @return string + */ +function getProjectType($pid) +{ + $str = '到期还本还息'; + switch ($pid) { + case 1: + $str = '按日付收益,保证金到期全额返还'; + break; + case 2: + $str = '每周返息,到期还本'; + break; + + case 3: + $str = '每月返息,到期还本'; + break; + + case 4: + $str = '每日复利,保本保息'; + break; + + case 5: + $str = '到期还本还息'; + break; + case 6: + $str = '当天投资,当天还本付息'; + break; + } + return $str; +} + +function getItemField($id, $field) +{ + return Db::name('LcItem')->where(['id'=>$id])->value($field); +} + +function getMallItemField($id, $field) +{ + return Db::name('LcMall')->where(['id'=>$id])->value($field); +} + +function getInvestMoney($id) +{ + return Db::name('LcInvestList')->where("iid = '$id' AND pay1 <> 0")->sum('money1'); +} + +/** + * @description:通用跳转 + * @date: 2020/5/14 0014 + * @param $msg + * @param int $time + * @param string $url + */ +function msg($msg, $time = 2, $url = '') +{ + echo ' + + + + 跳转提示 + + + + +
+
+
+ + + +
+
+
+

' . $msg . '

+

+ 确定 +

+
+
+
+ + +'; + exit(); +} + + +//短信开关 +function smsStatus($code) +{ + return Db::name('LcSms')->where(['code' => $code])->value('status'); +} + +/** + * @description:短信接口 + * @date: 2020/9/3 0003 + * @param $phone + * @param $code + * @param $msg + * @return array + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + * @throws \think\exception\PDOException + */ +function sendSms($phone, $code, $msg) +{ + if (smsStatus($code) == 0) { + return reSmsCode('001'); + } + $sms = Db::name('LcSms')->where(['code' => $code])->find(); + if (empty($sms)) { + return reSmsCode('002'); + } + $sms_code = $msg; + $sign = "【" . sysconf('yunpian_sign') . "】"; + $msg = str_replace('【', '[', $msg); + $msg = str_replace('】', ']', $msg); + $smsMsg = str_replace('###', $msg, $sign . $sms['msg']); + $sms_type = sysconf("sms_api_type"); + if ($sms_type == 1) $recode = yunpian($phone, $code, $smsMsg); + elseif ($sms_type == 2) $recode = wangJian($phone, $smsMsg); + else $recode = smsbao($phone, $smsMsg); + $data = array('phone' => $phone, 'msg' => $smsMsg, 'code' => $recode . '#' . reSmsCode($recode)['msg'], 'time' => date('Y-m-d H:i:s'), 'ip' => $sms_code); + Db::name('LcSmsList')->insert($data); + return reSmsCode($recode); +} + +/** + * @description:云片短信接口 + * @date: 2020/9/3 0003 + * @param $phone + * @param $code + * @param $smsMsg + * @return string + * @throws \think\Exception + * @throws \think\exception\PDOException + */ +function yunpian($phone, $code, $smsMsg) +{ + if ($code == '18001' || $code == '18004') { + $apikey = sysconf('yunpian_key');//注册、找回密码 + } else { + $apikey = sysconf('yunpian_tkey');//通知 + } + $url = 'https://sms.yunpian.com/v2/sms/single_send.json'; + $encoded_text = urlencode($smsMsg); + $mobile = urlencode($phone); + $post_string = 'apikey=' . $apikey . '&text=' . $encoded_text . '&mobile=' . $mobile; + $msg = vpost($url, $post_string); + $msg = json_decode($msg, true); + if ($msg['code'] == '0') { + $recode = '000'; + } else if (0 < $msg['code']) { + $recode = '004'; + } else { + if ($msg['code'] < 0 && -50 < $msg['code']) { + $recode = '005'; + } else if ($msg['code'] == -50) { + $recode = '006'; + } else { + $recode = '009'; + } + } + return $recode; +} + + +/** + * @description:网建通短信接口 + * @date: 2020/9/3 0003 + * @param $phone + * @param $smsMsg + * @return string + * @throws \think\Exception + * @throws \think\exception\PDOException + */ +function wangJian($phone, $smsMsg) +{ + $smsapi = "http://utf8.api.smschinese.cn/"; + $user = sysconf('wj_user'); + $key = sysconf('wj_key'); + $sendurl = $smsapi . "?Uid=" . $user . "&Key=" . $key . "&smsMob=" . $phone . "&smsText=" . $smsMsg; + $result = file_get_contents($sendurl); + if ($result > 0) return '000'; + return '009'; +} + +/** + * @description:短信宝 + * @date: 2020/9/3 0003 + * @param $phone + * @param $content + * @return string + * @throws \think\Exception + * @throws \think\exception\PDOException + */ +function smsBao($phone, $content) +{ + $smsapi = "http://api.smsbao.com/"; + $user = sysconf('smsbao_user'); + $pass = sysconf('smsbao_pass'); + $pass = md5("$pass"); + $sendurl = $smsapi . "sms?u=" . $user . "&p=" . $pass . "&m=" . $phone . "&c=" . urlencode($content); + $result = file_get_contents($sendurl); + if ($result == '0') return '000'; + return '009'; +} + +/** + * @description: + * @date: 2020/9/3 0003 + * @param $url + * @param $data + * @return mixed + */ +function vpost($url, $data) +{ + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($curl, CURLOPT_AUTOREFERER, 1); + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + curl_setopt($curl, CURLOPT_TIMEOUT, 30); + curl_setopt($curl, CURLOPT_HEADER, 0); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + $tmpInfo = curl_exec($curl); + if (curl_errno($curl)) { + echo 'Errno' . curl_error($curl); + } + curl_close($curl); + return $tmpInfo; +} + +function reSmsCode($code) +{ + $data = array('code' => $code, 'msg' => '未知'); + switch ($code) { + case '000': + $data['msg'] = '发送成功'; + break; + case '001': + $data['msg'] = '平台未启用短信通知'; + break; + case '002': + $data['msg'] = '平台未设置该模板'; + break; + case '003': + $data['msg'] = '平台未设置签名'; + break; + case '004': + $data['msg'] = '操作过于频繁'; + break; + case '005': + $data['msg'] = '短信权限不足'; + break; + case '006': + $data['msg'] = '短信接口调用失败'; + break; + case '007': + $data['msg'] = '管理员已关闭短信通知'; + break; + case '008': + $data['msg'] = '操作过于频繁,请一小时后再试'; + break; + default: + $data['code'] = '009'; + $data['msg'] = '未知错误'; + } + return $data; +} +function ChickIsOpen($id){ + $pro = Db::name('LcProduct')->where('id',$id)->find(); + $otime_arr = []; + $otime_arr[] = $pro['opentime_1']; + $otime_arr[] = $pro['opentime_2']; + $otime_arr[] = $pro['opentime_3']; + $otime_arr[] = $pro['opentime_4']; + $otime_arr[] = $pro['opentime_5']; + $otime_arr[] = $pro['opentime_6']; + $otime_arr[] = $pro['opentime_7']; + + //此时时间 + $_time = time(); + $_zhou = (int)date("w"); + if($_zhou == 0){ + $_zhou = 7; + } + $_shi = (int)date("H"); + $_fen = (int)date("i"); + + $isopen = 1; + foreach ($otime_arr as $k => $v) { + if($k == $_zhou-1){ + $_check = explode('|',$v); + if(!$_check){ + continue; + } + foreach ($_check as $key => $value) { + $_check_shi = explode('~',$value); + if(count($_check_shi) != 2){ + continue; + } + $_check_shi_1 = explode(':',$_check_shi[0]); + $_check_shi_2 = explode(':',$_check_shi[1]); + //开市时间在1与2之间 + if($isopen == 1){ + continue; + } + if( ($_check_shi_1[0] == $_shi && $_check_shi_1[1] < $_fen) || + ($_check_shi_1[0] < $_shi && $_check_shi_2[0] > $_shi) || + ($_check_shi_2[0] == $_shi && $_check_shi_2[1] > $_fen) + ){ + $isopen = 1; + }else{ + $isopen = 0; + } + } + } + } + if ($pro['isopen']) { + return $isopen; + + }else{ + return 0; + } +} + +//计算小数点后位数 +function getFloatLength($num) { + $count = 0; + + $temp = explode ( '.', $num ); + + if (sizeof ( $temp ) > 1) { + $decimal = end ( $temp ); + $count = strlen ( $decimal ); + } + + return $count; +} + +/** + * 自定义返回提示信息 + * @author lukui 2017-07-14 + * @param [type] $data [description] + * @param [type] $type [description] + */ +function WPreturn($data,$type,$url=null) +{ + + $res = array('data'=>$data,'type'=>$type); + + if($url){ + $res['url'] = $url; + } + return $res; +} \ No newline at end of file diff --git a/application/index/view/index/about.html b/application/index/view/index/about.html new file mode 100755 index 0000000..752b378 --- /dev/null +++ b/application/index/view/index/about.html @@ -0,0 +1,93 @@ +{include file="public/header1" nav="关于我们"} + + + + + + +
+
+ +
+
关于我们
+
+
+
+ + {volist name="abour_type" id="t"} + +
+ + {$t.name} + +
+
+ {/volist} + + +
+
+{include file="public/footer" menu="about"} + + \ No newline at end of file diff --git a/application/index/view/index/about_details.html b/application/index/view/index/about_details.html new file mode 100755 index 0000000..3da7c7d --- /dev/null +++ b/application/index/view/index/about_details.html @@ -0,0 +1,23 @@ +{include file="public/header" nav="$article.title"} + +
+
+
+
+
+ + {$article.title} +
+
+
+ {:htmlspecialchars_decode($article['content'])} +
+
+
+
+ {include file="public/footer"} +
+
+ + + diff --git a/application/index/view/index/about_list.html b/application/index/view/index/about_list.html new file mode 100755 index 0000000..dfe0d11 --- /dev/null +++ b/application/index/view/index/about_list.html @@ -0,0 +1,79 @@ +{include file="public/header1" nav="$type_name"} + + + + + + +
+
+
+ +
+
{$type_name}
+
+
+ {volist name="about" id="t"} + +
+ + {$t.title} + +
+
+ {/volist} +
+
+{include file="public/footer" menu=""} + + \ No newline at end of file diff --git a/application/index/view/index/calculator.html b/application/index/view/index/calculator.html new file mode 100755 index 0000000..52d1c2d --- /dev/null +++ b/application/index/view/index/calculator.html @@ -0,0 +1,323 @@ + + + + + 计算器 + + + + + + + +
+
+ +
收益计算器
+
+
+
+
+ + + +
+
+ + + +
+
+ + + % +
+
+ + +
+
+ + +
+
+
+
+ 重新计算 +
    +
      + +
      +
      +
      + + diff --git a/application/index/view/index/ex_lists.html b/application/index/view/index/ex_lists.html new file mode 100755 index 0000000..243c1a4 --- /dev/null +++ b/application/index/view/index/ex_lists.html @@ -0,0 +1,287 @@ +{include file="public/header" nav="我的矿产"} + + + + +
      +
      + +
      + 矿机
      +
      + +
      合约 +
      +
      +
      +
      + +
      +
      +
      + + 正常矿机 + + + 到期矿机 + + +
      +
      +
      +
      累计收益
      +
      + {:round($ljsy,8)} BTC
      + +
      收益明细
      +
      +
      +
      + 有效矿机:{$yxkj} +   到期矿机:{$dqkj} +
      +
      +
      +
      + {volist name="invest" id="i"} +
    • +
      + 已到期 +
      +
      + + {$i.title} +
      +
      +
        +
      • + 订单保证金 + {$i.money/$i.num}元 × {$i.num}份 +
      • +
      • + 净收益/天 + {$i.profit} × {$i.num}份 +
      • +
      • + 已收益 + {$i.profit*$i.num} +
      • +
      • + 售出方式 + {$i.type=='1'?'手动出售':'自动售出'} +
      • +
      • + 订单号 + {$i.number} +
      • +
      • + 到期时间 + {:date("Y-m-d",strtotime($i.time2))} +
      • +
      + +
      + 查看矿机租赁合同 +
      +
      +
      +
      + 展开更多 +
      +
    • + {/volist} +
      +
      +
      +{include file="public/footer" menu="list"} + + + diff --git a/application/index/view/index/expirefutures.html b/application/index/view/index/expirefutures.html new file mode 100755 index 0000000..d97a09e --- /dev/null +++ b/application/index/view/index/expirefutures.html @@ -0,0 +1,285 @@ +{include file="public/header" nav="我的合约"} + + + +
      +
      + +
      + 矿机
      +
      + +
      合约 +
      +
      +
      +
      +
      +
      + +
      +
      +
      累计收益
      +
      + {:round($ljsy,2)} 元
      + +
      收益明细
      +
      +
      +
      + 在期合约:{$yxkj} +   到期合约:{$dqkj} +
      +
      +
      +
      + {volist name="invest" id="i"} +
    • + +
      + + {$i.title} +
      +
      +
        +
      • + 合约金额 + {$i.money}元 +
      • +
      • + 净收益率 + {$i.rate}% +
      • +
      • + 已收益 + 0 +
      • +
      • + 合约天数 + {$i.day} +
      • +
      • + 订单号 + {$i.number} +
      • +
      • + 到期时间 + {:date("Y-m-d",strtotime($i.time2))} +
      • +
      + +
      + 查看矿机租赁合同 +
      +
      +
      +
      + 展开更多 +
      +
    • + {/volist} +
      +
      +
      +{include file="public/footer" menu="list"} + + + diff --git a/application/index/view/index/form.html b/application/index/view/index/form.html new file mode 100755 index 0000000..5b49dfe --- /dev/null +++ b/application/index/view/index/form.html @@ -0,0 +1,658 @@ +{include file="public/header1" nav="交易详情"} + + + +
      +
      +
      + +
      +
      交易详情
      +
      +
      +
      +
      + + + + +
      {$data['title']}
      +
      购买金额
      +
      + + +
      +
      最低起投{:round($data['min'],2)}元,加一次为100整数倍
      + +
      支付密码
      +
      + +
      +
      支付密码默认为登录密码
      + {if condition="$data['offvoucher'] eq 1 and $voushow eq 1"} +
      投资抵用券
      +
      + 请选择投资抵用券 + +
      +
      最多使用{$usevounum}张投资抵用券
      + {/if} +
      +
      +
      + 账户余额 + ¥{$user['money']} +
      +
      + 可购金额(元) + {:getProjectSurplus($data['id'])} +
      +
      + 日化收益率 + {:round($data['rate'],2)}% +
      +
      + 结息时间 + 满24小时自动发放收益 +
      +
      + 起投金额 + {:round($data['min'],2)}元 +
      + +
      +
      确认
      +
      +
      +
      + +
      + + + +
      +
      +

      温馨提示

      +

      +
      +
      确定
      +
      +
      +
      + + + + + diff --git a/application/index/view/index/futureslist.html b/application/index/view/index/futureslist.html new file mode 100755 index 0000000..eb1b360 --- /dev/null +++ b/application/index/view/index/futureslist.html @@ -0,0 +1,152 @@ +{include file="public/header" nav="算力合约"} + + + + +
      + 算力合约 + + +
      +
      +
      +
        + {volist name="item" id="i"} +
      • + +
        日化收益{:round($i['rate'],2)}%
        +
        + 投资周期 + {$i.day}天 +
        +
        + 收益方式 + {:getProjectType($i['type'])} +
        +
        + 起购金额 + {:round($i['min'],2)}元 +
        +
        + 本期份额 + {:round($i['total']*10000,2)}元 +
        +
        + 剩余份额 + {:getProjectSurplus($i['id'])}元 +
        +
        + 合约进度 + + + + {:round(getProjectPercent($i['id']),2)}% +
        +
      • + {/volist} +
      +
      +
      + + diff --git a/application/index/view/index/goods.html b/application/index/view/index/goods.html new file mode 100755 index 0000000..4f63341 --- /dev/null +++ b/application/index/view/index/goods.html @@ -0,0 +1,806 @@ +{include file="public/header" nav="-"} + + + + + + + + + + + +
      +
      + + + + + + +
      +
      +
      +
      {$info.Price}
      +
      + {$info.Open} + {$info.Close} +
      +
      +
      +
      最高{$info.High}
      +
      最低{$info.Low}
      +
      +
      + + +
      +
      +
      +
      Time:
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + + +
      + +

      买涨

      +
      +
      + +

      买跌

      +
      +
      + +
      +
      +
      +
      +
      + 订单确认 +
      + +
      +
      +
      +
      +
      +

      结算时间/赔率

      + +
      +
      + {if $info.protime_1 > 0 } +
      +
      + {$info.protime_1*300} + 秒|85% +
      + {if $info.showps==1 or $info.showps2==1} + {/if} +
      + {/if} + {if $info.protime_2 > 0 } +
      +
      + {$info.protime_2*30} + 秒|90% +
      + {if $info.showps==1 or $info.showps2==1} + {/if} +
      + {/if} + {if $info.protime_3 > 0 } +
      +
      + {$info.protime_3*30} + 秒|95% +
      + {if $info.showps==1 or $info.showps2==1} + {/if} +
      + {/if} + {if $info.protime_4 > 0 } +
      + + + +
      + {$info.protime_4*60} + +
      + {if $info.showps==1 or $info.showps2==1} + + {/if} +
      + {/if} +
      +
      +
      +
      +
      +
      +
      + + + +

      投资金额

      +
      + + + +
      +
      + + + + +
      +
      +
      +
      +
      +
      + +
      +
      +
      余额: ¥ {$user.money}
      +
      手续费:{:getinfo('order_charge')}%
      +
      +
      +
      +
      +
      + +
      +
      + +
      +
      名称
      +
      方向
      +
      现价
      +
      金额
      +
      +
      +
      {$info['title']}222
      +
      买涨
      +
      {$info['Price']}
      +
      + +
      +

      + 预期收益 : ¥ +    + 保底金额 : ¥ 0.00 +

      +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      +
      现价
      +
      {$info.Price}
      +
      +
      +
      +

      交易成功,等待结算

      +

      + 剩余时间: + 天Invalid Date +

      +
      +
      +
      +

      方向

      +

      +
      +
      +

      金额

      +

      +
      +
      +

      执行价

      +

      +
      +
      +

      预测结果

      +

      +
      +
      +
      +
      +
      +
      + + 请稍后…… +
      +
      +
      +
      +
      +
      + + 正在提交订单 +
      +
      +
      +
      +
      +
      + + +
      +
      +
      +
      +
      +
      +
      +
      到期结算完成
      +
      +
      +
      +
      +

      方向

      +

      +
      +
      +

      金额

      +

      +
      +
      +

      执行价

      +

      +
      +
      +

      成交价

      +

      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      + +
      +
      +
      + +
      +
        +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      + + {include file="public/footer" menu='goods'} +
      +
      + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/index/view/index/home.html b/application/index/view/index/home.html new file mode 100755 index 0000000..1b53c66 --- /dev/null +++ b/application/index/view/index/home.html @@ -0,0 +1,215 @@ +{include file="public/header" nav="首页"} + + +
      +
      +
      +
      + {volist name="banner" id="s"} +
      + {/volist} +
      +
      +
      + + + 涨幅榜 + +
      +
      +
      +
      + + + + + + + + {volist name="product" id="vo"} + + + + + + + {/volist} +
      LOGO名称最新价交易状态
      + + + {$vo['title']} + + + + +
      + + + + + + + + + + + + + + + + + +
      +
      +
      + {include file="public/footer" menu='index'} +
      + +
      {if $ater} +
      +
      + +
      + {$ater.title} +
      +
      + {$ater.content|raw} +
      + +
      +
      {/if} + + diff --git a/application/index/view/index/index.html b/application/index/view/index/index.html new file mode 100755 index 0000000..d4fa749 --- /dev/null +++ b/application/index/view/index/index.html @@ -0,0 +1,170 @@ + + + + + 线路选择 + + + + + + + + + + + +
      + +
      + +
      + +
      +
      + +
      + +
      + +
      +
      + +
      + + \ No newline at end of file diff --git a/application/index/view/index/item.html b/application/index/view/index/item.html new file mode 100755 index 0000000..09d422c --- /dev/null +++ b/application/index/view/index/item.html @@ -0,0 +1,243 @@ + + + + + + + + + 产品详情 + + + + + + + + + + +
      + 产品介绍 + + +
      +
      +
      +
      +
      +
      日化收益率
      +
      + {:round($data['rate'],2)}%
      +
      +
      +
      合约期限
      +
      + {$data.day} +
      +
      +
      + +
        +
      • +
        +
        + 本期总额(元) + {:round($data['total']*10000,2)} +
        +
        + 剩余份额(元) + {:getProjectSurplus($data['id'])} +
        +
        + 起购金额(元) + {:round($data['min'],2)} +
        +
        +
        + + 已售{:round(getProjectPercent($data['id']),2)}% + + + +
        +
      • +
      + +
      +
        +
      • +
        产品介绍
        +
        产品名称{$data.title}
        +
        + 合约算力 + {$data.hysl}Ghash +
        +
        + 收益方式 + {:getProjectType($data['type'])} +
        +
        + 产品亮点 + {$data.desc} +
        +
      • +
      +
      + +
      +
        +
      • +
        + + 产品详情 + +
        + {:htmlspecialchars_decode($data['fixedcontent'])} +
      • +
      +
      + +
      +
      + + +
      + 马上抢购
      +
      + + diff --git a/application/index/view/index/lists.html b/application/index/view/index/lists.html new file mode 100755 index 0000000..cc297eb --- /dev/null +++ b/application/index/view/index/lists.html @@ -0,0 +1,286 @@ +{include file="public/header" nav="我的矿产"} + + + +
      +
      + +
      + 矿机
      +
      + +
      合约 +
      +
      +
      +
      +
      +
      +
      + + 正常矿机 + + + + 到期矿机 + +
      +
      +
      +
      累计收益
      +
      + {:round($ljsy,8)} BTC
      + +
      收益明细
      +
      +
      +
      + 有效矿机:{$yxkj} +   到期矿机:{$dqkj} +
      +
      +
      +
      + {volist name="invest" id="i"} +
    • +
      + 运行中 +
      +
      + + {$i.title} +
      +
      +
        +
      • + 订单保证金 + {$i.money/$i.num}元 × {$i.num}份 +
      • +
      • + 净收益/天 + {$i.profit} × {$i.num}份 +
      • +
      • + 已收益 + 0.00000000 +
      • +
      • + 售出方式 + {$i.type=='1'?'手动出售':'自动售出'} +
      • +
      • + 订单号 + {$i.number} +
      • +
      • + 到期时间 + {:date("Y-m-d",strtotime($i.time2))} +
      • +
      + +
      + 查看矿机租赁合同 +
      +
      +
      +
      + 展开更多 +
      +
    • + {/volist} +
      +
      +
      +{include file="public/footer" menu="list"} + + + diff --git a/application/index/view/index/mall.html b/application/index/view/index/mall.html new file mode 100755 index 0000000..d1dab64 --- /dev/null +++ b/application/index/view/index/mall.html @@ -0,0 +1,226 @@ + + + + + + + + + 矿机商城 + + + + + + + + +
      + 矿机商城 + + +
      +
      +
      +
      +
      +
      + {volist name="mall" id="i"} +
    • +
      + + + + +
      +
      + +
      {$i.title}
      +
      +
      + 净收益/天:{:getProfit($i.day_income,$i.cost)} BTC +
      +
      + 使用期限:{$i.day} 天 +
      +
      + + 保证金: + {$i.min} + +
      + 支付 +
      +
      + +
      +
      +
      +
      + + {:getMinerPercent($i.total,$i.stock)}% +
      + 仅剩{$i.stock}份 +
      +
      +
    • + {/volist} +
      +
      +
      +
      +
      + + diff --git a/application/index/view/index/mall_detail.html b/application/index/view/index/mall_detail.html new file mode 100755 index 0000000..72b6dcc --- /dev/null +++ b/application/index/view/index/mall_detail.html @@ -0,0 +1,271 @@ + + + + + + + + + 矿机详情 + + + + + + + + + + +
      + {$data.title} + + +
      +
      +
      + +
      +
      + + 规格参数 + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      规格 + 参数
      使用期限{$data.day} 天
      保证金{$data.min} 元/份
      算力{$data.power} TH/s
      日总产出{$data.day_income} BTC/天
      日运维费{$data.cost} BTC/天
      日净收益{:getProfit($data.day_income,$data.cost)} BTC/天
      日化收益率{$data.rate}
      上架时间{$data.time}
      +
      + +
      +
        +
      • +
        + + 产品详情 + +
        + {:htmlspecialchars_decode($data['fixedcontent'])} +
      • +
      +
      +
      +
      + + +
      + 马上抢购
      +
      + + diff --git a/application/index/view/index/mall_form.html b/application/index/view/index/mall_form.html new file mode 100755 index 0000000..5244f10 --- /dev/null +++ b/application/index/view/index/mall_form.html @@ -0,0 +1,516 @@ + + + + + + + + + 交易详情 + + + + + + + + + +
      + 交易详情 + + +
      +
      +
      +
      +
      + 保证金(元) + {$data.min} +
      +
      + 租赁期限(天) + {$data.day} +
      +
      +
      + + {$data.title} + 本批剩余{$data.stock}份 +
      + +
        +
      • + 收益方式 + 每日分配收益,保证金到期全额返还 +
      • +
      • + 日净收益 + {:getProfit($data.day_income,$data.cost)} BTC +
      • +
      • + 总净收益 + {:round(getProfit($data.day_income,$data.cost)*$data.day,8)} BTC +
      • +
      • + 总保证金 + ¥{$data.min} +
      • +
      • + BTC售出方式 + + + + +
      • +
      • + 租赁份数 + +
      • +
      • + 每次加减1份,可自行输入份数 +
      • +
      + +
      + 实付:¥{$data.min} + 确认支付 +
      +
      +
      +
      +
      +
      请输入支付密码 +
      ×
      +
      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      +
      安全支付环境,请放心使用
      +
        +
        + +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + diff --git a/application/index/view/index/msg_view.html b/application/index/view/index/msg_view.html new file mode 100644 index 0000000..b0358c8 --- /dev/null +++ b/application/index/view/index/msg_view.html @@ -0,0 +1,25 @@ +{include file="public/header" nav="消息详情"} + +
        +
        +
        +
        +
        + + {$msg.title} +
        +
        + +
        + {:htmlspecialchars_decode($msg['content'])} +
        +
        +
        +
        + {include file="public/footer" menu='index'} +
        +
        + + + + diff --git a/application/index/view/index/my_news.html b/application/index/view/index/my_news.html new file mode 100755 index 0000000..661a5cb --- /dev/null +++ b/application/index/view/index/my_news.html @@ -0,0 +1,124 @@ + + + + + + + 新闻 + + + + + + + + + + +
        +
        + +
        + {include file="public/footer" menu='news'} +
        + + + + + + + \ No newline at end of file diff --git a/application/index/view/index/new_index.html b/application/index/view/index/new_index.html new file mode 100755 index 0000000..262d6a1 --- /dev/null +++ b/application/index/view/index/new_index.html @@ -0,0 +1,87 @@ + + + + + + 新闻 + + + + + + + + + +
        +
        + +
        + + +
        + + {if getInfo("activity1_status")} +
        +
        +
        + 关闭 + +
        +
        +
        +
        + {/if} + + + + + diff --git a/application/index/view/index/normalfutures.html b/application/index/view/index/normalfutures.html new file mode 100755 index 0000000..2bf53eb --- /dev/null +++ b/application/index/view/index/normalfutures.html @@ -0,0 +1,286 @@ +{include file="public/header" nav="我的合约"} + + + +
        +
        + +
        + 矿机
        +
        + +
        合约 +
        +
        +
        +
        +
        +
        +
        + + 在期合约 + + + + 到期合约 + +
        +
        +
        +
        累计收益
        +
        + {:round($ljsy,2)} 元
        + +
        收益明细
        +
        +
        +
        + 在期合约:{$yxkj} +   到期合约:{$dqkj} +
        +
        +
        +
        + {volist name="invest" id="i"} +
      • + +
        + + {$i.title} +
        +
        +
          +
        • + 合约金额 + {$i.money}元 +
        • +
        • + 净收益率 + {$i.rate}% +
        • +
        • + 已收益 + 0 +
        • +
        • + 合约天数 + {$i.day} +
        • +
        • + 订单号 + {$i.number} +
        • +
        • + 到期时间 + {:date("Y-m-d",strtotime($i.time2))} +
        • +
        + +
        + 查看矿机租赁合同 +
        +
        +
        +
        + 展开更多 +
        +
      • + {/volist} +
        +
        +
        +{include file="public/footer" menu="list"} + + + diff --git a/application/index/view/index/notice.html b/application/index/view/index/notice.html new file mode 100755 index 0000000..300f6c2 --- /dev/null +++ b/application/index/view/index/notice.html @@ -0,0 +1,36 @@ +{include file="public/header" nav="最新公告"} + +
        +
        +
        +
        +
        + + 最新公告 +
        +
        + {if count($notice)} + + {else/} +
        +

        没有更多数据了

        +
        + {/if} +
        +
        +
        + {include file="public/footer"} +
        +
        + + + diff --git a/application/index/view/index/prize.html b/application/index/view/index/prize.html new file mode 100755 index 0000000..63413b0 --- /dev/null +++ b/application/index/view/index/prize.html @@ -0,0 +1,131 @@ + + + + + + + 大转盘 + + + + + + + + + + +
        + + + + + +
        + +
        + +
        + +
        +
        + + + + +
        + {volist name="prize_list" id="vo"} +
        + {$vo.msg} +
        + {/volist} + + +
        + + +
        + {:htmlspecialchars_decode($data['rule'])} +
        +
        + + +
        +
        +
        + + 中奖啦
        +
        +
        关闭
        +
        +
        + + +
        +
        +
        + 很遗憾
        没有抽中礼品 +
        +
        关闭
        +
        +
        + + + + + + + + + + \ No newline at end of file diff --git a/application/index/view/index/prize_list.html b/application/index/view/index/prize_list.html new file mode 100755 index 0000000..bbde5d4 --- /dev/null +++ b/application/index/view/index/prize_list.html @@ -0,0 +1,108 @@ + + + + + + + + 抽奖记录 + + + + + + + +
        + + +
        + + + + + + + + + + {volist name="prize" id="p"} + + + + + + {/volist} + +
        奖品类型日期
        {$p.name} + {if condition="$p['type'] eq 1"} + 现金 + {else/} + 实物 + {/if} + {:date('m-d H:i',strtotime($p['time']))}
        +
        +
        +
        + + \ No newline at end of file diff --git a/application/index/view/index/shop.html b/application/index/view/index/shop.html new file mode 100755 index 0000000..024b87b --- /dev/null +++ b/application/index/view/index/shop.html @@ -0,0 +1,68 @@ +{include file="public/header" nav="积分商城"} + + + + \ No newline at end of file diff --git a/application/index/view/index/shop_details.html b/application/index/view/index/shop_details.html new file mode 100755 index 0000000..746e188 --- /dev/null +++ b/application/index/view/index/shop_details.html @@ -0,0 +1,143 @@ +{include file="public/header" nav="商品详情"} + +
        +
        + + + +
        商品详情
        +
        +
        +
        +
        + +
        +
        + [{if condition="$goods['type'] eq 1"}现金{else/}实物{/if}] {$goods.title} +
        +
        +
        + 需{$goods.integral}积分 +
        +
        + 剩{$goods.num}份 +
        +
        +
        +
        +
        +
        + 您有{$count}积分 +
        +
        + +
        +
        +
        +
        +
        商品详情
        +
        + {:htmlspecialchars_decode($goods['content'])} +
        +
        +
        + © {:getInfo('webname')} +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + \ No newline at end of file diff --git a/application/index/view/index/shop_order.html b/application/index/view/index/shop_order.html new file mode 100755 index 0000000..9fa385c --- /dev/null +++ b/application/index/view/index/shop_order.html @@ -0,0 +1,37 @@ +{include file="public/header" nav="兑换记录"} + + + \ No newline at end of file diff --git a/application/index/view/login/index.html b/application/index/view/login/index.html new file mode 100755 index 0000000..a333954 --- /dev/null +++ b/application/index/view/login/index.html @@ -0,0 +1,110 @@ + + + + + + + + + + + 会员登录 + + + + + + +
        +
        + +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + + diff --git a/application/index/view/login/reg.html b/application/index/view/login/reg.html new file mode 100755 index 0000000..79f225d --- /dev/null +++ b/application/index/view/login/reg.html @@ -0,0 +1,192 @@ + + + + + + + + + + +会员注册 + + + + + + + +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + + diff --git a/application/index/view/public/footer.html b/application/index/view/public/footer.html new file mode 100755 index 0000000..6f6e05a --- /dev/null +++ b/application/index/view/public/footer.html @@ -0,0 +1,38 @@ + + + + + \ No newline at end of file diff --git a/application/index/view/public/header.html b/application/index/view/public/header.html new file mode 100755 index 0000000..323ad88 --- /dev/null +++ b/application/index/view/public/header.html @@ -0,0 +1,20 @@ + + + + + + + + + + + [nav] + + + + + \ No newline at end of file diff --git a/application/index/view/public/header1.html b/application/index/view/public/header1.html new file mode 100755 index 0000000..083f999 --- /dev/null +++ b/application/index/view/public/header1.html @@ -0,0 +1,9 @@ + + + + + + [nav] + + + diff --git a/application/index/view/user/account.html b/application/index/view/user/account.html new file mode 100755 index 0000000..c295f43 --- /dev/null +++ b/application/index/view/user/account.html @@ -0,0 +1,231 @@ +{include file="public/header" nav="我的"} + + + + + + + + +
        +
        +
        + +
        + + + + + + + +
        +
        +

        持仓明细(0)

        +
        +
        +

        历史明细(0)

        +
        +
        +
        +
        + + + + + + + + + + +
          +
        +
        + +
          +
        +
        +
        +
        + +
        + + + + + + +
        +
        + +
        +
        + {include file="public/footer" menu='account'} +
        +
        +
        + + + + + + diff --git a/application/index/view/user/add_card.html b/application/index/view/user/add_card.html new file mode 100755 index 0000000..27a2895 --- /dev/null +++ b/application/index/view/user/add_card.html @@ -0,0 +1,100 @@ +{include file="public/header" nav="添加银行卡"} + + +
        +
        +
        +
        +
        + + 添加银行卡 +
        +
        +
          +
        • + + +
        • + {if condition="getInfo('bank') eq 0"} +
        • + + +
        • +
        • + + +
        • + {else/} + + + {/if} +
        • + + +
        • +
        +
        + +
        +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + diff --git a/application/index/view/user/alipay.html b/application/index/view/user/alipay.html new file mode 100755 index 0000000..d7ba6d5 --- /dev/null +++ b/application/index/view/user/alipay.html @@ -0,0 +1,125 @@ +{include file="public/header1" nav="支付宝设置"} + + + +
        + + + +
        支付宝设置
        +
        +
        +
        +
        +
        真实姓名
        +
        +
        +
        +
        支付宝账号
        +
        +
        +

        绑定的支付宝必须与实名一致,否则将无法成功提现

        + {if condition="empty($user['alipay'])"} +
        确认
        + {/if} +
        +
        + + + + + diff --git a/application/index/view/user/bank.html b/application/index/view/user/bank.html new file mode 100755 index 0000000..39d25db --- /dev/null +++ b/application/index/view/user/bank.html @@ -0,0 +1,564 @@ + + + + + + 银行入款充值 + + + +
        +
        +
        + +
        +
        银行入款充值
        +
        +
        +
        +
        +
        + +
        +
        银行入款
        +
        {$money}元
        + +
        +
        + 此为我公司财务,请放心充值 +
        +
        +
        收款银行:
        +
        + {if condition="$type eq 'gz_bank'"} + {:getInfo('gz_bank_type')} + {/if} + {if condition="$type eq 'alipay_bank'"} + {:getInfo('alipay_bank_type')} + {/if} + {if condition="$type eq 'wx_bank'"} + {:getInfo('wx_bank_type')} + {/if} + {if condition="$type eq 'bank'"} + {:getInfo('pay_bank_type')} + {/if} +
        +
        +
        +
        收款人:
        +
        + {if condition="$type eq 'gz_bank'"} + {:getInfo('gz_bank_name')} + {/if} + {if condition="$type eq 'wx_bank'"} + {:getInfo('wx_bank_name')} + {/if} + {if condition="$type eq 'alipay_bank'"} + {:getInfo('alipay_bank_name')} + {/if} + {if condition="$type eq 'bank'"} + {:getInfo('pay_bank_name')} + {/if} +
        +
        +
        +
        收款账号:
        +
        + {if condition="$type eq 'gz_bank'"} + {:getInfo('gz_bank_account')} + {/if} + {if condition="$type eq 'wx_bank'"} + {:getInfo('wx_bank_account')} + {/if} + {if condition="$type eq 'alipay_bank'"} + {:getInfo('alipay_bank_account')} + {/if} + {if condition="$type eq 'bank'"} + {:getInfo('pay_bank_account')} + {/if} +
        +
        +
        +
        + +
        +
        +
        付款人:
        +
        +
        +
        +
        转账附言:
        +
        +
        +
        +
        提交
        +
        +
        +
        +
        注意事项
        +
        + {if condition="$type eq 'gz_bank'"} + {:getInfo('gz_bank')} + {/if} + {if condition="$type eq 'wx_bank'"} + {:getInfo('wx_bank')} + {/if} + {if condition="$type eq 'alipay_bank'"} + {:getInfo('alipay_bank')} + {/if} + {if condition="$type eq 'bank'"} + {:getInfo('pay_bank')} + {/if} +
        +
        +
        +
        + +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + + + diff --git a/application/index/view/user/bank_card.html b/application/index/view/user/bank_card.html new file mode 100755 index 0000000..b3b01af --- /dev/null +++ b/application/index/view/user/bank_card.html @@ -0,0 +1,44 @@ +{include file="public/header" nav="银行卡管理"} + +
        +
        +
        +
        +
        + + 银行卡管理 +
        +
        + {if condition="$bank"} + {volist name="bank" id="b"} +
          +
        • + + {$b.bank} ****{:substr($b['account'], strlen($b['account']) - 4, 4)} + {$b.name} + +
        • +
        + {/volist} + + + {else} + {/if} +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        + + + \ No newline at end of file diff --git a/application/index/view/user/cash.html b/application/index/view/user/cash.html new file mode 100755 index 0000000..c293039 --- /dev/null +++ b/application/index/view/user/cash.html @@ -0,0 +1,156 @@ +{include file="public/header" nav="提现"} + + + +
        +
        +
        +
        +
        + + 提现 +
        +
        +
        +
        可提现金额(元)
        +
        + + {$user['money']} +
        +
        +
        +
        提现金额
        +
        + + + {$txsxf?$txsxf:'0'}% +
        +
        单次提现金额最低 {$cash_min?$cash_min:'0'}元
        +
        + + +
        + + +
        +
        + +
        + {if $bank} + + {else} +

        绑定银行卡 +

        + {/if} +
        +
        + {if $bank} +
        + +
        + {else} +
        + +
        + {/if} + +

        提示:

        +

        1.提现限制:{$cash_min} - {$cash_max}

        +

        2.提现时间:{$cash_start} - {$cash_end}

        +

        3.若忘记提款密码,请点击找回

        +
        + +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + + + diff --git a/application/index/view/user/cash_record.html b/application/index/view/user/cash_record.html new file mode 100755 index 0000000..1731750 --- /dev/null +++ b/application/index/view/user/cash_record.html @@ -0,0 +1,71 @@ +{include file="public/header" nav="提现记录"} + + +
        +
        +
        +
        +
        + + 提现记录 +
        +
        + {if count($cash) > 0} + {volist name="cash" id="r"} +
          +
        • + 时间: +

          {$r.time}

          +
        • +
        • + 金额: +

          ¥{$r.money}

          +
        • +
        • + 手续费: +

          {$r.sxfbfb}%

          +
        • +
        • + 实际到账: +

          ¥{$r.dzje}

          +
        • +
        • + 类型: +

          {if condition="$r['bid'] eq 0"}支付宝提现{else}银行卡提现{/if}

          +
        • +
        • + 状态: +

          + {if condition="$r['status'] eq 0"} + 审核中 + {/if} + {if condition="$r['status'] eq 1"} + 申请成功 + {/if} + {if condition="$r['status'] eq 2"} + 申请失败 + {/if} +

          +
        • + {if condition="$r['reaolae'] "} +
        • + 拒绝原因: +

          {$r.reaolae}

          +
        • + {/if} +
        + {/volist} + {else/} +
        +

        没有更多数据了

        +
        + {/if} +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        + + + diff --git a/application/index/view/user/certification.html b/application/index/view/user/certification.html new file mode 100755 index 0000000..473669f --- /dev/null +++ b/application/index/view/user/certification.html @@ -0,0 +1,103 @@ +{include file="public/header" nav="实名认证"} + + +
        +
        +
        +
        +
        + + 实名认证 +
        +
        + {if condition="$user['auth'] eq 1"} +
        +

        +
        +
          +
        • + + {$user.name} +
        • +
        • + + {$user.idcard} +
        • +
        + {else /} +
          +
        • + + +
        • +
        • + + +
        • +
        + +
        + +
        + {/if} +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + diff --git a/application/index/view/user/contract.html b/application/index/view/user/contract.html new file mode 100755 index 0000000..fd7b346 --- /dev/null +++ b/application/index/view/user/contract.html @@ -0,0 +1,80 @@ +{include file="public/header" nav="合同"} +
        +
        + + + +
        合同书
        +
        +
        + +
        +

        {:getInfo('webname')}投资合同书

        +

        合同编号:{$invest['number']}

        +

        :{:getUserField($uid,'name')}

        +

        :{:getInfo('company')}

        +

        :{:getItemField($invest['pid'],'guarantee')}

        +

        甲乙丙双方经友好协商,本着平等自愿、诚实信用的原则,就甲方使用乙方提供的本网站所有服务的

        +

        +

        一、

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        产品名称{$invest.title}
        投资人姓名{:getUserField($uid,'name')}
        投资人身份证{:getUserField($uid,'idcard')}
        投入本金数额
        (下称"甲方投资本金")
        {$invest.money}元
        协议期(天){$invest.day}天
        预期收益率{$invest.rate}%
        起息日{:date('Y-m-d',strtotime($invest['time']))}
        到期日{:date('Y-m-d',strtotime('+'.$invest['day'].' day',strtotime($invest['time'])))}
        应收本息(元){:getInvestMoney($invest['id'])+$invest['money']}元
        还款方式{$invest.type2}
        + {:htmlspecialchars_decode(getInfo('contract'))} +
        +
        +

        甲方:{:getUserField($uid,'name')}

        + {:date('Y年m月d日',strtotime($invest['time']))} +
        +
        +

        乙方:{:getInfo('company')}

        + {:date('Y年m月d日',strtotime($invest['time']))} +
        +
        +
        +

        丙方:{:getItemField($invest['pid'],'guarantee')}

        + {:date('Y年m月d日',strtotime($invest['time']))} +
        +
        +
        + + \ No newline at end of file diff --git a/application/index/view/user/details.html b/application/index/view/user/details.html new file mode 100755 index 0000000..b27c1fb --- /dev/null +++ b/application/index/view/user/details.html @@ -0,0 +1,55 @@ +{include file="public/header" nav="投资详情"} +
        +
        + + + +
        投资详情
        +
        +
        +
        +
        + 投资金额:{$invest.money}元 + 预期效益:{:getInvestMoney($invest['id'])}元
        + 投资时间:{:date('Y-m-d',strtotime($invest['time']))} + 到期时间:{:date('Y-m-d',strtotime('+'.$invest['day'].' day',strtotime($invest['time'])))}
        + 收益方式:{$invest.type2} +
        +
        + + + + + + + + + + + + {volist name="list" id="l"} + + + + + + + + + + + {/volist} +
        期号应收本金应收利息应收时间收益时间应收总额已支付状态
        第{$l.num}期{$l.money2}{$l.money1}{$l.time1} + + {$l.pay1}{$l.pay2} + {if condition="$l['status'] eq 1"} + 已完成 + {else/} + 未完成 + {/if} +
        +
        +
        +
        + + \ No newline at end of file diff --git a/application/index/view/user/extend.html b/application/index/view/user/extend.html new file mode 100755 index 0000000..98b9f2a --- /dev/null +++ b/application/index/view/user/extend.html @@ -0,0 +1,182 @@ +{include file="public/header1" nav="推广记录"} + + + + +
        +
        + +
        +
        推广记录
        +
        + {volist name="results" id="r"} +
        +
        +
        +

        {$r.name|default='未实名'}({$r.phone})

        +
        +

        注册日期:{:date('Y-m-d',strtotime($r['time']))}

        +
        +
        +

        + 充值金额:{$r.recharge} 元 +

        +

        + 提现金额:{$r.cash} 元 +

        +
        +
        + {/volist} +
        暂无更多记录
        + + + + diff --git a/application/index/view/user/fund.html b/application/index/view/user/fund.html new file mode 100755 index 0000000..301088e --- /dev/null +++ b/application/index/view/user/fund.html @@ -0,0 +1,43 @@ +{include file="public/header" nav="资金明细"} + +
        +
        +
        +
        +
        + + 资金明细 +
        +
        + {if count($finance) > 0} + {volist name="finance" id="f"} +
          +
        • + 时间: +

          {$f['time']}

          +
        • +
        • + 备注: +

          {$f.reason}

          +
        • +
        • + 金额: +

          {if condition="$f['type'] eq 1"}+{else /}-{/if}{$f.money}

          +
        • +
        + {/volist} + {else/} +
        +

        没有更多数据了

        +
        + {/if} +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        + + + + diff --git a/application/index/view/user/hold.html b/application/index/view/user/hold.html new file mode 100755 index 0000000..ac011ae --- /dev/null +++ b/application/index/view/user/hold.html @@ -0,0 +1,166 @@ +{include file="public/header" nav="历史委托"} + + + + + + + + + + +
        +
        + + + + + + + + + +
        +
        +

        持仓明细

        +
        +
        +

        历史明细

        +
        +
        +
        +
        + +
          +
        +
        + +
          +
        +
        +
        + +
        +
        +
        +
        +
        +
        + +
        +
        + +
        + {include file="public/footer" menu='hold'} +
        +
        + + + + + + \ No newline at end of file diff --git a/application/index/view/user/index.html b/application/index/view/user/index.html new file mode 100755 index 0000000..53782cc --- /dev/null +++ b/application/index/view/user/index.html @@ -0,0 +1,193 @@ +{include file="public/header" nav="我的"} + +
        +
        +
        +
        + + + + +
        +
        +
        +
        + +
        + +
        + 我的信用积分 +
        +
        + /100 +
        +
        + + + + + + + + + + + + + + + + + + + + +
        +
        +
        +
        +
        + +
        +
        + +
        +
        + +
        +
        +
        +
        + + +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        +
        + + + diff --git a/application/index/view/user/inquiries.html b/application/index/view/user/inquiries.html new file mode 100755 index 0000000..4198b4f --- /dev/null +++ b/application/index/view/user/inquiries.html @@ -0,0 +1,45 @@ +{include file="public/header" nav="平仓查询"} + +
        +
        +
        +
        +
        + 平仓查询 +
        +
          +
        • 商品名称
        • +
        • 金额
        • +
        • 方向
        • +
        • 盈亏
        • +
        +
        + {if count($list)} +
        + {volist name="list" id="vo"} +
        +
        +
        + + {$vo.ptitle} + ¥{$vo.fee} + {$vo['ostyle']==0?'买涨':'买跌'} + {$vo.ploss} +
        +
        +
        + {/volist} +
        + {else/} +
        +

        没有更多数据了

        +
        + {/if} +
        +
        +
        + {include file="public/footer"} +
        +
        + + diff --git a/application/index/view/user/interest.html b/application/index/view/user/interest.html new file mode 100755 index 0000000..33a3cdc --- /dev/null +++ b/application/index/view/user/interest.html @@ -0,0 +1,185 @@ +{include file="public/header1" nav="收益记录"} + + + + +
        +
        + +
        +
        收益记录
        +
        + {volist name="interest" id="f"} +
        +
        +
        +

        第{$f.num}期 {$f.title}

        +
        +
        +

        + 已完成 +

        +
        +
        +
        +
        +

        金额:

        +

        {$f.pay2}元

        +
        +

        {:$f['time2']}

        +
        +
        + {/volist} +
        暂无更多记录
        + + + + diff --git a/application/index/view/user/invest.html b/application/index/view/user/invest.html new file mode 100755 index 0000000..bf87059 --- /dev/null +++ b/application/index/view/user/invest.html @@ -0,0 +1,185 @@ +{include file="public/header1" nav="投资记录"} + + + + +
        +
        + +
        +
        投资记录
        +
        +{volist name="invest" id="f"} +
        +
        +
        +

        {$f.title}

        +
        + +
        +
        +
        +

        金额:

        +

        {$f.money}元{:getInvestStatus($f['id'])}

        +
        +

        {:$f['time']}

        +
        +
        +{/volist} +
        暂无更多记录
        + + + + diff --git a/application/index/view/user/mall_contract.html b/application/index/view/user/mall_contract.html new file mode 100755 index 0000000..30dd3e1 --- /dev/null +++ b/application/index/view/user/mall_contract.html @@ -0,0 +1,88 @@ +{include file="public/header" nav="合同"} +
        +
        + + + +
        合同书
        +
        +
        + +
        +

        {:getInfo('webname')}投资合同书

        +

        合同编号:{$invest['number']}

        +

        :{:getUserField($uid,'name')}

        +

        :{:getInfo('company')}

        +

        :{:getMallItemField($invest['pid'],'guarantee')}

        +

        根据中华人民共和国有关法律、法规规定,本着平等、自愿、公平、互惠互利和诚实守信的原则,就乙方使用甲方平台提供的矿机租赁服务的有关事项达成如下协议:

        +

        一、

        +

        1.矿机租赁明细

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        矿机名称{$invest.title}
        租赁人姓名{:getUserField($uid,'name')}
        租赁人身份证{:getUserField($uid,'idcard')}
        租赁份数{$invest.num}
        租赁单份保证金{$invest.money/$invest.num}元
        租赁总保证金{$invest.money}元
        租赁期限{$invest.day}天
        租赁人日净收益{$invest.profit}
        租赁人总净收益{$invest.profit*$invest.day}
        矿机上线日期{:date('Y-m-d',strtotime($invest['time']))}
        矿机到期日期{:date('Y-m-d',strtotime('+'.$invest['day'].' day',strtotime($invest['time'])))}
        还款方式每日分配收益,保证金到期全额返还
        + {:htmlspecialchars_decode(getInfo('contract_kj'))} +
        +
        +

        甲方:{:getUserField($uid,'name')}

        + {:date('Y年m月d日',strtotime($invest['time']))} +
        +
        +

        乙方:{:getInfo('company')}

        + {:date('Y年m月d日',strtotime($invest['time']))} +
        +
        +
        +

        丙方:{:getMallItemField($invest['pid'],'guarantee')}

        + {:date('Y年m月d日',strtotime($invest['time']))} +
        +
        +
        + + diff --git a/application/index/view/user/msg.html b/application/index/view/user/msg.html new file mode 100755 index 0000000..5859053 --- /dev/null +++ b/application/index/view/user/msg.html @@ -0,0 +1,48 @@ +{include file="public/header" nav="站内信"} + +
        +
        +
        +
        +
        + + 站内信 +
        +
        + {if count($msgtop) > 0 || count($msgfoot) > 0 } + {volist name="msgtop" id="m"} + + {/volist} + {volist name="msgfoot" id="m"} + + {/volist} + {else/} +
        +

        没有更多数据了

        +
        + {/if} +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        + + + \ No newline at end of file diff --git a/application/index/view/user/msg_view.html b/application/index/view/user/msg_view.html new file mode 100755 index 0000000..8d7b27b --- /dev/null +++ b/application/index/view/user/msg_view.html @@ -0,0 +1,25 @@ +{include file="public/header" nav="消息详情"} + +
        +
        +
        +
        +
        + + {$msg.title} +
        +
        + +
        + {:htmlspecialchars_decode($msg['content'])} +
        +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        + + + + diff --git a/application/index/view/user/pwd_login.html b/application/index/view/user/pwd_login.html new file mode 100755 index 0000000..8d8f548 --- /dev/null +++ b/application/index/view/user/pwd_login.html @@ -0,0 +1,98 @@ +{include file="public/header" nav="设置密码"} + + +
        +
        +
        +
        +
        + + 修改登录密码 +
        +
        +
          +
        • + + +
        • +
        • + + +
        • +
        • + + +
        • +
        +
        + +
        +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + diff --git a/application/index/view/user/pwd_pay.html b/application/index/view/user/pwd_pay.html new file mode 100755 index 0000000..347719f --- /dev/null +++ b/application/index/view/user/pwd_pay.html @@ -0,0 +1,98 @@ +{include file="public/header" nav="设置密码"} + + +
        +
        +
        +
        +
        + + 修改支付密码 +
        +
        +
          +
        • + + +
        • +
        • + + +
        • +
        • + + +
        • +
        +
        + +
        +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + diff --git a/application/index/view/user/recharge.html b/application/index/view/user/recharge.html new file mode 100755 index 0000000..3c07189 --- /dev/null +++ b/application/index/view/user/recharge.html @@ -0,0 +1,146 @@ +{include file="public/header" nav="充值"} + + +
        +
        +
        +
        +
        + + 充值 +
        +
        +
        + +
        +
        +
          +
        • + 开户银行:{:getInfo('pay_bank_type')} +
        • +
        • + 开户网点:{:getInfo('pay_bank_type')} +
        • +
        • + 收款账号:

          {:getInfo('pay_bank_account')}

          +
        • +
        • + 收款姓名:

          {:getInfo('pay_bank_name')}

          +
        • +
        +
        +
        + +
        +
        +
          +
        • 充值金额: 
        • +
        • 存款姓名: 
        • +
        • 转账附言: 
        • +
        +
        +
        + +
        +
        +
        +
        + +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + + diff --git a/application/index/view/user/recharge_record.html b/application/index/view/user/recharge_record.html new file mode 100755 index 0000000..d5b49ab --- /dev/null +++ b/application/index/view/user/recharge_record.html @@ -0,0 +1,65 @@ +{include file="public/header" nav="充值记录"} + + +
        +
        +
        +
        +
        + + 充值记录 +
        +
        + {if count($recharge) > 0} + {volist name="recharge" id="r"} +
          +
        • + 时间: +

          {$r.time}

          +
        • +
        • + 金额: +

          ¥{$r.money}

          +
        • +
        • + 类型: +

          {$r.type}

          +
        • +
        • + 状态: +

          + {if condition="$r['status'] eq 0"} + 审核中 + {/if} + {if condition="$r['status'] eq 1"} + 申请成功 + {/if} + {if condition="$r['status'] eq 2"} + 申请失败 + {/if} +

          +
        • + {if condition="$r['reaolae'] "} +
        • + 拒绝原因: +

          {$r.reaolae}

          +
        • + {/if} +
        + {/volist} + {else/} +
        +

        没有更多数据了

        +
        + {/if} +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        + + + + + diff --git a/application/index/view/user/recommend.html b/application/index/view/user/recommend.html new file mode 100755 index 0000000..9b3da5a --- /dev/null +++ b/application/index/view/user/recommend.html @@ -0,0 +1,227 @@ +{include file="public/header1" nav="邀请朋友"} + + + +
        +
        +
        + +
        +
        +
        + +
        +
        +

        好友扫描二维码可直接注册

        + +
        您的邀请ID: {$user.phone}
        +
        +
        +
        +
        我的邀请奖励
        + +
        +
        +
        邀请规则
        +
        +

        1.本活动永久有效,欢迎参与

        + +

        2.推荐名额可累计计算

        + +

        3.满足条件后,请联系在线客服申请奖励

        + +
        +
        +
        +
        + + + + + + diff --git a/application/index/view/user/scan.html b/application/index/view/user/scan.html new file mode 100755 index 0000000..fafc754 --- /dev/null +++ b/application/index/view/user/scan.html @@ -0,0 +1,42 @@ +{include file="public/header" nav="充值"} +{if condition="$_GET['type'] eq 'wechat'"} +
        +
        + + + +
        微信扫码充值
        +
        +
        +
        + 微信充值 {$money} 元 +
        +
        + +
        +
        + {:getInfo('qr_wechat')} +
        +
        + {else/} +
        +
        + + + +
        支付宝扫码充值
        +
        +
        +
        + 支付宝充值 {$money} 元 +
        +
        + +
        +
        + {:getInfo('qr_alipay')} +
        +
        +{/if} + + diff --git a/application/index/view/user/set_account.html b/application/index/view/user/set_account.html new file mode 100755 index 0000000..db372e8 --- /dev/null +++ b/application/index/view/user/set_account.html @@ -0,0 +1,38 @@ +{include file="public/header" nav="账户安全"} + +
        +
        +
        +
        +
        + + 账户安全 +
        +
        +
        +
        + 用户名 + {$user.phone} +
        + + +
        +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        + + + \ No newline at end of file diff --git a/application/index/view/user/trade.html b/application/index/view/user/trade.html new file mode 100755 index 0000000..6b9929e --- /dev/null +++ b/application/index/view/user/trade.html @@ -0,0 +1,679 @@ +{include file="public/header" nav="交易中心"} + + + + + + + + + +
        + 交易中心 + 交易明细 +
        +
        +
        +
        +
        BTC
        +
        + 0.00 + 0.00% +
        +
        + +
        +
        +
        + BTC钱包 + {$user.btc} +
        +
        + +   全部出售   +
        +
        确认出售
        +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        +{include file="public/footer" menu='trade'} + + + + diff --git a/application/index/view/user/verified.html b/application/index/view/user/verified.html new file mode 100755 index 0000000..3477c13 --- /dev/null +++ b/application/index/view/user/verified.html @@ -0,0 +1,244 @@ +{include file="public/header" nav="实名认证"} + + + + +
        +
        +
        +
        +
        + + 实名认证 +
        +
        +
        + {if condition="$user['rz_status'] eq 0"} +

        + {/if} + {if condition="$user['rz_status'] eq 1"} +

        + {/if} + {if condition="$user['rz_status'] eq 2"} +

        + {/if} + {if condition="$user['rz_status'] eq 3"} +

        + {/if} +
        + {if condition="$user['rz_status'] eq 1 or $user['rz_status'] eq 2"} +
          +
        • + + {$user.name} +
        • +
        • + + {$user.idcard} +
        • +
        +
        + + +
        + + + + {else /} +
          +
        • + + +
        • +
        • + + +
        • +
        +
        + + +
        +
        + +
        + {/if} +
        +
        +
        + {include file="public/footer" menu='user'} +
        +
        +
        +
        +

        温馨提示

        +

        +
        +
        确定
        +
        +
        +
        + + + + + + diff --git a/application/index/view/user/wallet.html b/application/index/view/user/wallet.html new file mode 100755 index 0000000..585e78b --- /dev/null +++ b/application/index/view/user/wallet.html @@ -0,0 +1,148 @@ +{include file="public/header" nav="我的钱包"} + + + + + + + + +
        + 我的钱包 +
        +
        +
        +
        +
        +
        +
        账户余额(元)
        +
        + {$user.money}
        + +
        +
          +
        • + + 矿机保证金 + {$kjbz} +
        • +
        • + + 合约保证金 + {$hybz} +
        • +
        • + + BTC钱包 + {$user.btc} +
        • +
        • + + BTC累计产量 + {$kjcl} +
        • +
        • + + 矿机收益 + {$kjsy} +
        • +
        • + + 合约收益 + {$hysy} +
        • +
        • + + 推荐奖励 + 0.00 +
        • +
        • + + 获得积分 + {$user.integral} +
        • +
        +
        +
        +{include file="public/footer" menu='wallet'} + + diff --git a/application/index/view/user/yeb.html b/application/index/view/user/yeb.html new file mode 100755 index 0000000..6543983 --- /dev/null +++ b/application/index/view/user/yeb.html @@ -0,0 +1,244 @@ +{include file="public/header" nav="利息宝"} + +
        +
        +
        +
        +
        + + 利息宝 +
        +
        +
        总金额(元)
        +
        {$yuebaouc.balance}
        +
        可转出余额(元):{$yuebaouc.trans_balance}
        +
        +
        +
        昨天收益(元)
        +
        {$yuebaouc.preprofit}
        +
        +
        +
        累计收益(元)
        +
        {$yuebaouc.totalprofit}
        +
        +
        +
        昨天余额
        +
        {$yuebaouc.prebalance}
        +
        +
        +
        +
        + + +
        +
        +
        +
        +
        + 方案明细 + 进行中 + 已结束 +
        +
        + {foreach $doinglist as $key=>$vo} +
        +
        + 产品名称:{$vo.yebtitle}:{$vo.money}元 + 当前收益:{$vo.nowprofit}元
        +
        + 办理时间:{$vo.start_time} + 状态:{$vo.status=='1'?'进行中':''} +
        +
        + 预计收益:{$vo.finishprofit}元 + / +
        +
        + {/foreach} + {empty name='$doinglist'}没有记录哦{/empty} +
        + + +
        +
        + + + + {include file="public/footer" menu='yeb'} + + +
        +
        +
        + + diff --git a/application/lang/en.json b/application/lang/en.json new file mode 100644 index 0000000..6875105 --- /dev/null +++ b/application/lang/en.json @@ -0,0 +1 @@ +{"账户余额不足,请确认":"Insufficient account balance, please confirm","您办理的方案有最低存入":"The plan you applied for has a minimum deposit","网络异常,请稍后再试":"Network abnormality, please try again later","操作成功":"Successful operation","登录成功":"login successful","用户不存在":"User does not exist","请输入正确的用户名":"Please enter a valid username","登录密码有误,请重试!":"The login password is incorrect, please try again!","账号被锁定,请联系管理员!":"No trading allowed!","该账号已注册!":"This account has been registered!","请输入6-16位密码!":"Please enter a 6-16 digit password!","手机号请输入数字":"Please enter your mobile phone number","两次支付密码不一致":"The two payment passwords are inconsistent","两次密码不一致":"The two passwords do not match","验证码不正确":"Incorrect verification code","请输入验证码":"please enter verification code","无效邀请人!":"Invalid inviter!","系统繁忙,注册失败!":"The system is busy, registration failed!","注册成功":"registration success","产品不存在":"Product does not exist","产品未开启":"The product is not turned on","已认证请勿重复提交!":"Please do not submit again if it has been verified!","名字不能为空!":"Name cannot be empty!","身份证号码不能为空!":"ID number cannot be empty!","身份证正面照不能为空!":"The front photo of the ID card cannot be empty!","身份证反面照不能为空!":"The back side of the ID card cannot be empty!","身份证号码已被其他账号绑定!":"The ID number has been bound to another account!","名字不正确!":"The name is incorrect!","身份证号码不正确!":"Incorrect ID number!","认证信息提交成功!":"Authentication information submitted successfully!","认证信息提交失败!":"Failed to submit authentication information!","请先完成实名认证!":"Please complete the real-name authentication first!","提现时间为":"The withdrawal time is","提现金额不能为空!":"The withdrawal amount cannot be empty!","交易密码不正确!":"The transaction password is incorrect!","提现金额不能小于":"The withdrawal amount cannot be less than","提现金额不能大于":"The withdrawal amount cannot be greater than","每日提现次数":"Daily withdrawal times","当日累计最高提现金额不能大于":"The maximum daily withdrawal amount cannot be greater than","提现申请成功!":"Withdrawal application successful!","提现失败!":"Withdrawal failed!","产品未找到":"Product not found","休市中":"Closed","持仓最大金额为":"The maximum amount of position is","地址已绑定,请勿重复添加!":"The address has been bound, please do not add it again!","持仓最小金额为":"The minimum position amount is","":""} \ No newline at end of file diff --git a/application/lang/fr.json b/application/lang/fr.json new file mode 100644 index 0000000..a017d28 --- /dev/null +++ b/application/lang/fr.json @@ -0,0 +1 @@ +{"账户余额不足,请确认":"Solde du compte insuffisant, veuillez confirmer","您办理的方案有最低存入":"Le plan que vous avez demandé comporte un dépôt minimum","网络异常,请稍后再试":"Anomalie du réseau, veuillez réessayer plus tard","操作成功":"Opération réussie","登录成功":"connexion réussie","用户不存在":"L'utilisateur n'existe pas","请输入正确的用户名":"Veuillez entrer un nom d'utilisateur valide","登录密码有误,请重试!":"Le mot de passe de connexion est incorrect, veuillez réessayer !","账号被锁定,请联系管理员!":"Aucun échange autorisé !","该账号已注册!":"Ce compte a été enregistré !","请输入6-16位密码!":"Veuillez entrer un mot de passe de 6 à 16 chiffres !","手机号请输入数字":"Veuillez entrer votre numéro de téléphone portable","两次支付密码不一致":"Les deux mots de passe de paiement sont incohérents","两次密码不一致":"Les deux mots de passe ne correspondent pas","验证码不正确":"Code de vérification incorrect","请输入验证码":"veuillez entrer le code de vérification","无效邀请人!":"Invitant invalide !","系统繁忙,注册失败!":"Le système est occupé, l'enregistrement a échoué !","注册成功":"succès de l'inscription","产品不存在":"Le produit n'existe pas","产品未开启":"Le produit n'est pas allumé","已认证请勿重复提交!":"Veuillez ne pas soumettre à nouveau si cela a été vérifié !","名字不能为空!":"Le nom ne peut pas être vide !","身份证号码不能为空!":"Le numéro d'identification ne peut pas être vide !","身份证正面照不能为空!":"La photo de face de la carte d'identité ne peut pas être vide !","身份证反面照不能为空!":"Le verso de la carte d'identité ne peut pas être vide !","身份证号码已被其他账号绑定!":"Le numéro d’identification a été lié à un autre compte !","名字不正确!":"Le nom est incorrect !","身份证号码不正确!":"Numéro d'identification incorrect !","认证信息提交成功!":"Les informations d'authentification ont été soumises avec succès !","认证信息提交失败!":"Échec de la soumission des informations d'authentification !","请先完成实名认证!":"Veuillez d’abord compléter l’authentification du nom réel !","提现时间为":"Le délai de retrait est","提现金额不能为空!":"Le montant du retrait ne peut pas être vide !","交易密码不正确!":"Le mot de passe de transaction est incorrect !","提现金额不能小于":"Le montant du retrait ne peut pas être inférieur à","提现金额不能大于":"Le montant du retrait ne peut pas être supérieur à","每日提现次数":"Délais de retrait quotidiens","当日累计最高提现金额不能大于":"Le montant maximum de retrait quotidien ne peut pas être supérieur à","提现申请成功!":"Demande de retrait réussie !","提现失败!":"Le retrait a échoué !","产品未找到":"Produit non trouvé","休市中":"Fermé","持仓最大金额为":"Le montant maximum de la position est","地址已绑定,请勿重复添加!":"L'adresse a été liée, veuillez ne pas l'ajouter à nouveau !","持仓最小金额为":"Le montant minimum de la position est","":""} \ No newline at end of file diff --git a/application/lang/ko.json b/application/lang/ko.json new file mode 100644 index 0000000..76c9785 --- /dev/null +++ b/application/lang/ko.json @@ -0,0 +1 @@ +{"账户余额不足,请确认":"계좌잔액이 부족합니다. 확인해 주세요.","您办理的方案有最低存入":"신청하신 플랜에는 최소 보증금이 있습니다.","网络异常,请稍后再试":"네트워크 이상입니다. 잠시후 다시 시도해주세요.","操作成功":"성공적인 작업","登录成功":"성공적 로그인","用户不存在":"사용자가 존재하지 않습니다","请输入正确的用户名":"유효한 사용자 이름을 입력하세요","登录密码有误,请重试!":"로그인 비밀번호가 올바르지 않습니다. 다시 시도해 주세요!","账号被锁定,请联系管理员!":"거래는 허용되지 않습니다!","该账号已注册!":"이 계정은 등록되었습니다!","请输入6-16位密码!":"6~16자리의 비밀번호를 입력하세요!","手机号请输入数字":"휴대폰 번호를 입력해주세요.","两次支付密码不一致":"두 개의 결제 비밀번호가 일치하지 않습니다.","两次密码不一致":"두 비밀번호가 일치하지 않습니다","验证码不正确":"잘못된 검증코드입니다","请输入验证码":"인증 코드를 입력하세요","无效邀请人!":"잘못된 초대자입니다!","系统繁忙,注册失败!":"시스템이 사용 중이어서 등록에 실패했습니다!","注册成功":"등록 성공","产品不存在":"제품이 존재하지 않습니다","产品未开启":"제품이 켜지지 않습니다","已认证请勿重复提交!":"검증이 완료된 경우 다시 제출하지 마세요!","名字不能为空!":"이름은 비워둘 수 없습니다!","身份证号码不能为空!":"ID 번호는 비어있을 수 없습니다!","身份证正面照不能为空!":"신분증 앞면 사진은 비워둘 수 없습니다!","身份证反面照不能为空!":"신분증 뒷면은 비워둘 수 없습니다!","身份证号码已被其他账号绑定!":"ID번호가 다른 계정에 연결되어 있습니다!","名字不正确!":"이름이 잘못되었습니다!","身份证号码不正确!":"잘못된 ID 번호입니다!","认证信息提交成功!":"인증 정보가 성공적으로 전송되었습니다!","认证信息提交失败!":"인증 정보를 제출하지 못했습니다!","请先完成实名认证!":"먼저 실명인증을 완료해 주세요!","提现时间为":"출금시간은","提现金额不能为空!":"출금 금액은 비어 있을 수 없습니다!","交易密码不正确!":"거래 비밀번호가 틀렸습니다!","提现金额不能小于":"출금금액은 다음보다 적을 수 없습니다.","提现金额不能大于":"인출금액은 다음보다 클 수 없습니다.","每日提现次数":"일일 출금 시간","当日累计最高提现金额不能大于":"최대 일일 출금 금액은 다음보다 클 수 없습니다.","提现申请成功!":"출금 신청이 성공했습니다!","提现失败!":"출금 실패!","产品未找到":"제품을 찾을 수 없습니다","休市中":"닫은","持仓最大金额为":"최대 위치량은","地址已绑定,请勿重复添加!":"주소가 바인딩되었으니 다시 추가하지 마세요!","持仓最小金额为":"최소 포지션 금액은","":""} \ No newline at end of file diff --git a/application/lang/pt.json b/application/lang/pt.json new file mode 100644 index 0000000..02e672a --- /dev/null +++ b/application/lang/pt.json @@ -0,0 +1 @@ +{"账户余额不足,请确认":"Saldo de conta insuficiente, confirme","您办理的方案有最低存入":"O plano que você solicitou tem um depósito mínimo","网络异常,请稍后再试":"Anormalidade na rede, tente novamente mais tarde","操作成功":"Operação bem-sucedida","登录成功":"login bem-sucedido","用户不存在":"Usuário não existe","请输入正确的用户名":"Por favor, insira um nome de usuário válido","登录密码有误,请重试!":"A senha de login está incorreta, tente novamente!","账号被锁定,请联系管理员!":"Não é permitida negociação!","该账号已注册!":"Esta conta foi registrada!","请输入6-16位密码!":"Por favor, digite uma senha de 6 a 16 dígitos!","手机号请输入数字":"Por favor, insira seu número de telefone celular","两次支付密码不一致":"As duas senhas de pagamento são inconsistentes","两次密码不一致":"As duas senhas não correspondem","验证码不正确":"Código de verificação incorreto","请输入验证码":"por favor insira o código de verificação","无效邀请人!":"Convidador inválido!","系统繁忙,注册失败!":"O sistema está ocupado, o registro falhou!","注册成功":"Registro bem sucedido","产品不存在":"O produto não existe","产品未开启":"O produto não liga","已认证请勿重复提交!":"Por favor, não envie novamente se já tiver sido verificado!","名字不能为空!":"O nome não pode estar vazio!","身份证号码不能为空!":"O número de identificação não pode estar vazio!","身份证正面照不能为空!":"A foto da frente do documento de identificação não pode estar vazia!","身份证反面照不能为空!":"O verso do documento de identificação não pode ficar em branco!","身份证号码已被其他账号绑定!":"O número de identificação foi vinculado a outra conta!","名字不正确!":"O nome está incorreto!","身份证号码不正确!":"Número de identificação incorreto!","认证信息提交成功!":"Informações de autenticação enviadas com sucesso!","认证信息提交失败!":"Falha ao enviar informações de autenticação!","请先完成实名认证!":"Por favor, conclua a autenticação do nome real primeiro!","提现时间为":"O tempo de retirada é","提现金额不能为空!":"O valor de retirada não pode estar vazio!","交易密码不正确!":"A senha da transação está incorreta!","提现金额不能小于":"O valor do saque não pode ser inferior a","提现金额不能大于":"O valor do saque não pode ser maior que","每日提现次数":"Tempos de retirada diários","当日累计最高提现金额不能大于":"O valor máximo de retirada diária não pode ser maior que","提现申请成功!":"Pedido de retirada bem-sucedido!","提现失败!":"A retirada falhou!","产品未找到":"Produto não encontrado","休市中":"Fechado","持仓最大金额为":"A quantidade máxima de posição é","地址已绑定,请勿重复添加!":"O endereço foi vinculado, por favor, não o adicione novamente!","持仓最小金额为":"O valor mínimo da posição é","":""} \ No newline at end of file diff --git a/application/lang/th.json b/application/lang/th.json new file mode 100644 index 0000000..d4dc11c --- /dev/null +++ b/application/lang/th.json @@ -0,0 +1 @@ +{"账户余额不足,请确认":"ยอดเงินในบัญชีไม่เพียงพอ กรุณายืนยัน","您办理的方案有最低存入":"แผนที่คุณสมัครมีเงินฝากขั้นต่ำ","网络异常,请稍后再试":"เครือข่ายผิดปกติ กรุณาลองใหม่อีกครั้งในภายหลัง","操作成功":"การดำเนินการที่ประสบความสำเร็จ","登录成功":"เข้าสู่ระบบสำเร็จ","用户不存在":"ไม่มีผู้ใช้","请输入正确的用户名":"กรุณากรอกชื่อผู้ใช้ให้ถูกต้อง","登录密码有误,请重试!":"รหัสผ่านเข้าสู่ระบบไม่ถูกต้อง กรุณาลองอีกครั้ง!","账号被锁定,请联系管理员!":"ไม่อนุญาตให้ซื้อขาย!","该账号已注册!":"บัญชีนี้ได้รับการลงทะเบียนแล้ว!","请输入6-16位密码!":"กรุณาใส่รหัสผ่าน 6-16 หลัก!","手机号请输入数字":"กรุณากรอกหมายเลขโทรศัพท์มือถือของคุณ","两次支付密码不一致":"รหัสผ่านการชำระเงินทั้งสองไม่สอดคล้องกัน","两次密码不一致":"รหัสผ่านทั้งสองไม่ตรงกัน","验证码不正确":"รหัสตรวจสอบไม่ถูกต้อง","请输入验证码":"กรุณากรอกรหัสยืนยัน","无效邀请人!":"ผู้เชิญไม่ถูกต้อง!","系统繁忙,注册失败!":"ระบบกำลังยุ่งอยู่ ลงทะเบียนล้มเหลว!","注册成功":"การลงทะเบียนสำเร็จ","产品不存在":"สินค้าไม่มีอยู่","产品未开启":"สินค้าไม่ได้เปิดอยู่","已认证请勿重复提交!":"กรุณาอย่าส่งซ้ำอีกหากได้รับการตรวจสอบแล้ว!","名字不能为空!":"ชื่อไม่สามารถว่างเปล่าได้!","身份证号码不能为空!":"หมายเลขบัตรประชาชนไม่สามารถว่างเปล่าได้!","身份证正面照不能为空!":"รูปหน้าบัตรประชาชนห้ามเว้นว่างไว้!","身份证反面照不能为空!":"หลังบัตรประชาชนห้ามว่างเปล่า!","身份证号码已被其他账号绑定!":"เลขบัตรประชาชนถูกผูกกับบัญชีอื่นแล้ว!","名字不正确!":"ชื่อไม่ถูกต้อง!","身份证号码不正确!":"หมายเลขบัตรประชาชนไม่ถูกต้อง!","认证信息提交成功!":"ส่งข้อมูลยืนยันตัวตนเรียบร้อยแล้ว!","认证信息提交失败!":"ไม่สามารถส่งข้อมูลยืนยันตัวตนได้!","请先完成实名认证!":"กรุณาทำการพิสูจน์ชื่อจริงก่อน!","提现时间为":"เวลาถอนเงินคือ","提现金额不能为空!":"จำนวนเงินที่ถอนไม่สามารถว่างเปล่าได้!","交易密码不正确!":"รหัสผ่านการทำธุรกรรมไม่ถูกต้อง!","提现金额不能小于":"จำนวนเงินที่ถอนไม่สามารถน้อยกว่า","提现金额不能大于":"จำนวนเงินที่ถอนออกไม่สามารถมากกว่า","每日提现次数":"เวลาถอนเงินรายวัน","当日累计最高提现金额不能大于":"จำนวนเงินถอนสูงสุดต่อวันไม่สามารถมากกว่า","提现申请成功!":"การสมัครถอนเงินสำเร็จแล้ว!","提现失败!":"การถอนเงินล้มเหลว!","产品未找到":"ไม่พบสินค้า","休市中":"ปิด","持仓最大金额为":"จำนวนตำแหน่งสูงสุดคือ","地址已绑定,请勿重复添加!":"ที่อยู่ถูกผูกไว้แล้ว กรุณาอย่าเพิ่มอีก!","持仓最小金额为":"จำนวนตำแหน่งขั้นต่ำคือ","":""} \ No newline at end of file diff --git a/application/lang/tr.json b/application/lang/tr.json new file mode 100644 index 0000000..b7a5a10 --- /dev/null +++ b/application/lang/tr.json @@ -0,0 +1 @@ +{"账户余额不足,请确认":"Yetersiz hesap bakiyesi, lütfen onaylayın","您办理的方案有最低存入":"Başvurduğunuz planın minimum depozitosu var","网络异常,请稍后再试":"Ağ anormalliği, lütfen daha sonra tekrar deneyin","操作成功":"İşlem başarılı","登录成功":"giriş başarılı","用户不存在":"Kullanıcı yok","请输入正确的用户名":"Lütfen geçerli bir kullanıcı adı girin","登录密码有误,请重试!":"Giriş şifresi hatalı, lütfen tekrar deneyin!","账号被锁定,请联系管理员!":"İşlem yapılmasına izin verilmiyor!","该账号已注册!":"Bu hesap kaydedildi!","请输入6-16位密码!":"Lütfen 6-16 haneli bir şifre giriniz!","手机号请输入数字":"Lütfen cep telefonu numaranızı giriniz","两次支付密码不一致":"İki ödeme şifresi tutarsız","两次密码不一致":"İki şifre eşleşmiyor","验证码不正确":"Yanlış doğrulama kodu","请输入验证码":"lütfen doğrulama kodunu girin","无效邀请人!":"Geçersiz davet eden!","系统繁忙,注册失败!":"Sistem meşgul, kayıt başarısız!","注册成功":"başarılı Kayıt","产品不存在":"Ürün mevcut değil","产品未开启":"Ürün açık değil","已认证请勿重复提交!":"Doğrulandıysa lütfen tekrar göndermeyin!","名字不能为空!":"İsim boş bırakılamaz!","身份证号码不能为空!":"Kimlik numarası boş bırakılamaz!","身份证正面照不能为空!":"Kimliğin ön yüzü boş olamaz!","身份证反面照不能为空!":"Kimliğin arka yüzü boş olamaz!","身份证号码已被其他账号绑定!":"Kimlik numarası başka bir hesaba bağlanmış!","名字不正确!":"İsim yanlış!","身份证号码不正确!":"Hatalı TC Kimlik Numarası!","认证信息提交成功!":"Kimlik doğrulama bilgileri başarıyla gönderildi!","认证信息提交失败!":"Kimlik doğrulama bilgileri gönderilemedi!","请先完成实名认证!":"Lütfen önce gerçek isim doğrulamasını tamamlayın!","提现时间为":"Para çekme süresi","提现金额不能为空!":"Çekim tutarı boş bırakılamaz!","交易密码不正确!":"İşlem şifresi hatalı!","提现金额不能小于":"Çekilecek tutar şu miktardan az olamaz:","提现金额不能大于":"Çekilecek tutar şu miktardan fazla olamaz:","每日提现次数":"Günlük çekim süreleri","当日累计最高提现金额不能大于":"Günlük maksimum çekim tutarı şundan büyük olamaz:","提现申请成功!":"Para çekme talebiniz başarılı!","提现失败!":"Para çekme işlemi başarısız oldu!","产品未找到":"Ürün bulunamadı","休市中":"Kapalı","持仓最大金额为":"Pozisyonun maksimum miktarı","地址已绑定,请勿重复添加!":"Adres bağlanmış, lütfen tekrar eklemeyin!","持仓最小金额为":"Minimum pozisyon miktarı","":""} \ No newline at end of file diff --git a/application/lang/vi.json b/application/lang/vi.json new file mode 100644 index 0000000..4dfbe5c --- /dev/null +++ b/application/lang/vi.json @@ -0,0 +1 @@ +{"账户余额不足,请确认":"Số dư tài khoản không đủ, vui lòng xác nhận","您办理的方案有最低存入":"Kế hoạch bạn đã đăng ký có mức tiền gửi tối thiểu","网络异常,请稍后再试":"Mạng bất thường, vui lòng thử lại sau","操作成功":"Hoạt động thành công","登录成功":"đăng nhập thành công","用户不存在":"người dùng không tồn tại","请输入正确的用户名":"Vui lòng nhập tên người dùng hợp lệ","登录密码有误,请重试!":"Mật khẩu đăng nhập không đúng, vui lòng thử lại!","账号被锁定,请联系管理员!":"Không được phép giao dịch!","该账号已注册!":"Tài khoản này đã được đăng ký!","请输入6-16位密码!":"Vui lòng nhập mật khẩu từ 6-16 chữ số!","手机号请输入数字":"Vui lòng nhập số điện thoại di động của bạn","两次支付密码不一致":"Hai mật khẩu thanh toán không nhất quán","两次密码不一致":"Hai mật khẩu không nhất quán","验证码不正确":"Mã xác minh không chính xác","请输入验证码":"vui lòng nhập mã xác nhận","无效邀请人!":"Người mời không hợp lệ!","系统繁忙,注册失败!":"Hệ thống đang bận, đăng ký không thành công!","注册成功":"đăng ký thành công","产品不存在":"Sản phẩm không tồn tại","产品未开启":"Sản phẩm chưa được bật","已认证请勿重复提交!":"Vui lòng không gửi lại nếu thông tin đã được xác minh!","名字不能为空!":"Tên không được để trống!","身份证号码不能为空!":"Số ID không được để trống!","身份证正面照不能为空!":"Ảnh mặt trước của thẻ căn cước không được để trống!","身份证反面照不能为空!":"Mặt sau của thẻ căn cước không được để trống!","身份证号码已被其他账号绑定!":"Số ID đã được liên kết với một tài khoản khác!","名字不正确!":"Tên không đúng!","身份证号码不正确!":"Số CMND không đúng!","认证信息提交成功!":"Thông tin xác thực đã được gửi thành công!","认证信息提交失败!":"Không thể gửi thông tin xác thực!","请先完成实名认证!":"Vui lòng hoàn tất xác thực tên thật trước!","提现时间为":"Thời gian rút tiền là","提现金额不能为空!":"Số tiền rút không được để trống!","交易密码不正确!":"Mật khẩu giao dịch không đúng!","提现金额不能小于":"Số tiền rút không được ít hơn","提现金额不能大于":"Số tiền rút không được lớn hơn","每日提现次数":"Thời gian rút tiền hàng ngày","当日累计最高提现金额不能大于":"Số tiền rút tối đa hàng ngày không được lớn hơn","提现申请成功!":"Đã nộp đơn xin rút tiền thành công!","提现失败!":"Rút tiền không thành công!","产品未找到":"Không tìm thấy sản phẩm","休市中":"Đã đóng","持仓最大金额为":"Số lượng vị trí tối đa là","地址已绑定,请勿重复添加!":"Địa chỉ đã được liên kết, vui lòng không thêm lại nữa!","持仓最小金额为":"Số lượng vị trí tối thiểu là","":""} \ No newline at end of file diff --git a/application/lang/zh-cn.json b/application/lang/zh-cn.json new file mode 100644 index 0000000..ed0258a --- /dev/null +++ b/application/lang/zh-cn.json @@ -0,0 +1,50 @@ +{ + "账户余额不足,请确认": "账户余额不足,请确认", + "您办理的方案有最低存入": "您办理的方案有最低存入", + "网络异常,请稍后再试": "网络异常,请稍后再试", + "操作成功": "操作成功", + "登录成功": "登录成功", + "用户不存在": "用户不存在", + "邀请人不存在": "邀请人不存在", + "请输入正确的用户名": "请输入正确的用户名", + "登录密码有误,请重试!": "登录密码有误,请重试!", + "账号被锁定,请联系管理员!": "禁止交易!", + "该账号已注册!": "该账号已注册!", + "请输入6-16位密码!": "请输入6-16位密码!", + "手机号请输入数字": "手机号请输入数字", + "两次支付密码不一致": "两次支付密码不一致", + "两次密码不一致": "两次密码不一致", + "验证码不正确": "验证码不正确", + "请输入验证码": "请输入验证码", + "无效邀请人!": "无效邀请人!", + "系统繁忙,注册失败!": "系统繁忙,注册失败!", + "注册成功": "注册成功", + "产品不存在": "产品不存在", + "产品未开启": "产品未开启", + "已认证请勿重复提交!": "已认证请勿重复提交!", + "名字不能为空!": "名字不能为空!", + "身份证号码不能为空!": "身份证号码不能为空!", + "身份证正面照不能为空!": "身份证正面照不能为空!", + "身份证反面照不能为空!": "身份证反面照不能为空!", + "身份证号码已被其他账号绑定!": "身份证号码已被其他账号绑定!", + "名字不正确!": "名字不正确!", + "身份证号码不正确!": "身份证号码不正确!", + "认证信息提交成功!": "认证信息提交成功!", + "认证信息提交失败!": "认证信息提交失败!", + "请先完成实名认证!": "请先完成实名认证!", + "提现时间为": "提现时间为", + "提现金额不能为空!": "提现金额不能为空!", + "交易密码不正确!": "交易密码不正确!", + "提现金额不能小于": "提现金额不能小于", + "提现金额不能大于": "提现金额不能大于", + "每日提现次数": "每日提现次数", + "当日累计最高提现金额不能大于": "当日累计最高提现金额不能大于", + "提现申请成功!": "提现申请成功!", + "提现失败!": "提现失败!", + "产品未找到": "产品未找到", + "休市中": "休市中", + "持仓最大金额为": "持仓最大金额为", + "地址已绑定,请勿重复添加!": "地址已绑定,请勿重复添加!", + "持仓最小金额为": "持仓最小金额为", + "": "" +} \ No newline at end of file diff --git a/build.php b/build.php new file mode 100644 index 0000000..34ba3c8 --- /dev/null +++ b/build.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- + +return [ + // 生成应用公共文件 + '__file__' => ['common.php'], + + // 定义demo模块的自动生成 (按照实际定义的文件名生成) + 'demo' => [ + '__file__' => ['common.php'], + '__dir__' => ['behavior', 'controller', 'model', 'view'], + 'controller' => ['Index', 'Test', 'UserType'], + 'model' => ['User', 'UserType'], + 'view' => ['index/index'], + ], + + // 其他更多的模块定义 +]; diff --git a/config/app.php b/config/app.php new file mode 100755 index 0000000..9e674a9 --- /dev/null +++ b/config/app.php @@ -0,0 +1,31 @@ + true, + // 应用Trace调试 + 'app_trace' => false, + // 0按名称成对解析 1按顺序解析 + 'url_param_type' => 1, + // 当前 ThinkAdmin 版本号 + 'thinkadmin_ver' => 'v5', + // 设置时区 +// 设置时区为圣保罗 + 'DEFAULT_TIMEZONE' => 'America/Sao_Paulo', + 'default_lang' => 'zh-cn', // 设置默认语言 + 'lang_switch_on' => true, // 开启多语言切换 + 'deny_module_list' => ['akszadmin'] +]; diff --git a/config/cookie.php b/config/cookie.php new file mode 100755 index 0000000..5030834 --- /dev/null +++ b/config/cookie.php @@ -0,0 +1,25 @@ + 1800, + // cookie 启用安全传输 + 'secure' => false, + // httponly 设置 + 'httponly' => true, + // 是否使用 setcookie + 'setcookie' => true, +]; diff --git a/config/database.php b/config/database.php new file mode 100755 index 0000000..42d093e --- /dev/null +++ b/config/database.php @@ -0,0 +1,35 @@ + env('database.debug', true), + // 数据库类型 + 'type' => 'mysql', + // 服务器地址 + 'hostname' => env('database.hostname', '127.0.0.1'), + // 数据库名 + 'database' => env('database.database', '0302-2'), + // 用户名 + 'username' => env('database.username', '0302-2'), + // 密码 + 'password' => env('database.password', '0302-2'), + // 编码 + 'charset' => env('database.charset', 'utf8mb4'), + // 端口 + 'hostport' => env('database.hostport', '3306'), + // 主从 + 'deploy' => 0, + // 分离 + 'rw_separate' => false, +]; diff --git a/config/log.php b/config/log.php new file mode 100755 index 0000000..932bb1e --- /dev/null +++ b/config/log.php @@ -0,0 +1,27 @@ + 'single', + // 最多保留50个文件 + 'max_files' => 50, + // 日志每10兆分割文件 + 'file_size' => 10485760, + // 设置记录目录的类型 + // 'level' => ['error'], + // 日志类型分别写入文件 + 'apart_level' => ['error', 'sql'], +]; diff --git a/config/session.php b/config/session.php new file mode 100755 index 0000000..cdaab64 --- /dev/null +++ b/config/session.php @@ -0,0 +1,26 @@ + 'fw', + 'path' => $_path_, + 'name' => $_name_, +]; diff --git a/config/template.php b/config/template.php new file mode 100755 index 0000000..2fff727 --- /dev/null +++ b/config/template.php @@ -0,0 +1,30 @@ + true, + // 开启模板编译缓存 + 'tpl_cache' => !Config::get('app_debug'), + // 定义模板替换字符串 + 'tpl_replace_string' => [ + '__APP__' => rtrim(url('@'), '\\/'), + '__ROOT__' => rtrim(dirname(Request::basefile()), '\\/'), + '__FULL__' => rtrim(dirname(Request::basefile(true)), '\\/'), + ], +]; diff --git a/config/wechat.php b/config/wechat.php new file mode 100755 index 0000000..5c6f2a8 --- /dev/null +++ b/config/wechat.php @@ -0,0 +1,28 @@ + 'https://demo.thinkadmin.top', + // 小程序支付参数 + 'miniapp' => [ + 'appid' => 'wx8c108930fe12b7ef', + 'appsecret' => '13d829992a2b6a0a44195a4a580da56d', + 'mch_id' => '1332187001', + 'mch_key' => 'A82DC5BD1F3359081049C568D8502BC5', + 'ssl_p12' => __DIR__ . '/cert/1332187001_20181030_cert.p12', + 'cache_path' => env('runtime_path') . 'wechat' . DIRECTORY_SEPARATOR, + ], +]; diff --git a/db/0302-2_20250306_112456.sql.gz b/db/0302-2_20250306_112456.sql.gz new file mode 100644 index 0000000..b3a6256 Binary files /dev/null and b/db/0302-2_20250306_112456.sql.gz differ diff --git a/db/wp_amazonhub_sit_20230208_224851.sql.gz b/db/wp_amazonhub_sit_20230208_224851.sql.gz new file mode 100644 index 0000000..ecd39fd Binary files /dev/null and b/db/wp_amazonhub_sit_20230208_224851.sql.gz differ diff --git a/extend/ExtendException.php b/extend/ExtendException.php new file mode 100644 index 0000000..0128e4a --- /dev/null +++ b/extend/ExtendException.php @@ -0,0 +1,21 @@ +] + * +---------------------------------------------------------------------- + * | Tool: [ PhpStorm ] + * +---------------------------------------------------------------------- + * | Date: [ 2024/12/26 ] + * +---------------------------------------------------------------------- + * | 版权所有 [ 2020~2024 kaadon.com ] + * +---------------------------------------------------------------------- + **/ +class ExtendException extends Exception +{ + +} \ No newline at end of file diff --git a/extend/GdImageClass.php b/extend/GdImageClass.php new file mode 100644 index 0000000..b35eb55 --- /dev/null +++ b/extend/GdImageClass.php @@ -0,0 +1,220 @@ +image = $this->createImageFromPath($imagePath, $ext); + + if ($this->image === false) { + throw new ExtendException('Unsupported image type: ' . $ext); + } + } + + /** + * @throws \Exception + */ + function convertToValidPng($filePath, $outputPath) + { + // 获取文件内容 + $fileContent = file_get_contents($filePath); + if ($fileContent === false) { + throw new Exception('读取文件失败。'); + } + + // 从文件内容创建图像 + $image = imagecreatefromstring($fileContent); + if ($image === false) { + throw new Exception('该文件不是有效的图像。'); + } + + // 将图像保存为有效的 PNG 文件 + if (!imagepng($image, $outputPath)) { + throw new Exception('保存图像为 PNG 文件失败。'); + } + + // 释放内存 + imagedestroy($image); + } + + /** + * @param $filePath + * @param $outputPath + * @return void + * @throws \Exception + */ + function convertToValidJpg($filePath, $outputPath) + { + // 获取文件内容 + $fileContent = file_get_contents($filePath); + if ($fileContent === false) { + throw new Exception('读取文件失败。'); + } + + // 从文件内容创建图像 + $image = imagecreatefromstring($fileContent); + if ($image === false) { + throw new Exception('该文件不是有效的图像。'); + } + + // 将图像保存为有效的 PNG 文件 + if (!imagejpeg($image, $outputPath)) { + throw new Exception('保存图像为 PNG 文件失败。'); + } + + // 释放内存 + imagedestroy($image); + } + + /** + * @param $filePath + * @return bool + */ + function isValidPng($filePath): bool + { + $imageInfo = getimagesize($filePath); + return $imageInfo && $imageInfo[2] === IMAGETYPE_PNG; + } + + //判断是否为有效的jpg文件 + + /** + * @param $filePath + * @return bool + */ + function isValidJpg($filePath): bool + { + $imageInfo = getimagesize($filePath); + return $imageInfo && $imageInfo[2] === IMAGETYPE_JPEG; + } + + + /** + * @param string $imagePath + * @param string $ext + * @return \GdImage|false|resource + * @throws \Exception + */ + private function createImageFromPath(string $imagePath, string $ext) + { + switch ($ext) { + case 'png': + if (!$this->isValidPng($imagePath)){ + $this->convertToValidPng($imagePath, $imagePath); + } + return imagecreatefrompng($imagePath); + case 'gif': + return imagecreatefromgif($imagePath); + case 'jpeg': + case 'jpg': + if (!$this->isValidJpg($imagePath)){ + $this->convertToValidJpg($imagePath, $imagePath); + } + return imagecreatefromjpeg($imagePath); + case 'bmp': + return imagecreatefrombmp($imagePath); + case 'webp': + return imagecreatefromwebp($imagePath); + case 'xbm': + return imagecreatefromxbm($imagePath); + case 'xpm': + return imagecreatefromxpm($imagePath); + default: + return false; + } + } + + /** + * @return int + * @noinspection PhpUnusedPrivateMethodInspection + */ + private function getFileSize(): int + { + ob_start(); + imagejpeg($this->image); + $content = ob_get_clean(); + /** @noinspection PhpComposerExtensionStubsInspection */ + return (int)bcdiv((string)strlen($content), "1024", 4); + } + + /** + * @param int $width + * @param int $height + * @return $this + */ + public function resize(int $width, int $height): self + { + $newImage = imagecreatetruecolor($width, $height); + imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $width, $height, imagesx($this->image), imagesy($this->image)); + imagedestroy($this->image); + $this->image = $newImage; + return $this; + } + + /** + * @param string $targetPath + * @param string $format + * @return string + * @throws \ExtendException + */ + public function convertTo(string $targetPath, string $format): string + { + if (!imageistruecolor($this->image)) { + imagepalettetotruecolor($this->image); + } + switch (strtolower($format)) { + case 'png': + imagepng($this->image, $targetPath); + break; + case 'gif': + imagegif($this->image, $targetPath); + break; + case 'jpeg': + case 'jpg': + imagejpeg($this->image, $targetPath); + break; + case 'bmp': + imagebmp($this->image, $targetPath); + break; + case 'webp': + imagewebp($this->image, $targetPath); + break; + default: + throw new ExtendException('Unsupported target format: ' . $format); + } + + imagedestroy($this->image); + return $targetPath; + } +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..1bd54ae --- /dev/null +++ b/index.html @@ -0,0 +1,55 @@ + + + + + Site is created successfully! + + + +
        +

        Congratulations, the site is created successfully!

        +

        This is the default index.html, this page is automatically generated by the system

        +
          +
        • The index.html of this page is in the site root directory
        • +
        • You can modify, delete or overwrite this page
        • +
        +
        + + + \ No newline at end of file diff --git a/nodejs/String-ext.js b/nodejs/String-ext.js new file mode 100755 index 0000000..ec71060 --- /dev/null +++ b/nodejs/String-ext.js @@ -0,0 +1,38 @@ +String.prototype.format=function(){ + if(arguments.length==0) return this; + + var args=[], i=0; + for(;i + + + + + + + \ No newline at end of file diff --git a/nodejs/node_modules/cron-parser/.idea/encodings.xml b/nodejs/node_modules/cron-parser/.idea/encodings.xml new file mode 100755 index 0000000..97626ba --- /dev/null +++ b/nodejs/node_modules/cron-parser/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/nodejs/node_modules/cron-parser/.idea/jsLibraryMappings.xml b/nodejs/node_modules/cron-parser/.idea/jsLibraryMappings.xml new file mode 100755 index 0000000..63b6c47 --- /dev/null +++ b/nodejs/node_modules/cron-parser/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/nodejs/node_modules/cron-parser/.idea/modules.xml b/nodejs/node_modules/cron-parser/.idea/modules.xml new file mode 100755 index 0000000..7088fb0 --- /dev/null +++ b/nodejs/node_modules/cron-parser/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/nodejs/node_modules/cron-parser/.idea/vcs.xml b/nodejs/node_modules/cron-parser/.idea/vcs.xml new file mode 100755 index 0000000..94a25f7 --- /dev/null +++ b/nodejs/node_modules/cron-parser/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/nodejs/node_modules/cron-parser/.idea/workspace.xml b/nodejs/node_modules/cron-parser/.idea/workspace.xml new file mode 100755 index 0000000..12a06b8 --- /dev/null +++ b/nodejs/node_modules/cron-parser/.idea/workspace.xml @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + iterator + Dec + currentDate + const + range + explicit day of month definition + Invalid explicit day of month definition + yearly + _parseField + callback + + + $PROJECT_DIR$/test + $PROJECT_DIR$/lib + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'YYYY-[W]WW', // + MONTH: 'YYYY-MM' // + }; + + //! moment.js locale configuration + + hooks.defineLocale('af', { + months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), + weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), + weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), + meridiemParse: /vm|nm/i, + isPM : function (input) { + return /^nm$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'vm' : 'VM'; + } else { + return isLower ? 'nm' : 'NM'; + } + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Vandag om] LT', + nextDay : '[Môre om] LT', + nextWeek : 'dddd [om] LT', + lastDay : '[Gister om] LT', + lastWeek : '[Laas] dddd [om] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'oor %s', + past : '%s gelede', + s : '\'n paar sekondes', + ss : '%d sekondes', + m : '\'n minuut', + mm : '%d minute', + h : '\'n uur', + hh : '%d ure', + d : '\'n dag', + dd : '%d dae', + M : '\'n maand', + MM : '%d maande', + y : '\'n jaar', + yy : '%d jaar' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter + }, + week : { + dow : 1, // Maandag is die eerste dag van die week. + doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ar-dz', { + months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 4 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ar-kw', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap = { + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '0': '0' + }, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; + }, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] + }, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, months$1 = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر' + ]; + + hooks.defineLocale('ar-ly', { + months : months$1, + monthsShort : months$1, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'بعد %s', + past : 'منذ %s', + s : pluralize('s'), + ss : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ar-ma', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$1 = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }; + + hooks.defineLocale('ar-sa', { + months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$1[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ar-tn', { + months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + ss : '%d ثانية', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات' + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$2 = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, numberMap$1 = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }, pluralForm$1 = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; + }, plurals$1 = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] + }, pluralize$1 = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm$1(number), + str = plurals$1[u][pluralForm$1(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, months$2 = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر' + ]; + + hooks.defineLocale('ar', { + months : months$2, + monthsShort : months$2, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'بعد %s', + past : 'منذ %s', + s : pluralize$1('s'), + ss : pluralize$1('s'), + m : pluralize$1('m'), + mm : pluralize$1('m'), + h : pluralize$1('h'), + hh : pluralize$1('h'), + d : pluralize$1('d'), + dd : pluralize$1('d'), + M : pluralize$1('M'), + MM : pluralize$1('M'), + y : pluralize$1('y'), + yy : pluralize$1('y') + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap$1[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$2[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var suffixes = { + 1: '-inci', + 5: '-inci', + 8: '-inci', + 70: '-inci', + 80: '-inci', + 2: '-nci', + 7: '-nci', + 20: '-nci', + 50: '-nci', + 3: '-üncü', + 4: '-üncü', + 100: '-üncü', + 6: '-ncı', + 9: '-uncu', + 10: '-uncu', + 30: '-uncu', + 60: '-ıncı', + 90: '-ıncı' + }; + + hooks.defineLocale('az', { + months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), + monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), + weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), + weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), + weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[sabah saat] LT', + nextWeek : '[gələn həftə] dddd [saat] LT', + lastDay : '[dünən] LT', + lastWeek : '[keçən həftə] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s sonra', + past : '%s əvvəl', + s : 'birneçə saniyə', + ss : '%d saniyə', + m : 'bir dəqiqə', + mm : '%d dəqiqə', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir il', + yy : '%d il' + }, + meridiemParse: /gecə|səhər|gündüz|axşam/, + isPM : function (input) { + return /^(gündüz|axşam)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'gecə'; + } else if (hour < 12) { + return 'səhər'; + } else if (hour < 17) { + return 'gündüz'; + } else { + return 'axşam'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, + ordinal : function (number) { + if (number === 0) { // special case for zero + return number + '-ıncı'; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', + 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', + 'dd': 'дзень_дні_дзён', + 'MM': 'месяц_месяцы_месяцаў', + 'yy': 'год_гады_гадоў' + }; + if (key === 'm') { + return withoutSuffix ? 'хвіліна' : 'хвіліну'; + } + else if (key === 'h') { + return withoutSuffix ? 'гадзіна' : 'гадзіну'; + } + else { + return number + ' ' + plural(format[key], +number); + } + } + + hooks.defineLocale('be', { + months : { + format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'), + standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_') + }, + monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), + weekdays : { + format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), + standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), + isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/ + }, + weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., HH:mm', + LLLL : 'dddd, D MMMM YYYY г., HH:mm' + }, + calendar : { + sameDay: '[Сёння ў] LT', + nextDay: '[Заўтра ў] LT', + lastDay: '[Учора ў] LT', + nextWeek: function () { + return '[У] dddd [ў] LT'; + }, + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return '[У мінулую] dddd [ў] LT'; + case 1: + case 2: + case 4: + return '[У мінулы] dddd [ў] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'праз %s', + past : '%s таму', + s : 'некалькі секунд', + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : relativeTimeWithPlural, + hh : relativeTimeWithPlural, + d : 'дзень', + dd : relativeTimeWithPlural, + M : 'месяц', + MM : relativeTimeWithPlural, + y : 'год', + yy : relativeTimeWithPlural + }, + meridiemParse: /ночы|раніцы|дня|вечара/, + isPM : function (input) { + return /^(дня|вечара)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночы'; + } else if (hour < 12) { + return 'раніцы'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечара'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; + case 'D': + return number + '-га'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('bg', { + months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), + weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Днес в] LT', + nextDay : '[Утре в] LT', + nextWeek : 'dddd [в] LT', + lastDay : '[Вчера в] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[В изминалата] dddd [в] LT'; + case 1: + case 2: + case 4: + case 5: + return '[В изминалия] dddd [в] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'след %s', + past : 'преди %s', + s : 'няколко секунди', + ss : '%d секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дни', + M : 'месец', + MM : '%d месеца', + y : 'година', + yy : '%d години' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('bm', { + months : 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split('_'), + monthsShort : 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'), + weekdays : 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'), + weekdaysShort : 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'), + weekdaysMin : 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'MMMM [tile] D [san] YYYY', + LLL : 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm', + LLLL : 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm' + }, + calendar : { + sameDay : '[Bi lɛrɛ] LT', + nextDay : '[Sini lɛrɛ] LT', + nextWeek : 'dddd [don lɛrɛ] LT', + lastDay : '[Kunu lɛrɛ] LT', + lastWeek : 'dddd [tɛmɛnen lɛrɛ] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s kɔnɔ', + past : 'a bɛ %s bɔ', + s : 'sanga dama dama', + ss : 'sekondi %d', + m : 'miniti kelen', + mm : 'miniti %d', + h : 'lɛrɛ kelen', + hh : 'lɛrɛ %d', + d : 'tile kelen', + dd : 'tile %d', + M : 'kalo kelen', + MM : 'kalo %d', + y : 'san kelen', + yy : 'san %d' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$3 = { + '1': '১', + '2': '২', + '3': '৩', + '4': '৪', + '5': '৫', + '6': '৬', + '7': '৭', + '8': '৮', + '9': '৯', + '0': '০' + }, + numberMap$2 = { + '১': '1', + '২': '2', + '৩': '3', + '৪': '4', + '৫': '5', + '৬': '6', + '৭': '7', + '৮': '8', + '৯': '9', + '০': '0' + }; + + hooks.defineLocale('bn', { + months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), + monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'), + weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'), + weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'), + weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'), + longDateFormat : { + LT : 'A h:mm সময়', + LTS : 'A h:mm:ss সময়', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm সময়', + LLLL : 'dddd, D MMMM YYYY, A h:mm সময়' + }, + calendar : { + sameDay : '[আজ] LT', + nextDay : '[আগামীকাল] LT', + nextWeek : 'dddd, LT', + lastDay : '[গতকাল] LT', + lastWeek : '[গত] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s পরে', + past : '%s আগে', + s : 'কয়েক সেকেন্ড', + ss : '%d সেকেন্ড', + m : 'এক মিনিট', + mm : '%d মিনিট', + h : 'এক ঘন্টা', + hh : '%d ঘন্টা', + d : 'এক দিন', + dd : '%d দিন', + M : 'এক মাস', + MM : '%d মাস', + y : 'এক বছর', + yy : '%d বছর' + }, + preparse: function (string) { + return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { + return numberMap$2[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$3[match]; + }); + }, + meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'রাত' && hour >= 4) || + (meridiem === 'দুপুর' && hour < 5) || + meridiem === 'বিকাল') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'রাত'; + } else if (hour < 10) { + return 'সকাল'; + } else if (hour < 17) { + return 'দুপুর'; + } else if (hour < 20) { + return 'বিকাল'; + } else { + return 'রাত'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$4 = { + '1': '༡', + '2': '༢', + '3': '༣', + '4': '༤', + '5': '༥', + '6': '༦', + '7': '༧', + '8': '༨', + '9': '༩', + '0': '༠' + }, + numberMap$3 = { + '༡': '1', + '༢': '2', + '༣': '3', + '༤': '4', + '༥': '5', + '༦': '6', + '༧': '7', + '༨': '8', + '༩': '9', + '༠': '0' + }; + + hooks.defineLocale('bo', { + months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), + weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[དི་རིང] LT', + nextDay : '[སང་ཉིན] LT', + nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', + lastDay : '[ཁ་སང] LT', + lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ལ་', + past : '%s སྔན་ལ', + s : 'ལམ་སང', + ss : '%d སྐར་ཆ།', + m : 'སྐར་མ་གཅིག', + mm : '%d སྐར་མ', + h : 'ཆུ་ཚོད་གཅིག', + hh : '%d ཆུ་ཚོད', + d : 'ཉིན་གཅིག', + dd : '%d ཉིན་', + M : 'ཟླ་བ་གཅིག', + MM : '%d ཟླ་བ', + y : 'ལོ་གཅིག', + yy : '%d ལོ' + }, + preparse: function (string) { + return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { + return numberMap$3[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$4[match]; + }); + }, + meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'མཚན་མོ' && hour >= 4) || + (meridiem === 'ཉིན་གུང' && hour < 5) || + meridiem === 'དགོང་དག') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'མཚན་མོ'; + } else if (hour < 10) { + return 'ཞོགས་ཀས'; + } else if (hour < 17) { + return 'ཉིན་གུང'; + } else if (hour < 20) { + return 'དགོང་དག'; + } else { + return 'མཚན་མོ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + function relativeTimeWithMutation(number, withoutSuffix, key) { + var format = { + 'mm': 'munutenn', + 'MM': 'miz', + 'dd': 'devezh' + }; + return number + ' ' + mutation(format[key], number); + } + function specialMutationForYears(number) { + switch (lastNumber(number)) { + case 1: + case 3: + case 4: + case 5: + case 9: + return number + ' bloaz'; + default: + return number + ' vloaz'; + } + } + function lastNumber(number) { + if (number > 9) { + return lastNumber(number % 10); + } + return number; + } + function mutation(text, number) { + if (number === 2) { + return softMutation(text); + } + return text; + } + function softMutation(text) { + var mutationTable = { + 'm': 'v', + 'b': 'v', + 'd': 'z' + }; + if (mutationTable[text.charAt(0)] === undefined) { + return text; + } + return mutationTable[text.charAt(0)] + text.substring(1); + } + + hooks.defineLocale('br', { + months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), + monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), + weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), + weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), + weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h[e]mm A', + LTS : 'h[e]mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [a viz] MMMM YYYY', + LLL : 'D [a viz] MMMM YYYY h[e]mm A', + LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A' + }, + calendar : { + sameDay : '[Hiziv da] LT', + nextDay : '[Warc\'hoazh da] LT', + nextWeek : 'dddd [da] LT', + lastDay : '[Dec\'h da] LT', + lastWeek : 'dddd [paset da] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'a-benn %s', + past : '%s \'zo', + s : 'un nebeud segondennoù', + ss : '%d eilenn', + m : 'ur vunutenn', + mm : relativeTimeWithMutation, + h : 'un eur', + hh : '%d eur', + d : 'un devezh', + dd : relativeTimeWithMutation, + M : 'ur miz', + MM : relativeTimeWithMutation, + y : 'ur bloaz', + yy : specialMutationForYears + }, + dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/, + ordinal : function (number) { + var output = (number === 1) ? 'añ' : 'vet'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + hooks.defineLocale('bs', { + months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : 'dan', + dd : translate, + M : 'mjesec', + MM : translate, + y : 'godinu', + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ca', { + months : { + standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), + format: 'de gener_de febrer_de març_d\'abril_de maig_de juny_de juliol_d\'agost_de setembre_d\'octubre_de novembre_de desembre'.split('_'), + isFormat: /D[oD]?(\s)+MMMM/ + }, + monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'), + monthsParseExact : true, + weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), + weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), + weekdaysMin : 'dg_dl_dt_dc_dj_dv_ds'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [de] YYYY', + ll : 'D MMM YYYY', + LLL : 'D MMMM [de] YYYY [a les] H:mm', + lll : 'D MMM YYYY, H:mm', + LLLL : 'dddd D MMMM [de] YYYY [a les] H:mm', + llll : 'ddd D MMM YYYY, H:mm' + }, + calendar : { + sameDay : function () { + return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextDay : function () { + return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastDay : function () { + return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'd\'aquí %s', + past : 'fa %s', + s : 'uns segons', + ss : '%d segons', + m : 'un minut', + mm : '%d minuts', + h : 'una hora', + hh : '%d hores', + d : 'un dia', + dd : '%d dies', + M : 'un mes', + MM : '%d mesos', + y : 'un any', + yy : '%d anys' + }, + dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/, + ordinal : function (number, period) { + var output = (number === 1) ? 'r' : + (number === 2) ? 'n' : + (number === 3) ? 'r' : + (number === 4) ? 't' : 'è'; + if (period === 'w' || period === 'W') { + output = 'a'; + } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var months$3 = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), + monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); + function plural$1(n) { + return (n > 1) && (n < 5) && (~~(n / 10) !== 1); + } + function translate$1(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural$1(number) ? 'sekundy' : 'sekund'); + } else { + return result + 'sekundami'; + } + break; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural$1(number) ? 'minuty' : 'minut'); + } else { + return result + 'minutami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural$1(number) ? 'hodiny' : 'hodin'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'den' : 'dnem'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural$1(number) ? 'dny' : 'dní'); + } else { + return result + 'dny'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural$1(number) ? 'měsíce' : 'měsíců'); + } else { + return result + 'měsíci'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural$1(number) ? 'roky' : 'let'); + } else { + return result + 'lety'; + } + break; + } + } + + hooks.defineLocale('cs', { + months : months$3, + monthsShort : monthsShort, + monthsParse : (function (months, monthsShort) { + var i, _monthsParse = []; + for (i = 0; i < 12; i++) { + // use custom parser to solve problem with July (červenec) + _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); + } + return _monthsParse; + }(months$3, monthsShort)), + shortMonthsParse : (function (monthsShort) { + var i, _shortMonthsParse = []; + for (i = 0; i < 12; i++) { + _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i'); + } + return _shortMonthsParse; + }(monthsShort)), + longMonthsParse : (function (months) { + var i, _longMonthsParse = []; + for (i = 0; i < 12; i++) { + _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i'); + } + return _longMonthsParse; + }(months$3)), + weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), + weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), + weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), + longDateFormat : { + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm', + l : 'D. M. YYYY' + }, + calendar : { + sameDay: '[dnes v] LT', + nextDay: '[zítra v] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v neděli v] LT'; + case 1: + case 2: + return '[v] dddd [v] LT'; + case 3: + return '[ve středu v] LT'; + case 4: + return '[ve čtvrtek v] LT'; + case 5: + return '[v pátek v] LT'; + case 6: + return '[v sobotu v] LT'; + } + }, + lastDay: '[včera v] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulou neděli v] LT'; + case 1: + case 2: + return '[minulé] dddd [v] LT'; + case 3: + return '[minulou středu v] LT'; + case 4: + case 5: + return '[minulý] dddd [v] LT'; + case 6: + return '[minulou sobotu v] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : 'před %s', + s : translate$1, + ss : translate$1, + m : translate$1, + mm : translate$1, + h : translate$1, + hh : translate$1, + d : translate$1, + dd : translate$1, + M : translate$1, + MM : translate$1, + y : translate$1, + yy : translate$1 + }, + dayOfMonthOrdinalParse : /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('cv', { + months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'), + monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), + weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'), + weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), + weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', + LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', + LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm' + }, + calendar : { + sameDay: '[Паян] LT [сехетре]', + nextDay: '[Ыран] LT [сехетре]', + lastDay: '[Ӗнер] LT [сехетре]', + nextWeek: '[Ҫитес] dddd LT [сехетре]', + lastWeek: '[Иртнӗ] dddd LT [сехетре]', + sameElse: 'L' + }, + relativeTime : { + future : function (output) { + var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран'; + return output + affix; + }, + past : '%s каялла', + s : 'пӗр-ик ҫеккунт', + ss : '%d ҫеккунт', + m : 'пӗр минут', + mm : '%d минут', + h : 'пӗр сехет', + hh : '%d сехет', + d : 'пӗр кун', + dd : '%d кун', + M : 'пӗр уйӑх', + MM : '%d уйӑх', + y : 'пӗр ҫул', + yy : '%d ҫул' + }, + dayOfMonthOrdinalParse: /\d{1,2}-мӗш/, + ordinal : '%d-мӗш', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('cy', { + months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), + monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), + weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), + weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), + weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), + weekdaysParseExact : true, + // time formats are the same as en-gb + longDateFormat: { + LT: 'HH:mm', + LTS : 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[Heddiw am] LT', + nextDay: '[Yfory am] LT', + nextWeek: 'dddd [am] LT', + lastDay: '[Ddoe am] LT', + lastWeek: 'dddd [diwethaf am] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'mewn %s', + past: '%s yn ôl', + s: 'ychydig eiliadau', + ss: '%d eiliad', + m: 'munud', + mm: '%d munud', + h: 'awr', + hh: '%d awr', + d: 'diwrnod', + dd: '%d diwrnod', + M: 'mis', + MM: '%d mis', + y: 'blwyddyn', + yy: '%d flynedd' + }, + dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, + // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh + ordinal: function (number) { + var b = number, + output = '', + lookup = [ + '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed + 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed + ]; + if (b > 20) { + if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { + output = 'fed'; // not 30ain, 70ain or 90ain + } else { + output = 'ain'; + } + } else if (b > 0) { + output = lookup[b]; + } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('da', { + months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay : '[i dag kl.] LT', + nextDay : '[i morgen kl.] LT', + nextWeek : 'på dddd [kl.] LT', + lastDay : '[i går kl.] LT', + lastWeek : '[i] dddd[s kl.] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s siden', + s : 'få sekunder', + ss : '%d sekunder', + m : 'et minut', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dage', + M : 'en måned', + MM : '%d måneder', + y : 'et år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + hooks.defineLocale('de-at', { + months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime, + mm : '%d Minuten', + h : processRelativeTime, + hh : '%d Stunden', + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function processRelativeTime$1(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + hooks.defineLocale('de-ch', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime$1, + mm : '%d Minuten', + h : processRelativeTime$1, + hh : '%d Stunden', + d : processRelativeTime$1, + dd : processRelativeTime$1, + M : processRelativeTime$1, + MM : processRelativeTime$1, + y : processRelativeTime$1, + yy : processRelativeTime$1 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function processRelativeTime$2(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + hooks.defineLocale('de', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime$2, + mm : '%d Minuten', + h : processRelativeTime$2, + hh : '%d Stunden', + d : processRelativeTime$2, + dd : processRelativeTime$2, + M : processRelativeTime$2, + MM : processRelativeTime$2, + y : processRelativeTime$2, + yy : processRelativeTime$2 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var months$4 = [ + 'ޖެނުއަރީ', + 'ފެބްރުއަރީ', + 'މާރިޗު', + 'އޭޕްރީލު', + 'މޭ', + 'ޖޫން', + 'ޖުލައި', + 'އޯގަސްޓު', + 'ސެޕްޓެމްބަރު', + 'އޮކްޓޯބަރު', + 'ނޮވެމްބަރު', + 'ޑިސެމްބަރު' + ], weekdays = [ + 'އާދިއްތަ', + 'ހޯމަ', + 'އަންގާރަ', + 'ބުދަ', + 'ބުރާސްފަތި', + 'ހުކުރު', + 'ހޮނިހިރު' + ]; + + hooks.defineLocale('dv', { + months : months$4, + monthsShort : months$4, + weekdays : weekdays, + weekdaysShort : weekdays, + weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), + longDateFormat : { + + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/M/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /މކ|މފ/, + isPM : function (input) { + return 'މފ' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'މކ'; + } else { + return 'މފ'; + } + }, + calendar : { + sameDay : '[މިއަދު] LT', + nextDay : '[މާދަމާ] LT', + nextWeek : 'dddd LT', + lastDay : '[އިއްޔެ] LT', + lastWeek : '[ފާއިތުވި] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ތެރޭގައި %s', + past : 'ކުރިން %s', + s : 'ސިކުންތުކޮޅެއް', + ss : 'd% ސިކުންތު', + m : 'މިނިޓެއް', + mm : 'މިނިޓު %d', + h : 'ގަޑިއިރެއް', + hh : 'ގަޑިއިރު %d', + d : 'ދުވަހެއް', + dd : 'ދުވަސް %d', + M : 'މަހެއް', + MM : 'މަސް %d', + y : 'އަހަރެއް', + yy : 'އަހަރު %d' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 7, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('el', { + monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), + monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), + months : function (momentToFormat, format) { + if (!momentToFormat) { + return this._monthsNominativeEl; + } else if (typeof format === 'string' && /D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' + return this._monthsGenitiveEl[momentToFormat.month()]; + } else { + return this._monthsNominativeEl[momentToFormat.month()]; + } + }, + monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), + weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), + weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), + weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'μμ' : 'ΜΜ'; + } else { + return isLower ? 'πμ' : 'ΠΜ'; + } + }, + isPM : function (input) { + return ((input + '').toLowerCase()[0] === 'μ'); + }, + meridiemParse : /[ΠΜ]\.?Μ?\.?/i, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendarEl : { + sameDay : '[Σήμερα {}] LT', + nextDay : '[Αύριο {}] LT', + nextWeek : 'dddd [{}] LT', + lastDay : '[Χθες {}] LT', + lastWeek : function () { + switch (this.day()) { + case 6: + return '[το προηγούμενο] dddd [{}] LT'; + default: + return '[την προηγούμενη] dddd [{}] LT'; + } + }, + sameElse : 'L' + }, + calendar : function (key, mom) { + var output = this._calendarEl[key], + hours = mom && mom.hours(); + if (isFunction(output)) { + output = output.apply(mom); + } + return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); + }, + relativeTime : { + future : 'σε %s', + past : '%s πριν', + s : 'λίγα δευτερόλεπτα', + ss : '%d δευτερόλεπτα', + m : 'ένα λεπτό', + mm : '%d λεπτά', + h : 'μία ώρα', + hh : '%d ώρες', + d : 'μία μέρα', + dd : '%d μέρες', + M : 'ένας μήνας', + MM : '%d μήνες', + y : 'ένας χρόνος', + yy : '%d χρόνια' + }, + dayOfMonthOrdinalParse: /\d{1,2}η/, + ordinal: '%dη', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('en-au', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('en-ca', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'YYYY-MM-DD', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('en-gb', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('en-ie', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('en-il', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('en-nz', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('eo', { + months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), + weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'), + weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'), + weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D[-a de] MMMM, YYYY', + LLL : 'D[-a de] MMMM, YYYY HH:mm', + LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm' + }, + meridiemParse: /[ap]\.t\.m/i, + isPM: function (input) { + return input.charAt(0).toLowerCase() === 'p'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'p.t.m.' : 'P.T.M.'; + } else { + return isLower ? 'a.t.m.' : 'A.T.M.'; + } + }, + calendar : { + sameDay : '[Hodiaŭ je] LT', + nextDay : '[Morgaŭ je] LT', + nextWeek : 'dddd [je] LT', + lastDay : '[Hieraŭ je] LT', + lastWeek : '[pasinta] dddd [je] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'post %s', + past : 'antaŭ %s', + s : 'sekundoj', + ss : '%d sekundoj', + m : 'minuto', + mm : '%d minutoj', + h : 'horo', + hh : '%d horoj', + d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo + dd : '%d tagoj', + M : 'monato', + MM : '%d monatoj', + y : 'jaro', + yy : '%d jaroj' + }, + dayOfMonthOrdinalParse: /\d{1,2}a/, + ordinal : '%da', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort$1 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + + var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; + var monthsRegex$1 = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + hooks.defineLocale('es-do', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort$1[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex: monthsRegex$1, + monthsShortRegex: monthsRegex$1, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY h:mm A', + LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var monthsShortDot$1 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort$2 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + + hooks.defineLocale('es-us', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot$1; + } else if (/-MMM-/.test(format)) { + return monthsShort$2[m.month()]; + } else { + return monthsShortDot$1[m.month()]; + } + }, + monthsParseExact : true, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'MM/DD/YYYY', + LL : 'MMMM [de] D [de] YYYY', + LLL : 'MMMM [de] D [de] YYYY h:mm A', + LLLL : 'dddd, MMMM [de] D [de] YYYY h:mm A' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var monthsShortDot$2 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort$3 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + + var monthsParse$1 = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; + var monthsRegex$2 = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + hooks.defineLocale('es', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot$2; + } else if (/-MMM-/.test(format)) { + return monthsShort$3[m.month()]; + } else { + return monthsShortDot$2[m.month()]; + } + }, + monthsRegex : monthsRegex$2, + monthsShortRegex : monthsRegex$2, + monthsStrictRegex : /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex : /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse : monthsParse$1, + longMonthsParse : monthsParse$1, + shortMonthsParse : monthsParse$1, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function processRelativeTime$3(number, withoutSuffix, key, isFuture) { + var format = { + 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], + 'ss': [number + 'sekundi', number + 'sekundit'], + 'm' : ['ühe minuti', 'üks minut'], + 'mm': [number + ' minuti', number + ' minutit'], + 'h' : ['ühe tunni', 'tund aega', 'üks tund'], + 'hh': [number + ' tunni', number + ' tundi'], + 'd' : ['ühe päeva', 'üks päev'], + 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], + 'MM': [number + ' kuu', number + ' kuud'], + 'y' : ['ühe aasta', 'aasta', 'üks aasta'], + 'yy': [number + ' aasta', number + ' aastat'] + }; + if (withoutSuffix) { + return format[key][2] ? format[key][2] : format[key][1]; + } + return isFuture ? format[key][0] : format[key][1]; + } + + hooks.defineLocale('et', { + months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), + monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), + weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), + weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), + weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Täna,] LT', + nextDay : '[Homme,] LT', + nextWeek : '[Järgmine] dddd LT', + lastDay : '[Eile,] LT', + lastWeek : '[Eelmine] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s pärast', + past : '%s tagasi', + s : processRelativeTime$3, + ss : processRelativeTime$3, + m : processRelativeTime$3, + mm : processRelativeTime$3, + h : processRelativeTime$3, + hh : processRelativeTime$3, + d : processRelativeTime$3, + dd : '%d päeva', + M : processRelativeTime$3, + MM : processRelativeTime$3, + y : processRelativeTime$3, + yy : processRelativeTime$3 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('eu', { + months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), + monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), + monthsParseExact : true, + weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), + weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), + weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY[ko] MMMM[ren] D[a]', + LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', + LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', + l : 'YYYY-M-D', + ll : 'YYYY[ko] MMM D[a]', + lll : 'YYYY[ko] MMM D[a] HH:mm', + llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' + }, + calendar : { + sameDay : '[gaur] LT[etan]', + nextDay : '[bihar] LT[etan]', + nextWeek : 'dddd LT[etan]', + lastDay : '[atzo] LT[etan]', + lastWeek : '[aurreko] dddd LT[etan]', + sameElse : 'L' + }, + relativeTime : { + future : '%s barru', + past : 'duela %s', + s : 'segundo batzuk', + ss : '%d segundo', + m : 'minutu bat', + mm : '%d minutu', + h : 'ordu bat', + hh : '%d ordu', + d : 'egun bat', + dd : '%d egun', + M : 'hilabete bat', + MM : '%d hilabete', + y : 'urte bat', + yy : '%d urte' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$5 = { + '1': '۱', + '2': '۲', + '3': '۳', + '4': '۴', + '5': '۵', + '6': '۶', + '7': '۷', + '8': '۸', + '9': '۹', + '0': '۰' + }, numberMap$4 = { + '۱': '1', + '۲': '2', + '۳': '3', + '۴': '4', + '۵': '5', + '۶': '6', + '۷': '7', + '۸': '8', + '۹': '9', + '۰': '0' + }; + + hooks.defineLocale('fa', { + months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /قبل از ظهر|بعد از ظهر/, + isPM: function (input) { + return /بعد از ظهر/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'قبل از ظهر'; + } else { + return 'بعد از ظهر'; + } + }, + calendar : { + sameDay : '[امروز ساعت] LT', + nextDay : '[فردا ساعت] LT', + nextWeek : 'dddd [ساعت] LT', + lastDay : '[دیروز ساعت] LT', + lastWeek : 'dddd [پیش] [ساعت] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'در %s', + past : '%s پیش', + s : 'چند ثانیه', + ss : 'ثانیه d%', + m : 'یک دقیقه', + mm : '%d دقیقه', + h : 'یک ساعت', + hh : '%d ساعت', + d : 'یک روز', + dd : '%d روز', + M : 'یک ماه', + MM : '%d ماه', + y : 'یک سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/[۰-۹]/g, function (match) { + return numberMap$4[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$5[match]; + }).replace(/,/g, '،'); + }, + dayOfMonthOrdinalParse: /\d{1,2}م/, + ordinal : '%dم', + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), + numbersFuture = [ + 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', + numbersPast[7], numbersPast[8], numbersPast[9] + ]; + function translate$2(number, withoutSuffix, key, isFuture) { + var result = ''; + switch (key) { + case 's': + return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; + case 'ss': + return isFuture ? 'sekunnin' : 'sekuntia'; + case 'm': + return isFuture ? 'minuutin' : 'minuutti'; + case 'mm': + result = isFuture ? 'minuutin' : 'minuuttia'; + break; + case 'h': + return isFuture ? 'tunnin' : 'tunti'; + case 'hh': + result = isFuture ? 'tunnin' : 'tuntia'; + break; + case 'd': + return isFuture ? 'päivän' : 'päivä'; + case 'dd': + result = isFuture ? 'päivän' : 'päivää'; + break; + case 'M': + return isFuture ? 'kuukauden' : 'kuukausi'; + case 'MM': + result = isFuture ? 'kuukauden' : 'kuukautta'; + break; + case 'y': + return isFuture ? 'vuoden' : 'vuosi'; + case 'yy': + result = isFuture ? 'vuoden' : 'vuotta'; + break; + } + result = verbalNumber(number, isFuture) + ' ' + result; + return result; + } + function verbalNumber(number, isFuture) { + return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; + } + + hooks.defineLocale('fi', { + months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), + monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), + weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), + weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), + weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'Do MMMM[ta] YYYY', + LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm', + LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', + l : 'D.M.YYYY', + ll : 'Do MMM YYYY', + lll : 'Do MMM YYYY, [klo] HH.mm', + llll : 'ddd, Do MMM YYYY, [klo] HH.mm' + }, + calendar : { + sameDay : '[tänään] [klo] LT', + nextDay : '[huomenna] [klo] LT', + nextWeek : 'dddd [klo] LT', + lastDay : '[eilen] [klo] LT', + lastWeek : '[viime] dddd[na] [klo] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s päästä', + past : '%s sitten', + s : translate$2, + ss : translate$2, + m : translate$2, + mm : translate$2, + h : translate$2, + hh : translate$2, + d : translate$2, + dd : translate$2, + M : translate$2, + MM : translate$2, + y : translate$2, + yy : translate$2 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('fo', { + months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), + weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), + weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D. MMMM, YYYY HH:mm' + }, + calendar : { + sameDay : '[Í dag kl.] LT', + nextDay : '[Í morgin kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[Í gjár kl.] LT', + lastWeek : '[síðstu] dddd [kl] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'um %s', + past : '%s síðani', + s : 'fá sekund', + ss : '%d sekundir', + m : 'ein minutt', + mm : '%d minuttir', + h : 'ein tími', + hh : '%d tímar', + d : 'ein dagur', + dd : '%d dagar', + M : 'ein mánaði', + MM : '%d mánaðir', + y : 'eitt ár', + yy : '%d ár' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('fr-ca', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal : function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('fr-ch', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal : function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('fr', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|)/, + ordinal : function (number, period) { + switch (period) { + // TODO: Return 'e' when day of month > 1. Move this case inside + // block for masculine words below. + // See https://github.com/moment/moment/issues/3375 + case 'D': + return number + (number === 1 ? 'er' : ''); + + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'); + + hooks.defineLocale('fy', { + months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + monthsParseExact : true, + weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'), + weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'), + weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[hjoed om] LT', + nextDay: '[moarn om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[juster om] LT', + lastWeek: '[ôfrûne] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'oer %s', + past : '%s lyn', + s : 'in pear sekonden', + ss : '%d sekonden', + m : 'ien minút', + mm : '%d minuten', + h : 'ien oere', + hh : '%d oeren', + d : 'ien dei', + dd : '%d dagen', + M : 'ien moanne', + MM : '%d moannen', + y : 'ien jier', + yy : '%d jierren' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var months$5 = [ + 'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd' + ]; + + var monthsShort$4 = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh']; + + var weekdays$1 = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne']; + + var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis']; + + var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; + + hooks.defineLocale('gd', { + months : months$5, + monthsShort : monthsShort$4, + monthsParseExact : true, + weekdays : weekdays$1, + weekdaysShort : weekdaysShort, + weekdaysMin : weekdaysMin, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[An-diugh aig] LT', + nextDay : '[A-màireach aig] LT', + nextWeek : 'dddd [aig] LT', + lastDay : '[An-dè aig] LT', + lastWeek : 'dddd [seo chaidh] [aig] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ann an %s', + past : 'bho chionn %s', + s : 'beagan diogan', + ss : '%d diogan', + m : 'mionaid', + mm : '%d mionaidean', + h : 'uair', + hh : '%d uairean', + d : 'latha', + dd : '%d latha', + M : 'mìos', + MM : '%d mìosan', + y : 'bliadhna', + yy : '%d bliadhna' + }, + dayOfMonthOrdinalParse : /\d{1,2}(d|na|mh)/, + ordinal : function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('gl', { + months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'), + monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextDay : function () { + return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextWeek : function () { + return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + lastDay : function () { + return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; + }, + lastWeek : function () { + return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : function (str) { + if (str.indexOf('un') === 0) { + return 'n' + str; + } + return 'en ' + str; + }, + past : 'hai %s', + s : 'uns segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'unha hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un ano', + yy : '%d anos' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function processRelativeTime$4(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['thodde secondanim', 'thodde second'], + 'ss': [number + ' secondanim', number + ' second'], + 'm': ['eka mintan', 'ek minute'], + 'mm': [number + ' mintanim', number + ' mintam'], + 'h': ['eka horan', 'ek hor'], + 'hh': [number + ' horanim', number + ' horam'], + 'd': ['eka disan', 'ek dis'], + 'dd': [number + ' disanim', number + ' dis'], + 'M': ['eka mhoinean', 'ek mhoino'], + 'MM': [number + ' mhoineanim', number + ' mhoine'], + 'y': ['eka vorsan', 'ek voros'], + 'yy': [number + ' vorsanim', number + ' vorsam'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + hooks.defineLocale('gom-latn', { + months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'), + monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\'var'.split('_'), + weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'), + weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'A h:mm [vazta]', + LTS : 'A h:mm:ss [vazta]', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY A h:mm [vazta]', + LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]', + llll: 'ddd, D MMM YYYY, A h:mm [vazta]' + }, + calendar : { + sameDay: '[Aiz] LT', + nextDay: '[Faleam] LT', + nextWeek: '[Ieta to] dddd[,] LT', + lastDay: '[Kal] LT', + lastWeek: '[Fatlo] dddd[,] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s', + past : '%s adim', + s : processRelativeTime$4, + ss : processRelativeTime$4, + m : processRelativeTime$4, + mm : processRelativeTime$4, + h : processRelativeTime$4, + hh : processRelativeTime$4, + d : processRelativeTime$4, + dd : processRelativeTime$4, + M : processRelativeTime$4, + MM : processRelativeTime$4, + y : processRelativeTime$4, + yy : processRelativeTime$4 + }, + dayOfMonthOrdinalParse : /\d{1,2}(er)/, + ordinal : function (number, period) { + switch (period) { + // the ordinal 'er' only applies to day of the month + case 'D': + return number + 'er'; + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + case 'w': + case 'W': + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + }, + meridiemParse: /rati|sokalli|donparam|sanje/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'rati') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'sokalli') { + return hour; + } else if (meridiem === 'donparam') { + return hour > 12 ? hour : hour + 12; + } else if (meridiem === 'sanje') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'rati'; + } else if (hour < 12) { + return 'sokalli'; + } else if (hour < 16) { + return 'donparam'; + } else if (hour < 20) { + return 'sanje'; + } else { + return 'rati'; + } + } + }); + + //! moment.js locale configuration + + var symbolMap$6 = { + '1': '૧', + '2': '૨', + '3': '૩', + '4': '૪', + '5': '૫', + '6': '૬', + '7': '૭', + '8': '૮', + '9': '૯', + '0': '૦' + }, + numberMap$5 = { + '૧': '1', + '૨': '2', + '૩': '3', + '૪': '4', + '૫': '5', + '૬': '6', + '૭': '7', + '૮': '8', + '૯': '9', + '૦': '0' + }; + + hooks.defineLocale('gu', { + months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split('_'), + monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.'.split('_'), + monthsParseExact: true, + weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split('_'), + weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'), + weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'), + longDateFormat: { + LT: 'A h:mm વાગ્યે', + LTS: 'A h:mm:ss વાગ્યે', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm વાગ્યે', + LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે' + }, + calendar: { + sameDay: '[આજ] LT', + nextDay: '[કાલે] LT', + nextWeek: 'dddd, LT', + lastDay: '[ગઇકાલે] LT', + lastWeek: '[પાછલા] dddd, LT', + sameElse: 'L' + }, + relativeTime: { + future: '%s મા', + past: '%s પેહલા', + s: 'અમુક પળો', + ss: '%d સેકંડ', + m: 'એક મિનિટ', + mm: '%d મિનિટ', + h: 'એક કલાક', + hh: '%d કલાક', + d: 'એક દિવસ', + dd: '%d દિવસ', + M: 'એક મહિનો', + MM: '%d મહિનો', + y: 'એક વર્ષ', + yy: '%d વર્ષ' + }, + preparse: function (string) { + return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) { + return numberMap$5[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$6[match]; + }); + }, + // Gujarati notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati. + meridiemParse: /રાત|બપોર|સવાર|સાંજ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'રાત') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'સવાર') { + return hour; + } else if (meridiem === 'બપોર') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'સાંજ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'રાત'; + } else if (hour < 10) { + return 'સવાર'; + } else if (hour < 17) { + return 'બપોર'; + } else if (hour < 20) { + return 'સાંજ'; + } else { + return 'રાત'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('he', { + months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), + monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), + weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), + weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), + weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [ב]MMMM YYYY', + LLL : 'D [ב]MMMM YYYY HH:mm', + LLLL : 'dddd, D [ב]MMMM YYYY HH:mm', + l : 'D/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' + }, + calendar : { + sameDay : '[היום ב־]LT', + nextDay : '[מחר ב־]LT', + nextWeek : 'dddd [בשעה] LT', + lastDay : '[אתמול ב־]LT', + lastWeek : '[ביום] dddd [האחרון בשעה] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'בעוד %s', + past : 'לפני %s', + s : 'מספר שניות', + ss : '%d שניות', + m : 'דקה', + mm : '%d דקות', + h : 'שעה', + hh : function (number) { + if (number === 2) { + return 'שעתיים'; + } + return number + ' שעות'; + }, + d : 'יום', + dd : function (number) { + if (number === 2) { + return 'יומיים'; + } + return number + ' ימים'; + }, + M : 'חודש', + MM : function (number) { + if (number === 2) { + return 'חודשיים'; + } + return number + ' חודשים'; + }, + y : 'שנה', + yy : function (number) { + if (number === 2) { + return 'שנתיים'; + } else if (number % 10 === 0 && number !== 10) { + return number + ' שנה'; + } + return number + ' שנים'; + } + }, + meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i, + isPM : function (input) { + return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 5) { + return 'לפנות בוקר'; + } else if (hour < 10) { + return 'בבוקר'; + } else if (hour < 12) { + return isLower ? 'לפנה"צ' : 'לפני הצהריים'; + } else if (hour < 18) { + return isLower ? 'אחה"צ' : 'אחרי הצהריים'; + } else { + return 'בערב'; + } + } + }); + + //! moment.js locale configuration + + var symbolMap$7 = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap$6 = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + hooks.defineLocale('hi', { + months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), + monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), + monthsParseExact: true, + weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat : { + LT : 'A h:mm बजे', + LTS : 'A h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, A h:mm बजे' + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[कल] LT', + nextWeek : 'dddd, LT', + lastDay : '[कल] LT', + lastWeek : '[पिछले] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s में', + past : '%s पहले', + s : 'कुछ ही क्षण', + ss : '%d सेकंड', + m : 'एक मिनट', + mm : '%d मिनट', + h : 'एक घंटा', + hh : '%d घंटे', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महीने', + MM : '%d महीने', + y : 'एक वर्ष', + yy : '%d वर्ष' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap$6[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$7[match]; + }); + }, + // Hindi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. + meridiemParse: /रात|सुबह|दोपहर|शाम/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सुबह') { + return hour; + } else if (meridiem === 'दोपहर') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'शाम') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'रात'; + } else if (hour < 10) { + return 'सुबह'; + } else if (hour < 17) { + return 'दोपहर'; + } else if (hour < 20) { + return 'शाम'; + } else { + return 'रात'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + function translate$3(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + hooks.defineLocale('hr', { + months : { + format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'), + standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_') + }, + monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), + monthsParseExact: true, + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + ss : translate$3, + m : translate$3, + mm : translate$3, + h : translate$3, + hh : translate$3, + d : 'dan', + dd : translate$3, + M : 'mjesec', + MM : translate$3, + y : 'godinu', + yy : translate$3 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); + function translate$4(number, withoutSuffix, key, isFuture) { + var num = number; + switch (key) { + case 's': + return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; + case 'ss': + return num + (isFuture || withoutSuffix) ? ' másodperc' : ' másodperce'; + case 'm': + return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'mm': + return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'h': + return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'hh': + return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'd': + return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'dd': + return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'M': + return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'MM': + return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'y': + return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); + case 'yy': + return num + (isFuture || withoutSuffix ? ' év' : ' éve'); + } + return ''; + } + function week(isFuture) { + return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; + } + + hooks.defineLocale('hu', { + months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), + monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), + weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), + weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), + weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY. MMMM D.', + LLL : 'YYYY. MMMM D. H:mm', + LLLL : 'YYYY. MMMM D., dddd H:mm' + }, + meridiemParse: /de|du/i, + isPM: function (input) { + return input.charAt(1).toLowerCase() === 'u'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower === true ? 'de' : 'DE'; + } else { + return isLower === true ? 'du' : 'DU'; + } + }, + calendar : { + sameDay : '[ma] LT[-kor]', + nextDay : '[holnap] LT[-kor]', + nextWeek : function () { + return week.call(this, true); + }, + lastDay : '[tegnap] LT[-kor]', + lastWeek : function () { + return week.call(this, false); + }, + sameElse : 'L' + }, + relativeTime : { + future : '%s múlva', + past : '%s', + s : translate$4, + ss : translate$4, + m : translate$4, + mm : translate$4, + h : translate$4, + hh : translate$4, + d : translate$4, + dd : translate$4, + M : translate$4, + MM : translate$4, + y : translate$4, + yy : translate$4 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('hy-am', { + months : { + format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'), + standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_') + }, + monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), + weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'), + weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY թ.', + LLL : 'D MMMM YYYY թ., HH:mm', + LLLL : 'dddd, D MMMM YYYY թ., HH:mm' + }, + calendar : { + sameDay: '[այսօր] LT', + nextDay: '[վաղը] LT', + lastDay: '[երեկ] LT', + nextWeek: function () { + return 'dddd [օրը ժամը] LT'; + }, + lastWeek: function () { + return '[անցած] dddd [օրը ժամը] LT'; + }, + sameElse: 'L' + }, + relativeTime : { + future : '%s հետո', + past : '%s առաջ', + s : 'մի քանի վայրկյան', + ss : '%d վայրկյան', + m : 'րոպե', + mm : '%d րոպե', + h : 'ժամ', + hh : '%d ժամ', + d : 'օր', + dd : '%d օր', + M : 'ամիս', + MM : '%d ամիս', + y : 'տարի', + yy : '%d տարի' + }, + meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, + isPM: function (input) { + return /^(ցերեկվա|երեկոյան)$/.test(input); + }, + meridiem : function (hour) { + if (hour < 4) { + return 'գիշերվա'; + } else if (hour < 12) { + return 'առավոտվա'; + } else if (hour < 17) { + return 'ցերեկվա'; + } else { + return 'երեկոյան'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, + ordinal: function (number, period) { + switch (period) { + case 'DDD': + case 'w': + case 'W': + case 'DDDo': + if (number === 1) { + return number + '-ին'; + } + return number + '-րդ'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('id', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|siang|sore|malam/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'siang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sore' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'siang'; + } else if (hours < 19) { + return 'sore'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Besok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kemarin pukul] LT', + lastWeek : 'dddd [lalu pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lalu', + s : 'beberapa detik', + ss : '%d detik', + m : 'semenit', + mm : '%d menit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + function plural$2(n) { + if (n % 100 === 11) { + return true; + } else if (n % 10 === 1) { + return false; + } + return true; + } + function translate$5(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; + case 'ss': + if (plural$2(number)) { + return result + (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum'); + } + return result + 'sekúnda'; + case 'm': + return withoutSuffix ? 'mínúta' : 'mínútu'; + case 'mm': + if (plural$2(number)) { + return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); + } else if (withoutSuffix) { + return result + 'mínúta'; + } + return result + 'mínútu'; + case 'hh': + if (plural$2(number)) { + return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); + } + return result + 'klukkustund'; + case 'd': + if (withoutSuffix) { + return 'dagur'; + } + return isFuture ? 'dag' : 'degi'; + case 'dd': + if (plural$2(number)) { + if (withoutSuffix) { + return result + 'dagar'; + } + return result + (isFuture ? 'daga' : 'dögum'); + } else if (withoutSuffix) { + return result + 'dagur'; + } + return result + (isFuture ? 'dag' : 'degi'); + case 'M': + if (withoutSuffix) { + return 'mánuður'; + } + return isFuture ? 'mánuð' : 'mánuði'; + case 'MM': + if (plural$2(number)) { + if (withoutSuffix) { + return result + 'mánuðir'; + } + return result + (isFuture ? 'mánuði' : 'mánuðum'); + } else if (withoutSuffix) { + return result + 'mánuður'; + } + return result + (isFuture ? 'mánuð' : 'mánuði'); + case 'y': + return withoutSuffix || isFuture ? 'ár' : 'ári'; + case 'yy': + if (plural$2(number)) { + return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); + } + return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); + } + } + + hooks.defineLocale('is', { + months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), + weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), + weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), + weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm' + }, + calendar : { + sameDay : '[í dag kl.] LT', + nextDay : '[á morgun kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[í gær kl.] LT', + lastWeek : '[síðasta] dddd [kl.] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'eftir %s', + past : 'fyrir %s síðan', + s : translate$5, + ss : translate$5, + m : translate$5, + mm : translate$5, + h : 'klukkustund', + hh : translate$5, + d : translate$5, + dd : translate$5, + M : translate$5, + MM : translate$5, + y : translate$5, + yy : translate$5 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('it', { + months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), + monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'), + weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'), + weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Oggi alle] LT', + nextDay: '[Domani alle] LT', + nextWeek: 'dddd [alle] LT', + lastDay: '[Ieri alle] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[la scorsa] dddd [alle] LT'; + default: + return '[lo scorso] dddd [alle] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : function (s) { + return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; + }, + past : '%s fa', + s : 'alcuni secondi', + ss : '%d secondi', + m : 'un minuto', + mm : '%d minuti', + h : 'un\'ora', + hh : '%d ore', + d : 'un giorno', + dd : '%d giorni', + M : 'un mese', + MM : '%d mesi', + y : 'un anno', + yy : '%d anni' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ja', { + months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), + weekdaysShort : '日_月_火_水_木_金_土'.split('_'), + weekdaysMin : '日_月_火_水_木_金_土'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日 dddd HH:mm', + l : 'YYYY/MM/DD', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日(ddd) HH:mm' + }, + meridiemParse: /午前|午後/i, + isPM : function (input) { + return input === '午後'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return '午前'; + } else { + return '午後'; + } + }, + calendar : { + sameDay : '[今日] LT', + nextDay : '[明日] LT', + nextWeek : function (now) { + if (now.week() < this.week()) { + return '[来週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + lastDay : '[昨日] LT', + lastWeek : function (now) { + if (this.week() < now.week()) { + return '[先週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + sameElse : 'L' + }, + dayOfMonthOrdinalParse : /\d{1,2}日/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + default: + return number; + } + }, + relativeTime : { + future : '%s後', + past : '%s前', + s : '数秒', + ss : '%d秒', + m : '1分', + mm : '%d分', + h : '1時間', + hh : '%d時間', + d : '1日', + dd : '%d日', + M : '1ヶ月', + MM : '%dヶ月', + y : '1年', + yy : '%d年' + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('jv', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), + weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /enjing|siyang|sonten|ndalu/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'enjing') { + return hour; + } else if (meridiem === 'siyang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sonten' || meridiem === 'ndalu') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'enjing'; + } else if (hours < 15) { + return 'siyang'; + } else if (hours < 19) { + return 'sonten'; + } else { + return 'ndalu'; + } + }, + calendar : { + sameDay : '[Dinten puniko pukul] LT', + nextDay : '[Mbenjang pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kala wingi pukul] LT', + lastWeek : 'dddd [kepengker pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'wonten ing %s', + past : '%s ingkang kepengker', + s : 'sawetawis detik', + ss : '%d detik', + m : 'setunggal menit', + mm : '%d menit', + h : 'setunggal jam', + hh : '%d jam', + d : 'sedinten', + dd : '%d dinten', + M : 'sewulan', + MM : '%d wulan', + y : 'setaun', + yy : '%d taun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ka', { + months : { + standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), + format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') + }, + monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), + weekdays : { + standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), + format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'), + isFormat: /(წინა|შემდეგ)/ + }, + weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), + weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[დღეს] LT[-ზე]', + nextDay : '[ხვალ] LT[-ზე]', + lastDay : '[გუშინ] LT[-ზე]', + nextWeek : '[შემდეგ] dddd LT[-ზე]', + lastWeek : '[წინა] dddd LT-ზე', + sameElse : 'L' + }, + relativeTime : { + future : function (s) { + return (/(წამი|წუთი|საათი|წელი)/).test(s) ? + s.replace(/ი$/, 'ში') : + s + 'ში'; + }, + past : function (s) { + if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { + return s.replace(/(ი|ე)$/, 'ის წინ'); + } + if ((/წელი/).test(s)) { + return s.replace(/წელი$/, 'წლის წინ'); + } + }, + s : 'რამდენიმე წამი', + ss : '%d წამი', + m : 'წუთი', + mm : '%d წუთი', + h : 'საათი', + hh : '%d საათი', + d : 'დღე', + dd : '%d დღე', + M : 'თვე', + MM : '%d თვე', + y : 'წელი', + yy : '%d წელი' + }, + dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, + ordinal : function (number) { + if (number === 0) { + return number; + } + if (number === 1) { + return number + '-ლი'; + } + if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { + return 'მე-' + number; + } + return number + '-ე'; + }, + week : { + dow : 1, + doy : 7 + } + }); + + //! moment.js locale configuration + + var suffixes$1 = { + 0: '-ші', + 1: '-ші', + 2: '-ші', + 3: '-ші', + 4: '-ші', + 5: '-ші', + 6: '-шы', + 7: '-ші', + 8: '-ші', + 9: '-шы', + 10: '-шы', + 20: '-шы', + 30: '-шы', + 40: '-шы', + 50: '-ші', + 60: '-шы', + 70: '-ші', + 80: '-ші', + 90: '-шы', + 100: '-ші' + }; + + hooks.defineLocale('kk', { + months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'), + monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'), + weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'), + weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'), + weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Бүгін сағат] LT', + nextDay : '[Ертең сағат] LT', + nextWeek : 'dddd [сағат] LT', + lastDay : '[Кеше сағат] LT', + lastWeek : '[Өткен аптаның] dddd [сағат] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ішінде', + past : '%s бұрын', + s : 'бірнеше секунд', + ss : '%d секунд', + m : 'бір минут', + mm : '%d минут', + h : 'бір сағат', + hh : '%d сағат', + d : 'бір күн', + dd : '%d күн', + M : 'бір ай', + MM : '%d ай', + y : 'бір жыл', + yy : '%d жыл' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes$1[number] || suffixes$1[a] || suffixes$1[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$8 = { + '1': '១', + '2': '២', + '3': '៣', + '4': '៤', + '5': '៥', + '6': '៦', + '7': '៧', + '8': '៨', + '9': '៩', + '0': '០' + }, numberMap$7 = { + '១': '1', + '២': '2', + '៣': '3', + '៤': '4', + '៥': '5', + '៦': '6', + '៧': '7', + '៨': '8', + '៩': '9', + '០': '0' + }; + + hooks.defineLocale('km', { + months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysShort: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysMin: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /ព្រឹក|ល្ងាច/, + isPM: function (input) { + return input === 'ល្ងាច'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ព្រឹក'; + } else { + return 'ល្ងាច'; + } + }, + calendar: { + sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', + nextDay: '[ស្អែក ម៉ោង] LT', + nextWeek: 'dddd [ម៉ោង] LT', + lastDay: '[ម្សិលមិញ ម៉ោង] LT', + lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', + sameElse: 'L' + }, + relativeTime: { + future: '%sទៀត', + past: '%sមុន', + s: 'ប៉ុន្មានវិនាទី', + ss: '%d វិនាទី', + m: 'មួយនាទី', + mm: '%d នាទី', + h: 'មួយម៉ោង', + hh: '%d ម៉ោង', + d: 'មួយថ្ងៃ', + dd: '%d ថ្ងៃ', + M: 'មួយខែ', + MM: '%d ខែ', + y: 'មួយឆ្នាំ', + yy: '%d ឆ្នាំ' + }, + dayOfMonthOrdinalParse : /ទី\d{1,2}/, + ordinal : 'ទី%d', + preparse: function (string) { + return string.replace(/[១២៣៤៥៦៧៨៩០]/g, function (match) { + return numberMap$7[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$8[match]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$9 = { + '1': '೧', + '2': '೨', + '3': '೩', + '4': '೪', + '5': '೫', + '6': '೬', + '7': '೭', + '8': '೮', + '9': '೯', + '0': '೦' + }, + numberMap$8 = { + '೧': '1', + '೨': '2', + '೩': '3', + '೪': '4', + '೫': '5', + '೬': '6', + '೭': '7', + '೮': '8', + '೯': '9', + '೦': '0' + }; + + hooks.defineLocale('kn', { + months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'), + monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ'.split('_'), + monthsParseExact: true, + weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'), + weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'), + weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[ಇಂದು] LT', + nextDay : '[ನಾಳೆ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ನಿನ್ನೆ] LT', + lastWeek : '[ಕೊನೆಯ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ನಂತರ', + past : '%s ಹಿಂದೆ', + s : 'ಕೆಲವು ಕ್ಷಣಗಳು', + ss : '%d ಸೆಕೆಂಡುಗಳು', + m : 'ಒಂದು ನಿಮಿಷ', + mm : '%d ನಿಮಿಷ', + h : 'ಒಂದು ಗಂಟೆ', + hh : '%d ಗಂಟೆ', + d : 'ಒಂದು ದಿನ', + dd : '%d ದಿನ', + M : 'ಒಂದು ತಿಂಗಳು', + MM : '%d ತಿಂಗಳು', + y : 'ಒಂದು ವರ್ಷ', + yy : '%d ವರ್ಷ' + }, + preparse: function (string) { + return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) { + return numberMap$8[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$9[match]; + }); + }, + meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ರಾತ್ರಿ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') { + return hour; + } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ಸಂಜೆ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ರಾತ್ರಿ'; + } else if (hour < 10) { + return 'ಬೆಳಿಗ್ಗೆ'; + } else if (hour < 17) { + return 'ಮಧ್ಯಾಹ್ನ'; + } else if (hour < 20) { + return 'ಸಂಜೆ'; + } else { + return 'ರಾತ್ರಿ'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/, + ordinal : function (number) { + return number + 'ನೇ'; + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ko', { + months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), + weekdaysShort : '일_월_화_수_목_금_토'.split('_'), + weekdaysMin : '일_월_화_수_목_금_토'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY년 MMMM D일', + LLL : 'YYYY년 MMMM D일 A h:mm', + LLLL : 'YYYY년 MMMM D일 dddd A h:mm', + l : 'YYYY.MM.DD.', + ll : 'YYYY년 MMMM D일', + lll : 'YYYY년 MMMM D일 A h:mm', + llll : 'YYYY년 MMMM D일 dddd A h:mm' + }, + calendar : { + sameDay : '오늘 LT', + nextDay : '내일 LT', + nextWeek : 'dddd LT', + lastDay : '어제 LT', + lastWeek : '지난주 dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s 후', + past : '%s 전', + s : '몇 초', + ss : '%d초', + m : '1분', + mm : '%d분', + h : '한 시간', + hh : '%d시간', + d : '하루', + dd : '%d일', + M : '한 달', + MM : '%d달', + y : '일 년', + yy : '%d년' + }, + dayOfMonthOrdinalParse : /\d{1,2}(일|월|주)/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '일'; + case 'M': + return number + '월'; + case 'w': + case 'W': + return number + '주'; + default: + return number; + } + }, + meridiemParse : /오전|오후/, + isPM : function (token) { + return token === '오후'; + }, + meridiem : function (hour, minute, isUpper) { + return hour < 12 ? '오전' : '오후'; + } + }); + + //! moment.js locale configuration + + var suffixes$2 = { + 0: '-чү', + 1: '-чи', + 2: '-чи', + 3: '-чү', + 4: '-чү', + 5: '-чи', + 6: '-чы', + 7: '-чи', + 8: '-чи', + 9: '-чу', + 10: '-чу', + 20: '-чы', + 30: '-чу', + 40: '-чы', + 50: '-чү', + 60: '-чы', + 70: '-чи', + 80: '-чи', + 90: '-чу', + 100: '-чү' + }; + + hooks.defineLocale('ky', { + months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), + monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'), + weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'), + weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Бүгүн саат] LT', + nextDay : '[Эртең саат] LT', + nextWeek : 'dddd [саат] LT', + lastDay : '[Кече саат] LT', + lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ичинде', + past : '%s мурун', + s : 'бирнече секунд', + ss : '%d секунд', + m : 'бир мүнөт', + mm : '%d мүнөт', + h : 'бир саат', + hh : '%d саат', + d : 'бир күн', + dd : '%d күн', + M : 'бир ай', + MM : '%d ай', + y : 'бир жыл', + yy : '%d жыл' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes$2[number] || suffixes$2[a] || suffixes$2[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + function processRelativeTime$5(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eng Minutt', 'enger Minutt'], + 'h': ['eng Stonn', 'enger Stonn'], + 'd': ['een Dag', 'engem Dag'], + 'M': ['ee Mount', 'engem Mount'], + 'y': ['ee Joer', 'engem Joer'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + function processFutureTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'a ' + string; + } + return 'an ' + string; + } + function processPastTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'viru ' + string; + } + return 'virun ' + string; + } + /** + * Returns true if the word before the given number loses the '-n' ending. + * e.g. 'an 10 Deeg' but 'a 5 Deeg' + * + * @param number {integer} + * @returns {boolean} + */ + function eifelerRegelAppliesToNumber(number) { + number = parseInt(number, 10); + if (isNaN(number)) { + return false; + } + if (number < 0) { + // Negative Number --> always true + return true; + } else if (number < 10) { + // Only 1 digit + if (4 <= number && number <= 7) { + return true; + } + return false; + } else if (number < 100) { + // 2 digits + var lastDigit = number % 10, firstDigit = number / 10; + if (lastDigit === 0) { + return eifelerRegelAppliesToNumber(firstDigit); + } + return eifelerRegelAppliesToNumber(lastDigit); + } else if (number < 10000) { + // 3 or 4 digits --> recursively check first digit + while (number >= 10) { + number = number / 10; + } + return eifelerRegelAppliesToNumber(number); + } else { + // Anything larger than 4 digits: recursively check first n-3 digits + number = number / 1000; + return eifelerRegelAppliesToNumber(number); + } + } + + hooks.defineLocale('lb', { + months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), + weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm [Auer]', + LTS: 'H:mm:ss [Auer]', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm [Auer]', + LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]' + }, + calendar: { + sameDay: '[Haut um] LT', + sameElse: 'L', + nextDay: '[Muer um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gëschter um] LT', + lastWeek: function () { + // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule + switch (this.day()) { + case 2: + case 4: + return '[Leschten] dddd [um] LT'; + default: + return '[Leschte] dddd [um] LT'; + } + } + }, + relativeTime : { + future : processFutureTime, + past : processPastTime, + s : 'e puer Sekonnen', + ss : '%d Sekonnen', + m : processRelativeTime$5, + mm : '%d Minutten', + h : processRelativeTime$5, + hh : '%d Stonnen', + d : processRelativeTime$5, + dd : '%d Deeg', + M : processRelativeTime$5, + MM : '%d Méint', + y : processRelativeTime$5, + yy : '%d Joer' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('lo', { + months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'ວັນdddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, + isPM: function (input) { + return input === 'ຕອນແລງ'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ຕອນເຊົ້າ'; + } else { + return 'ຕອນແລງ'; + } + }, + calendar : { + sameDay : '[ມື້ນີ້ເວລາ] LT', + nextDay : '[ມື້ອື່ນເວລາ] LT', + nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT', + lastDay : '[ມື້ວານນີ້ເວລາ] LT', + lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ອີກ %s', + past : '%sຜ່ານມາ', + s : 'ບໍ່ເທົ່າໃດວິນາທີ', + ss : '%d ວິນາທີ' , + m : '1 ນາທີ', + mm : '%d ນາທີ', + h : '1 ຊົ່ວໂມງ', + hh : '%d ຊົ່ວໂມງ', + d : '1 ມື້', + dd : '%d ມື້', + M : '1 ເດືອນ', + MM : '%d ເດືອນ', + y : '1 ປີ', + yy : '%d ປີ' + }, + dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/, + ordinal : function (number) { + return 'ທີ່' + number; + } + }); + + //! moment.js locale configuration + + var units = { + 'ss' : 'sekundė_sekundžių_sekundes', + 'm' : 'minutė_minutės_minutę', + 'mm': 'minutės_minučių_minutes', + 'h' : 'valanda_valandos_valandą', + 'hh': 'valandos_valandų_valandas', + 'd' : 'diena_dienos_dieną', + 'dd': 'dienos_dienų_dienas', + 'M' : 'mėnuo_mėnesio_mėnesį', + 'MM': 'mėnesiai_mėnesių_mėnesius', + 'y' : 'metai_metų_metus', + 'yy': 'metai_metų_metus' + }; + function translateSeconds(number, withoutSuffix, key, isFuture) { + if (withoutSuffix) { + return 'kelios sekundės'; + } else { + return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; + } + } + function translateSingular(number, withoutSuffix, key, isFuture) { + return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); + } + function special(number) { + return number % 10 === 0 || (number > 10 && number < 20); + } + function forms(key) { + return units[key].split('_'); + } + function translate$6(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + if (number === 1) { + return result + translateSingular(number, withoutSuffix, key[0], isFuture); + } else if (withoutSuffix) { + return result + (special(number) ? forms(key)[1] : forms(key)[0]); + } else { + if (isFuture) { + return result + forms(key)[1]; + } else { + return result + (special(number) ? forms(key)[1] : forms(key)[2]); + } + } + } + hooks.defineLocale('lt', { + months : { + format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), + standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'), + isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/ + }, + monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), + weekdays : { + format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'), + standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'), + isFormat: /dddd HH:mm/ + }, + weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), + weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY [m.] MMMM D [d.]', + LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', + l : 'YYYY-MM-DD', + ll : 'YYYY [m.] MMMM D [d.]', + lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]' + }, + calendar : { + sameDay : '[Šiandien] LT', + nextDay : '[Rytoj] LT', + nextWeek : 'dddd LT', + lastDay : '[Vakar] LT', + lastWeek : '[Praėjusį] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'po %s', + past : 'prieš %s', + s : translateSeconds, + ss : translate$6, + m : translateSingular, + mm : translate$6, + h : translateSingular, + hh : translate$6, + d : translateSingular, + dd : translate$6, + M : translateSingular, + MM : translate$6, + y : translateSingular, + yy : translate$6 + }, + dayOfMonthOrdinalParse: /\d{1,2}-oji/, + ordinal : function (number) { + return number + '-oji'; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var units$1 = { + 'ss': 'sekundes_sekundēm_sekunde_sekundes'.split('_'), + 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'h': 'stundas_stundām_stunda_stundas'.split('_'), + 'hh': 'stundas_stundām_stunda_stundas'.split('_'), + 'd': 'dienas_dienām_diena_dienas'.split('_'), + 'dd': 'dienas_dienām_diena_dienas'.split('_'), + 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'y': 'gada_gadiem_gads_gadi'.split('_'), + 'yy': 'gada_gadiem_gads_gadi'.split('_') + }; + /** + * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. + */ + function format$1(forms, number, withoutSuffix) { + if (withoutSuffix) { + // E.g. "21 minūte", "3 minūtes". + return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3]; + } else { + // E.g. "21 minūtes" as in "pēc 21 minūtes". + // E.g. "3 minūtēm" as in "pēc 3 minūtēm". + return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1]; + } + } + function relativeTimeWithPlural$1(number, withoutSuffix, key) { + return number + ' ' + format$1(units$1[key], number, withoutSuffix); + } + function relativeTimeWithSingular(number, withoutSuffix, key) { + return format$1(units$1[key], number, withoutSuffix); + } + function relativeSeconds(number, withoutSuffix) { + return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; + } + + hooks.defineLocale('lv', { + months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), + weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY.', + LL : 'YYYY. [gada] D. MMMM', + LLL : 'YYYY. [gada] D. MMMM, HH:mm', + LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm' + }, + calendar : { + sameDay : '[Šodien pulksten] LT', + nextDay : '[Rīt pulksten] LT', + nextWeek : 'dddd [pulksten] LT', + lastDay : '[Vakar pulksten] LT', + lastWeek : '[Pagājušā] dddd [pulksten] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'pēc %s', + past : 'pirms %s', + s : relativeSeconds, + ss : relativeTimeWithPlural$1, + m : relativeTimeWithSingular, + mm : relativeTimeWithPlural$1, + h : relativeTimeWithSingular, + hh : relativeTimeWithPlural$1, + d : relativeTimeWithSingular, + dd : relativeTimeWithPlural$1, + M : relativeTimeWithSingular, + MM : relativeTimeWithPlural$1, + y : relativeTimeWithSingular, + yy : relativeTimeWithPlural$1 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var translator = { + words: { //Different grammatical cases + ss: ['sekund', 'sekunda', 'sekundi'], + m: ['jedan minut', 'jednog minuta'], + mm: ['minut', 'minuta', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mjesec', 'mjeseca', 'mjeseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } + }; + + hooks.defineLocale('me', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact : true, + weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sjutra u] LT', + + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedjelje] [u] LT', + '[prošlog] [ponedjeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srijede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'nekoliko sekundi', + ss : translator.translate, + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : 'dan', + dd : translator.translate, + M : 'mjesec', + MM : translator.translate, + y : 'godinu', + yy : translator.translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('mi', { + months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'), + monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'), + monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i, + weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'), + weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [i] HH:mm', + LLLL: 'dddd, D MMMM YYYY [i] HH:mm' + }, + calendar: { + sameDay: '[i teie mahana, i] LT', + nextDay: '[apopo i] LT', + nextWeek: 'dddd [i] LT', + lastDay: '[inanahi i] LT', + lastWeek: 'dddd [whakamutunga i] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'i roto i %s', + past: '%s i mua', + s: 'te hēkona ruarua', + ss: '%d hēkona', + m: 'he meneti', + mm: '%d meneti', + h: 'te haora', + hh: '%d haora', + d: 'he ra', + dd: '%d ra', + M: 'he marama', + MM: '%d marama', + y: 'he tau', + yy: '%d tau' + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('mk', { + months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), + weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), + weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Денес во] LT', + nextDay : '[Утре во] LT', + nextWeek : '[Во] dddd [во] LT', + lastDay : '[Вчера во] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[Изминатата] dddd [во] LT'; + case 1: + case 2: + case 4: + case 5: + return '[Изминатиот] dddd [во] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'после %s', + past : 'пред %s', + s : 'неколку секунди', + ss : '%d секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дена', + M : 'месец', + MM : '%d месеци', + y : 'година', + yy : '%d години' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ml', { + months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), + monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), + monthsParseExact : true, + weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), + weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), + weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), + longDateFormat : { + LT : 'A h:mm -നു', + LTS : 'A h:mm:ss -നു', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm -നു', + LLLL : 'dddd, D MMMM YYYY, A h:mm -നു' + }, + calendar : { + sameDay : '[ഇന്ന്] LT', + nextDay : '[നാളെ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ഇന്നലെ] LT', + lastWeek : '[കഴിഞ്ഞ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s കഴിഞ്ഞ്', + past : '%s മുൻപ്', + s : 'അൽപ നിമിഷങ്ങൾ', + ss : '%d സെക്കൻഡ്', + m : 'ഒരു മിനിറ്റ്', + mm : '%d മിനിറ്റ്', + h : 'ഒരു മണിക്കൂർ', + hh : '%d മണിക്കൂർ', + d : 'ഒരു ദിവസം', + dd : '%d ദിവസം', + M : 'ഒരു മാസം', + MM : '%d മാസം', + y : 'ഒരു വർഷം', + yy : '%d വർഷം' + }, + meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'രാത്രി' && hour >= 4) || + meridiem === 'ഉച്ച കഴിഞ്ഞ്' || + meridiem === 'വൈകുന്നേരം') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'രാത്രി'; + } else if (hour < 12) { + return 'രാവിലെ'; + } else if (hour < 17) { + return 'ഉച്ച കഴിഞ്ഞ്'; + } else if (hour < 20) { + return 'വൈകുന്നേരം'; + } else { + return 'രാത്രി'; + } + } + }); + + //! moment.js locale configuration + + function translate$7(number, withoutSuffix, key, isFuture) { + switch (key) { + case 's': + return withoutSuffix ? 'хэдхэн секунд' : 'хэдхэн секундын'; + case 'ss': + return number + (withoutSuffix ? ' секунд' : ' секундын'); + case 'm': + case 'mm': + return number + (withoutSuffix ? ' минут' : ' минутын'); + case 'h': + case 'hh': + return number + (withoutSuffix ? ' цаг' : ' цагийн'); + case 'd': + case 'dd': + return number + (withoutSuffix ? ' өдөр' : ' өдрийн'); + case 'M': + case 'MM': + return number + (withoutSuffix ? ' сар' : ' сарын'); + case 'y': + case 'yy': + return number + (withoutSuffix ? ' жил' : ' жилийн'); + default: + return number; + } + } + + hooks.defineLocale('mn', { + months : 'Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар'.split('_'), + monthsShort : '1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар'.split('_'), + monthsParseExact : true, + weekdays : 'Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба'.split('_'), + weekdaysShort : 'Ням_Дав_Мяг_Лха_Пүр_Баа_Бям'.split('_'), + weekdaysMin : 'Ня_Да_Мя_Лх_Пү_Ба_Бя'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY оны MMMMын D', + LLL : 'YYYY оны MMMMын D HH:mm', + LLLL : 'dddd, YYYY оны MMMMын D HH:mm' + }, + meridiemParse: /ҮӨ|ҮХ/i, + isPM : function (input) { + return input === 'ҮХ'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ҮӨ'; + } else { + return 'ҮХ'; + } + }, + calendar : { + sameDay : '[Өнөөдөр] LT', + nextDay : '[Маргааш] LT', + nextWeek : '[Ирэх] dddd LT', + lastDay : '[Өчигдөр] LT', + lastWeek : '[Өнгөрсөн] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s дараа', + past : '%s өмнө', + s : translate$7, + ss : translate$7, + m : translate$7, + mm : translate$7, + h : translate$7, + hh : translate$7, + d : translate$7, + dd : translate$7, + M : translate$7, + MM : translate$7, + y : translate$7, + yy : translate$7 + }, + dayOfMonthOrdinalParse: /\d{1,2} өдөр/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + ' өдөр'; + default: + return number; + } + } + }); + + //! moment.js locale configuration + + var symbolMap$a = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap$9 = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + function relativeTimeMr(number, withoutSuffix, string, isFuture) + { + var output = ''; + if (withoutSuffix) { + switch (string) { + case 's': output = 'काही सेकंद'; break; + case 'ss': output = '%d सेकंद'; break; + case 'm': output = 'एक मिनिट'; break; + case 'mm': output = '%d मिनिटे'; break; + case 'h': output = 'एक तास'; break; + case 'hh': output = '%d तास'; break; + case 'd': output = 'एक दिवस'; break; + case 'dd': output = '%d दिवस'; break; + case 'M': output = 'एक महिना'; break; + case 'MM': output = '%d महिने'; break; + case 'y': output = 'एक वर्ष'; break; + case 'yy': output = '%d वर्षे'; break; + } + } + else { + switch (string) { + case 's': output = 'काही सेकंदां'; break; + case 'ss': output = '%d सेकंदां'; break; + case 'm': output = 'एका मिनिटा'; break; + case 'mm': output = '%d मिनिटां'; break; + case 'h': output = 'एका तासा'; break; + case 'hh': output = '%d तासां'; break; + case 'd': output = 'एका दिवसा'; break; + case 'dd': output = '%d दिवसां'; break; + case 'M': output = 'एका महिन्या'; break; + case 'MM': output = '%d महिन्यां'; break; + case 'y': output = 'एका वर्षा'; break; + case 'yy': output = '%d वर्षां'; break; + } + } + return output.replace(/%d/i, number); + } + + hooks.defineLocale('mr', { + months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), + monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), + monthsParseExact : true, + weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat : { + LT : 'A h:mm वाजता', + LTS : 'A h:mm:ss वाजता', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm वाजता', + LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता' + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[उद्या] LT', + nextWeek : 'dddd, LT', + lastDay : '[काल] LT', + lastWeek: '[मागील] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future: '%sमध्ये', + past: '%sपूर्वी', + s: relativeTimeMr, + ss: relativeTimeMr, + m: relativeTimeMr, + mm: relativeTimeMr, + h: relativeTimeMr, + hh: relativeTimeMr, + d: relativeTimeMr, + dd: relativeTimeMr, + M: relativeTimeMr, + MM: relativeTimeMr, + y: relativeTimeMr, + yy: relativeTimeMr + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap$9[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$a[match]; + }); + }, + meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात्री') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सकाळी') { + return hour; + } else if (meridiem === 'दुपारी') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'सायंकाळी') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'रात्री'; + } else if (hour < 10) { + return 'सकाळी'; + } else if (hour < 17) { + return 'दुपारी'; + } else if (hour < 20) { + return 'सायंकाळी'; + } else { + return 'रात्री'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ms-my', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + ss : '%d saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ms', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + ss : '%d saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('mt', { + months : 'Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru'.split('_'), + monthsShort : 'Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ'.split('_'), + weekdays : 'Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt'.split('_'), + weekdaysShort : 'Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib'.split('_'), + weekdaysMin : 'Ħa_Tn_Tl_Er_Ħa_Ġi_Si'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Illum fil-]LT', + nextDay : '[Għada fil-]LT', + nextWeek : 'dddd [fil-]LT', + lastDay : '[Il-bieraħ fil-]LT', + lastWeek : 'dddd [li għadda] [fil-]LT', + sameElse : 'L' + }, + relativeTime : { + future : 'f’ %s', + past : '%s ilu', + s : 'ftit sekondi', + ss : '%d sekondi', + m : 'minuta', + mm : '%d minuti', + h : 'siegħa', + hh : '%d siegħat', + d : 'ġurnata', + dd : '%d ġranet', + M : 'xahar', + MM : '%d xhur', + y : 'sena', + yy : '%d sni' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$b = { + '1': '၁', + '2': '၂', + '3': '၃', + '4': '၄', + '5': '၅', + '6': '၆', + '7': '၇', + '8': '၈', + '9': '၉', + '0': '၀' + }, numberMap$a = { + '၁': '1', + '၂': '2', + '၃': '3', + '၄': '4', + '၅': '5', + '၆': '6', + '၇': '7', + '၈': '8', + '၉': '9', + '၀': '0' + }; + + hooks.defineLocale('my', { + months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), + monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), + weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), + weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[ယနေ.] LT [မှာ]', + nextDay: '[မနက်ဖြန်] LT [မှာ]', + nextWeek: 'dddd LT [မှာ]', + lastDay: '[မနေ.က] LT [မှာ]', + lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', + sameElse: 'L' + }, + relativeTime: { + future: 'လာမည့် %s မှာ', + past: 'လွန်ခဲ့သော %s က', + s: 'စက္ကန်.အနည်းငယ်', + ss : '%d စက္ကန့်', + m: 'တစ်မိနစ်', + mm: '%d မိနစ်', + h: 'တစ်နာရီ', + hh: '%d နာရီ', + d: 'တစ်ရက်', + dd: '%d ရက်', + M: 'တစ်လ', + MM: '%d လ', + y: 'တစ်နှစ်', + yy: '%d နှစ်' + }, + preparse: function (string) { + return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { + return numberMap$a[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$b[match]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('nb', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), + monthsParseExact : true, + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay: '[i dag kl.] LT', + nextDay: '[i morgen kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[i går kl.] LT', + lastWeek: '[forrige] dddd [kl.] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s siden', + s : 'noen sekunder', + ss : '%d sekunder', + m : 'ett minutt', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dager', + M : 'en måned', + MM : '%d måneder', + y : 'ett år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$c = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap$b = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + hooks.defineLocale('ne', { + months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), + monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), + monthsParseExact : true, + weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), + weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), + weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'Aको h:mm बजे', + LTS : 'Aको h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, Aको h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap$b[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$c[match]; + }); + }, + meridiemParse: /राति|बिहान|दिउँसो|साँझ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'राति') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'बिहान') { + return hour; + } else if (meridiem === 'दिउँसो') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'साँझ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 3) { + return 'राति'; + } else if (hour < 12) { + return 'बिहान'; + } else if (hour < 16) { + return 'दिउँसो'; + } else if (hour < 20) { + return 'साँझ'; + } else { + return 'राति'; + } + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[भोलि] LT', + nextWeek : '[आउँदो] dddd[,] LT', + lastDay : '[हिजो] LT', + lastWeek : '[गएको] dddd[,] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%sमा', + past : '%s अगाडि', + s : 'केही क्षण', + ss : '%d सेकेण्ड', + m : 'एक मिनेट', + mm : '%d मिनेट', + h : 'एक घण्टा', + hh : '%d घण्टा', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महिना', + MM : '%d महिना', + y : 'एक बर्ष', + yy : '%d बर्ष' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var monthsShortWithDots$1 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsShortWithoutDots$1 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); + + var monthsParse$2 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; + var monthsRegex$3 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; + + hooks.defineLocale('nl-be', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots$1; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots$1[m.month()]; + } else { + return monthsShortWithDots$1[m.month()]; + } + }, + + monthsRegex: monthsRegex$3, + monthsShortRegex: monthsRegex$3, + monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + + monthsParse : monthsParse$2, + longMonthsParse : monthsParse$2, + shortMonthsParse : monthsParse$2, + + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + ss : '%d seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var monthsShortWithDots$2 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsShortWithoutDots$2 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); + + var monthsParse$3 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; + var monthsRegex$4 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; + + hooks.defineLocale('nl', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots$2; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots$2[m.month()]; + } else { + return monthsShortWithDots$2[m.month()]; + } + }, + + monthsRegex: monthsRegex$4, + monthsShortRegex: monthsRegex$4, + monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + + monthsParse : monthsParse$3, + longMonthsParse : monthsParse$3, + shortMonthsParse : monthsParse$3, + + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + ss : '%d seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('nn', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), + weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), + weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay: '[I dag klokka] LT', + nextDay: '[I morgon klokka] LT', + nextWeek: 'dddd [klokka] LT', + lastDay: '[I går klokka] LT', + lastWeek: '[Føregåande] dddd [klokka] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s sidan', + s : 'nokre sekund', + ss : '%d sekund', + m : 'eit minutt', + mm : '%d minutt', + h : 'ein time', + hh : '%d timar', + d : 'ein dag', + dd : '%d dagar', + M : 'ein månad', + MM : '%d månader', + y : 'eit år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$d = { + '1': '੧', + '2': '੨', + '3': '੩', + '4': '੪', + '5': '੫', + '6': '੬', + '7': '੭', + '8': '੮', + '9': '੯', + '0': '੦' + }, + numberMap$c = { + '੧': '1', + '੨': '2', + '੩': '3', + '੪': '4', + '੫': '5', + '੬': '6', + '੭': '7', + '੮': '8', + '੯': '9', + '੦': '0' + }; + + hooks.defineLocale('pa-in', { + // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi. + months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'), + weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + longDateFormat : { + LT : 'A h:mm ਵਜੇ', + LTS : 'A h:mm:ss ਵਜੇ', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm ਵਜੇ', + LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ' + }, + calendar : { + sameDay : '[ਅਜ] LT', + nextDay : '[ਕਲ] LT', + nextWeek : '[ਅਗਲਾ] dddd, LT', + lastDay : '[ਕਲ] LT', + lastWeek : '[ਪਿਛਲੇ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ਵਿੱਚ', + past : '%s ਪਿਛਲੇ', + s : 'ਕੁਝ ਸਕਿੰਟ', + ss : '%d ਸਕਿੰਟ', + m : 'ਇਕ ਮਿੰਟ', + mm : '%d ਮਿੰਟ', + h : 'ਇੱਕ ਘੰਟਾ', + hh : '%d ਘੰਟੇ', + d : 'ਇੱਕ ਦਿਨ', + dd : '%d ਦਿਨ', + M : 'ਇੱਕ ਮਹੀਨਾ', + MM : '%d ਮਹੀਨੇ', + y : 'ਇੱਕ ਸਾਲ', + yy : '%d ਸਾਲ' + }, + preparse: function (string) { + return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) { + return numberMap$c[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$d[match]; + }); + }, + // Punjabi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi. + meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ਰਾਤ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ਸਵੇਰ') { + return hour; + } else if (meridiem === 'ਦੁਪਹਿਰ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ਸ਼ਾਮ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ਰਾਤ'; + } else if (hour < 10) { + return 'ਸਵੇਰ'; + } else if (hour < 17) { + return 'ਦੁਪਹਿਰ'; + } else if (hour < 20) { + return 'ਸ਼ਾਮ'; + } else { + return 'ਰਾਤ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), + monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); + function plural$3(n) { + return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); + } + function translate$8(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + return result + (plural$3(number) ? 'sekundy' : 'sekund'); + case 'm': + return withoutSuffix ? 'minuta' : 'minutę'; + case 'mm': + return result + (plural$3(number) ? 'minuty' : 'minut'); + case 'h': + return withoutSuffix ? 'godzina' : 'godzinę'; + case 'hh': + return result + (plural$3(number) ? 'godziny' : 'godzin'); + case 'MM': + return result + (plural$3(number) ? 'miesiące' : 'miesięcy'); + case 'yy': + return result + (plural$3(number) ? 'lata' : 'lat'); + } + } + + hooks.defineLocale('pl', { + months : function (momentToFormat, format) { + if (!momentToFormat) { + return monthsNominative; + } else if (format === '') { + // Hack: if format empty we know this is used to generate + // RegExp by moment. Give then back both valid forms of months + // in RegExp ready format. + return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')'; + } else if (/D MMMM/.test(format)) { + return monthsSubjective[momentToFormat.month()]; + } else { + return monthsNominative[momentToFormat.month()]; + } + }, + monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), + weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), + weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'), + weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Dziś o] LT', + nextDay: '[Jutro o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[W niedzielę o] LT'; + + case 2: + return '[We wtorek o] LT'; + + case 3: + return '[W środę o] LT'; + + case 6: + return '[W sobotę o] LT'; + + default: + return '[W] dddd [o] LT'; + } + }, + lastDay: '[Wczoraj o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[W zeszłą niedzielę o] LT'; + case 3: + return '[W zeszłą środę o] LT'; + case 6: + return '[W zeszłą sobotę o] LT'; + default: + return '[W zeszły] dddd [o] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : '%s temu', + s : 'kilka sekund', + ss : translate$8, + m : translate$8, + mm : translate$8, + h : translate$8, + hh : translate$8, + d : '1 dzień', + dd : '%d dni', + M : 'miesiąc', + MM : translate$8, + y : 'rok', + yy : translate$8 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('pt-br', { + months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), + monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), + weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY [às] HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm' + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : 'em %s', + past : 'há %s', + s : 'poucos segundos', + ss : '%d segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal : '%dº' + }); + + //! moment.js locale configuration + + hooks.defineLocale('pt', { + months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), + monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), + weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : 'em %s', + past : 'há %s', + s : 'segundos', + ss : '%d segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function relativeTimeWithPlural$2(number, withoutSuffix, key) { + var format = { + 'ss': 'secunde', + 'mm': 'minute', + 'hh': 'ore', + 'dd': 'zile', + 'MM': 'luni', + 'yy': 'ani' + }, + separator = ' '; + if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { + separator = ' de '; + } + return number + separator + format[key]; + } + + hooks.defineLocale('ro', { + months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), + monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), + weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), + weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay: '[azi la] LT', + nextDay: '[mâine la] LT', + nextWeek: 'dddd [la] LT', + lastDay: '[ieri la] LT', + lastWeek: '[fosta] dddd [la] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'peste %s', + past : '%s în urmă', + s : 'câteva secunde', + ss : relativeTimeWithPlural$2, + m : 'un minut', + mm : relativeTimeWithPlural$2, + h : 'o oră', + hh : relativeTimeWithPlural$2, + d : 'o zi', + dd : relativeTimeWithPlural$2, + M : 'o lună', + MM : relativeTimeWithPlural$2, + y : 'un an', + yy : relativeTimeWithPlural$2 + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + function plural$4(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function relativeTimeWithPlural$3(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', + 'hh': 'час_часа_часов', + 'dd': 'день_дня_дней', + 'MM': 'месяц_месяца_месяцев', + 'yy': 'год_года_лет' + }; + if (key === 'm') { + return withoutSuffix ? 'минута' : 'минуту'; + } + else { + return number + ' ' + plural$4(format[key], +number); + } + } + var monthsParse$4 = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; + + // http://new.gramota.ru/spravka/rules/139-prop : § 103 + // Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637 + // CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753 + hooks.defineLocale('ru', { + months : { + format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'), + standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_') + }, + monthsShort : { + // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ? + format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'), + standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_') + }, + weekdays : { + standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), + format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'), + isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/ + }, + weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + monthsParse : monthsParse$4, + longMonthsParse : monthsParse$4, + shortMonthsParse : monthsParse$4, + + // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки + monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, + + // копия предыдущего + monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, + + // полные названия с падежами + monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i, + + // Выражение, которое соотвествует только сокращённым формам + monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., H:mm', + LLLL : 'dddd, D MMMM YYYY г., H:mm' + }, + calendar : { + sameDay: '[Сегодня, в] LT', + nextDay: '[Завтра, в] LT', + lastDay: '[Вчера, в] LT', + nextWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В следующее] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В следующий] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В следующую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + lastWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В прошлое] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В прошлый] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В прошлую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'через %s', + past : '%s назад', + s : 'несколько секунд', + ss : relativeTimeWithPlural$3, + m : relativeTimeWithPlural$3, + mm : relativeTimeWithPlural$3, + h : 'час', + hh : relativeTimeWithPlural$3, + d : 'день', + dd : relativeTimeWithPlural$3, + M : 'месяц', + MM : relativeTimeWithPlural$3, + y : 'год', + yy : relativeTimeWithPlural$3 + }, + meridiemParse: /ночи|утра|дня|вечера/i, + isPM : function (input) { + return /^(дня|вечера)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночи'; + } else if (hour < 12) { + return 'утра'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечера'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + return number + '-й'; + case 'D': + return number + '-го'; + case 'w': + case 'W': + return number + '-я'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var months$6 = [ + 'جنوري', + 'فيبروري', + 'مارچ', + 'اپريل', + 'مئي', + 'جون', + 'جولاءِ', + 'آگسٽ', + 'سيپٽمبر', + 'آڪٽوبر', + 'نومبر', + 'ڊسمبر' + ]; + var days$1 = [ + 'آچر', + 'سومر', + 'اڱارو', + 'اربع', + 'خميس', + 'جمع', + 'ڇنڇر' + ]; + + hooks.defineLocale('sd', { + months : months$6, + monthsShort : months$6, + weekdays : days$1, + weekdaysShort : days$1, + weekdaysMin : days$1, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd، D MMMM YYYY HH:mm' + }, + meridiemParse: /صبح|شام/, + isPM : function (input) { + return 'شام' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'صبح'; + } + return 'شام'; + }, + calendar : { + sameDay : '[اڄ] LT', + nextDay : '[سڀاڻي] LT', + nextWeek : 'dddd [اڳين هفتي تي] LT', + lastDay : '[ڪالهه] LT', + lastWeek : '[گزريل هفتي] dddd [تي] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s پوء', + past : '%s اڳ', + s : 'چند سيڪنڊ', + ss : '%d سيڪنڊ', + m : 'هڪ منٽ', + mm : '%d منٽ', + h : 'هڪ ڪلاڪ', + hh : '%d ڪلاڪ', + d : 'هڪ ڏينهن', + dd : '%d ڏينهن', + M : 'هڪ مهينو', + MM : '%d مهينا', + y : 'هڪ سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('se', { + months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'), + monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'), + weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'), + weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), + weekdaysMin : 's_v_m_g_d_b_L'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'MMMM D. [b.] YYYY', + LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm', + LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm' + }, + calendar : { + sameDay: '[otne ti] LT', + nextDay: '[ihttin ti] LT', + nextWeek: 'dddd [ti] LT', + lastDay: '[ikte ti] LT', + lastWeek: '[ovddit] dddd [ti] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s geažes', + past : 'maŋit %s', + s : 'moadde sekunddat', + ss: '%d sekunddat', + m : 'okta minuhta', + mm : '%d minuhtat', + h : 'okta diimmu', + hh : '%d diimmut', + d : 'okta beaivi', + dd : '%d beaivvit', + M : 'okta mánnu', + MM : '%d mánut', + y : 'okta jahki', + yy : '%d jagit' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + /*jshint -W100*/ + hooks.defineLocale('si', { + months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'), + monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'), + weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'), + weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), + weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'a h:mm', + LTS : 'a h:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY MMMM D', + LLL : 'YYYY MMMM D, a h:mm', + LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss' + }, + calendar : { + sameDay : '[අද] LT[ට]', + nextDay : '[හෙට] LT[ට]', + nextWeek : 'dddd LT[ට]', + lastDay : '[ඊයේ] LT[ට]', + lastWeek : '[පසුගිය] dddd LT[ට]', + sameElse : 'L' + }, + relativeTime : { + future : '%sකින්', + past : '%sකට පෙර', + s : 'තත්පර කිහිපය', + ss : 'තත්පර %d', + m : 'මිනිත්තුව', + mm : 'මිනිත්තු %d', + h : 'පැය', + hh : 'පැය %d', + d : 'දිනය', + dd : 'දින %d', + M : 'මාසය', + MM : 'මාස %d', + y : 'වසර', + yy : 'වසර %d' + }, + dayOfMonthOrdinalParse: /\d{1,2} වැනි/, + ordinal : function (number) { + return number + ' වැනි'; + }, + meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./, + isPM : function (input) { + return input === 'ප.ව.' || input === 'පස් වරු'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'ප.ව.' : 'පස් වරු'; + } else { + return isLower ? 'පෙ.ව.' : 'පෙර වරු'; + } + } + }); + + //! moment.js locale configuration + + var months$7 = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), + monthsShort$5 = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); + function plural$5(n) { + return (n > 1) && (n < 5); + } + function translate$9(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural$5(number) ? 'sekundy' : 'sekúnd'); + } else { + return result + 'sekundami'; + } + break; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural$5(number) ? 'minúty' : 'minút'); + } else { + return result + 'minútami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural$5(number) ? 'hodiny' : 'hodín'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural$5(number) ? 'dni' : 'dní'); + } else { + return result + 'dňami'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural$5(number) ? 'mesiace' : 'mesiacov'); + } else { + return result + 'mesiacmi'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural$5(number) ? 'roky' : 'rokov'); + } else { + return result + 'rokmi'; + } + break; + } + } + + hooks.defineLocale('sk', { + months : months$7, + monthsShort : monthsShort$5, + weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), + weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), + weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), + longDateFormat : { + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm' + }, + calendar : { + sameDay: '[dnes o] LT', + nextDay: '[zajtra o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v nedeľu o] LT'; + case 1: + case 2: + return '[v] dddd [o] LT'; + case 3: + return '[v stredu o] LT'; + case 4: + return '[vo štvrtok o] LT'; + case 5: + return '[v piatok o] LT'; + case 6: + return '[v sobotu o] LT'; + } + }, + lastDay: '[včera o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulú nedeľu o] LT'; + case 1: + case 2: + return '[minulý] dddd [o] LT'; + case 3: + return '[minulú stredu o] LT'; + case 4: + case 5: + return '[minulý] dddd [o] LT'; + case 6: + return '[minulú sobotu o] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : 'pred %s', + s : translate$9, + ss : translate$9, + m : translate$9, + mm : translate$9, + h : translate$9, + hh : translate$9, + d : translate$9, + dd : translate$9, + M : translate$9, + MM : translate$9, + y : translate$9, + yy : translate$9 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + function processRelativeTime$6(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami'; + case 'ss': + if (number === 1) { + result += withoutSuffix ? 'sekundo' : 'sekundi'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'sekundi' : 'sekundah'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'sekunde' : 'sekundah'; + } else { + result += withoutSuffix || isFuture ? 'sekund' : 'sekund'; + } + return result; + case 'm': + return withoutSuffix ? 'ena minuta' : 'eno minuto'; + case 'mm': + if (number === 1) { + result += withoutSuffix ? 'minuta' : 'minuto'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'minute' : 'minutami'; + } else { + result += withoutSuffix || isFuture ? 'minut' : 'minutami'; + } + return result; + case 'h': + return withoutSuffix ? 'ena ura' : 'eno uro'; + case 'hh': + if (number === 1) { + result += withoutSuffix ? 'ura' : 'uro'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'uri' : 'urama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'ure' : 'urami'; + } else { + result += withoutSuffix || isFuture ? 'ur' : 'urami'; + } + return result; + case 'd': + return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; + case 'dd': + if (number === 1) { + result += withoutSuffix || isFuture ? 'dan' : 'dnem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; + } else { + result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; + } + return result; + case 'M': + return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; + case 'MM': + if (number === 1) { + result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; + } else { + result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; + } + return result; + case 'y': + return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; + case 'yy': + if (number === 1) { + result += withoutSuffix || isFuture ? 'leto' : 'letom'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'leti' : 'letoma'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'leta' : 'leti'; + } else { + result += withoutSuffix || isFuture ? 'let' : 'leti'; + } + return result; + } + } + + hooks.defineLocale('sl', { + months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), + weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), + weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danes ob] LT', + nextDay : '[jutri ob] LT', + + nextWeek : function () { + switch (this.day()) { + case 0: + return '[v] [nedeljo] [ob] LT'; + case 3: + return '[v] [sredo] [ob] LT'; + case 6: + return '[v] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[v] dddd [ob] LT'; + } + }, + lastDay : '[včeraj ob] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + return '[prejšnjo] [nedeljo] [ob] LT'; + case 3: + return '[prejšnjo] [sredo] [ob] LT'; + case 6: + return '[prejšnjo] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prejšnji] dddd [ob] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'čez %s', + past : 'pred %s', + s : processRelativeTime$6, + ss : processRelativeTime$6, + m : processRelativeTime$6, + mm : processRelativeTime$6, + h : processRelativeTime$6, + hh : processRelativeTime$6, + d : processRelativeTime$6, + dd : processRelativeTime$6, + M : processRelativeTime$6, + MM : processRelativeTime$6, + y : processRelativeTime$6, + yy : processRelativeTime$6 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('sq', { + months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), + monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), + weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), + weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), + weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), + weekdaysParseExact : true, + meridiemParse: /PD|MD/, + isPM: function (input) { + return input.charAt(0) === 'M'; + }, + meridiem : function (hours, minutes, isLower) { + return hours < 12 ? 'PD' : 'MD'; + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Sot në] LT', + nextDay : '[Nesër në] LT', + nextWeek : 'dddd [në] LT', + lastDay : '[Dje në] LT', + lastWeek : 'dddd [e kaluar në] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'në %s', + past : '%s më parë', + s : 'disa sekonda', + ss : '%d sekonda', + m : 'një minutë', + mm : '%d minuta', + h : 'një orë', + hh : '%d orë', + d : 'një ditë', + dd : '%d ditë', + M : 'një muaj', + MM : '%d muaj', + y : 'një vit', + yy : '%d vite' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var translator$1 = { + words: { //Different grammatical cases + ss: ['секунда', 'секунде', 'секунди'], + m: ['један минут', 'једне минуте'], + mm: ['минут', 'минуте', 'минута'], + h: ['један сат', 'једног сата'], + hh: ['сат', 'сата', 'сати'], + dd: ['дан', 'дана', 'дана'], + MM: ['месец', 'месеца', 'месеци'], + yy: ['година', 'године', 'година'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator$1.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator$1.correctGrammaticalCase(number, wordKey); + } + } + }; + + hooks.defineLocale('sr-cyrl', { + months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'), + monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'), + monthsParseExact: true, + weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'), + weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'), + weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[данас у] LT', + nextDay: '[сутра у] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[у] [недељу] [у] LT'; + case 3: + return '[у] [среду] [у] LT'; + case 6: + return '[у] [суботу] [у] LT'; + case 1: + case 2: + case 4: + case 5: + return '[у] dddd [у] LT'; + } + }, + lastDay : '[јуче у] LT', + lastWeek : function () { + var lastWeekDays = [ + '[прошле] [недеље] [у] LT', + '[прошлог] [понедељка] [у] LT', + '[прошлог] [уторка] [у] LT', + '[прошле] [среде] [у] LT', + '[прошлог] [четвртка] [у] LT', + '[прошлог] [петка] [у] LT', + '[прошле] [суботе] [у] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'за %s', + past : 'пре %s', + s : 'неколико секунди', + ss : translator$1.translate, + m : translator$1.translate, + mm : translator$1.translate, + h : translator$1.translate, + hh : translator$1.translate, + d : 'дан', + dd : translator$1.translate, + M : 'месец', + MM : translator$1.translate, + y : 'годину', + yy : translator$1.translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var translator$2 = { + words: { //Different grammatical cases + ss: ['sekunda', 'sekunde', 'sekundi'], + m: ['jedan minut', 'jedne minute'], + mm: ['minut', 'minute', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mesec', 'meseca', 'meseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator$2.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator$2.correctGrammaticalCase(number, wordKey); + } + } + }; + + hooks.defineLocale('sr', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'), + weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedelju] [u] LT'; + case 3: + return '[u] [sredu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedelje] [u] LT', + '[prošlog] [ponedeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'pre %s', + s : 'nekoliko sekundi', + ss : translator$2.translate, + m : translator$2.translate, + mm : translator$2.translate, + h : translator$2.translate, + hh : translator$2.translate, + d : 'dan', + dd : translator$2.translate, + M : 'mesec', + MM : translator$2.translate, + y : 'godinu', + yy : translator$2.translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('ss', { + months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'), + monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'), + weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'), + weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'), + weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Namuhla nga] LT', + nextDay : '[Kusasa nga] LT', + nextWeek : 'dddd [nga] LT', + lastDay : '[Itolo nga] LT', + lastWeek : 'dddd [leliphelile] [nga] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'nga %s', + past : 'wenteka nga %s', + s : 'emizuzwana lomcane', + ss : '%d mzuzwana', + m : 'umzuzu', + mm : '%d emizuzu', + h : 'lihora', + hh : '%d emahora', + d : 'lilanga', + dd : '%d emalanga', + M : 'inyanga', + MM : '%d tinyanga', + y : 'umnyaka', + yy : '%d iminyaka' + }, + meridiemParse: /ekuseni|emini|entsambama|ebusuku/, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'ekuseni'; + } else if (hours < 15) { + return 'emini'; + } else if (hours < 19) { + return 'entsambama'; + } else { + return 'ebusuku'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ekuseni') { + return hour; + } else if (meridiem === 'emini') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') { + if (hour === 0) { + return 0; + } + return hour + 12; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : '%d', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('sv', { + months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), + weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), + weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D MMMM YYYY [kl.] HH:mm', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd D MMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Idag] LT', + nextDay: '[Imorgon] LT', + lastDay: '[Igår] LT', + nextWeek: '[På] dddd LT', + lastWeek: '[I] dddd[s] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : 'för %s sedan', + s : 'några sekunder', + ss : '%d sekunder', + m : 'en minut', + mm : '%d minuter', + h : 'en timme', + hh : '%d timmar', + d : 'en dag', + dd : '%d dagar', + M : 'en månad', + MM : '%d månader', + y : 'ett år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}(e|a)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'e' : + (b === 1) ? 'a' : + (b === 2) ? 'a' : + (b === 3) ? 'e' : 'e'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('sw', { + months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'), + weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), + weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[leo saa] LT', + nextDay : '[kesho saa] LT', + nextWeek : '[wiki ijayo] dddd [saat] LT', + lastDay : '[jana] LT', + lastWeek : '[wiki iliyopita] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s baadaye', + past : 'tokea %s', + s : 'hivi punde', + ss : 'sekunde %d', + m : 'dakika moja', + mm : 'dakika %d', + h : 'saa limoja', + hh : 'masaa %d', + d : 'siku moja', + dd : 'masiku %d', + M : 'mwezi mmoja', + MM : 'miezi %d', + y : 'mwaka mmoja', + yy : 'miaka %d' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var symbolMap$e = { + '1': '௧', + '2': '௨', + '3': '௩', + '4': '௪', + '5': '௫', + '6': '௬', + '7': '௭', + '8': '௮', + '9': '௯', + '0': '௦' + }, numberMap$d = { + '௧': '1', + '௨': '2', + '௩': '3', + '௪': '4', + '௫': '5', + '௬': '6', + '௭': '7', + '௮': '8', + '௯': '9', + '௦': '0' + }; + + hooks.defineLocale('ta', { + months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), + weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), + weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, HH:mm', + LLLL : 'dddd, D MMMM YYYY, HH:mm' + }, + calendar : { + sameDay : '[இன்று] LT', + nextDay : '[நாளை] LT', + nextWeek : 'dddd, LT', + lastDay : '[நேற்று] LT', + lastWeek : '[கடந்த வாரம்] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s இல்', + past : '%s முன்', + s : 'ஒரு சில விநாடிகள்', + ss : '%d விநாடிகள்', + m : 'ஒரு நிமிடம்', + mm : '%d நிமிடங்கள்', + h : 'ஒரு மணி நேரம்', + hh : '%d மணி நேரம்', + d : 'ஒரு நாள்', + dd : '%d நாட்கள்', + M : 'ஒரு மாதம்', + MM : '%d மாதங்கள்', + y : 'ஒரு வருடம்', + yy : '%d ஆண்டுகள்' + }, + dayOfMonthOrdinalParse: /\d{1,2}வது/, + ordinal : function (number) { + return number + 'வது'; + }, + preparse: function (string) { + return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { + return numberMap$d[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap$e[match]; + }); + }, + // refer http://ta.wikipedia.org/s/1er1 + meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, + meridiem : function (hour, minute, isLower) { + if (hour < 2) { + return ' யாமம்'; + } else if (hour < 6) { + return ' வைகறை'; // வைகறை + } else if (hour < 10) { + return ' காலை'; // காலை + } else if (hour < 14) { + return ' நண்பகல்'; // நண்பகல் + } else if (hour < 18) { + return ' எற்பாடு'; // எற்பாடு + } else if (hour < 22) { + return ' மாலை'; // மாலை + } else { + return ' யாமம்'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'யாமம்') { + return hour < 2 ? hour : hour + 12; + } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { + return hour; + } else if (meridiem === 'நண்பகல்') { + return hour >= 10 ? hour : hour + 12; + } else { + return hour + 12; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('te', { + months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'), + monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'), + monthsParseExact : true, + weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'), + weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), + weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[నేడు] LT', + nextDay : '[రేపు] LT', + nextWeek : 'dddd, LT', + lastDay : '[నిన్న] LT', + lastWeek : '[గత] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s లో', + past : '%s క్రితం', + s : 'కొన్ని క్షణాలు', + ss : '%d సెకన్లు', + m : 'ఒక నిమిషం', + mm : '%d నిమిషాలు', + h : 'ఒక గంట', + hh : '%d గంటలు', + d : 'ఒక రోజు', + dd : '%d రోజులు', + M : 'ఒక నెల', + MM : '%d నెలలు', + y : 'ఒక సంవత్సరం', + yy : '%d సంవత్సరాలు' + }, + dayOfMonthOrdinalParse : /\d{1,2}వ/, + ordinal : '%dవ', + meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'రాత్రి') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ఉదయం') { + return hour; + } else if (meridiem === 'మధ్యాహ్నం') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'సాయంత్రం') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'రాత్రి'; + } else if (hour < 10) { + return 'ఉదయం'; + } else if (hour < 17) { + return 'మధ్యాహ్నం'; + } else if (hour < 20) { + return 'సాయంత్రం'; + } else { + return 'రాత్రి'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('tet', { + months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'), + weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'), + weekdaysMin : 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Ohin iha] LT', + nextDay: '[Aban iha] LT', + nextWeek: 'dddd [iha] LT', + lastDay: '[Horiseik iha] LT', + lastWeek: 'dddd [semana kotuk] [iha] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'iha %s', + past : '%s liuba', + s : 'minutu balun', + ss : 'minutu %d', + m : 'minutu ida', + mm : 'minutu %d', + h : 'oras ida', + hh : 'oras %d', + d : 'loron ida', + dd : 'loron %d', + M : 'fulan ida', + MM : 'fulan %d', + y : 'tinan ida', + yy : 'tinan %d' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var suffixes$3 = { + 0: '-ум', + 1: '-ум', + 2: '-юм', + 3: '-юм', + 4: '-ум', + 5: '-ум', + 6: '-ум', + 7: '-ум', + 8: '-ум', + 9: '-ум', + 10: '-ум', + 12: '-ум', + 13: '-ум', + 20: '-ум', + 30: '-юм', + 40: '-ум', + 50: '-ум', + 60: '-ум', + 70: '-ум', + 80: '-ум', + 90: '-ум', + 100: '-ум' + }; + + hooks.defineLocale('tg', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split('_'), + weekdaysShort : 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'), + weekdaysMin : 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Имрӯз соати] LT', + nextDay : '[Пагоҳ соати] LT', + lastDay : '[Дирӯз соати] LT', + nextWeek : 'dddd[и] [ҳафтаи оянда соати] LT', + lastWeek : 'dddd[и] [ҳафтаи гузашта соати] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'баъди %s', + past : '%s пеш', + s : 'якчанд сония', + m : 'як дақиқа', + mm : '%d дақиқа', + h : 'як соат', + hh : '%d соат', + d : 'як рӯз', + dd : '%d рӯз', + M : 'як моҳ', + MM : '%d моҳ', + y : 'як сол', + yy : '%d сол' + }, + meridiemParse: /шаб|субҳ|рӯз|бегоҳ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'шаб') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'субҳ') { + return hour; + } else if (meridiem === 'рӯз') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'бегоҳ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'шаб'; + } else if (hour < 11) { + return 'субҳ'; + } else if (hour < 16) { + return 'рӯз'; + } else if (hour < 19) { + return 'бегоҳ'; + } else { + return 'шаб'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ум|юм)/, + ordinal: function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes$3[number] || suffixes$3[a] || suffixes$3[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('th', { + months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), + monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'), + monthsParseExact: true, + weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), + weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference + weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY เวลา H:mm', + LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm' + }, + meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, + isPM: function (input) { + return input === 'หลังเที่ยง'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ก่อนเที่ยง'; + } else { + return 'หลังเที่ยง'; + } + }, + calendar : { + sameDay : '[วันนี้ เวลา] LT', + nextDay : '[พรุ่งนี้ เวลา] LT', + nextWeek : 'dddd[หน้า เวลา] LT', + lastDay : '[เมื่อวานนี้ เวลา] LT', + lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'อีก %s', + past : '%sที่แล้ว', + s : 'ไม่กี่วินาที', + ss : '%d วินาที', + m : '1 นาที', + mm : '%d นาที', + h : '1 ชั่วโมง', + hh : '%d ชั่วโมง', + d : '1 วัน', + dd : '%d วัน', + M : '1 เดือน', + MM : '%d เดือน', + y : '1 ปี', + yy : '%d ปี' + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('tl-ph', { + months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), + monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), + weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), + weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), + weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'MM/D/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY HH:mm', + LLLL : 'dddd, MMMM DD, YYYY HH:mm' + }, + calendar : { + sameDay: 'LT [ngayong araw]', + nextDay: '[Bukas ng] LT', + nextWeek: 'LT [sa susunod na] dddd', + lastDay: 'LT [kahapon]', + lastWeek: 'LT [noong nakaraang] dddd', + sameElse: 'L' + }, + relativeTime : { + future : 'sa loob ng %s', + past : '%s ang nakalipas', + s : 'ilang segundo', + ss : '%d segundo', + m : 'isang minuto', + mm : '%d minuto', + h : 'isang oras', + hh : '%d oras', + d : 'isang araw', + dd : '%d araw', + M : 'isang buwan', + MM : '%d buwan', + y : 'isang taon', + yy : '%d taon' + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); + + function translateFuture(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'leS' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'waQ' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'nem' : + time + ' pIq'; + return time; + } + + function translatePast(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'Hu’' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'wen' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'ben' : + time + ' ret'; + return time; + } + + function translate$a(number, withoutSuffix, string, isFuture) { + var numberNoun = numberAsNoun(number); + switch (string) { + case 'ss': + return numberNoun + ' lup'; + case 'mm': + return numberNoun + ' tup'; + case 'hh': + return numberNoun + ' rep'; + case 'dd': + return numberNoun + ' jaj'; + case 'MM': + return numberNoun + ' jar'; + case 'yy': + return numberNoun + ' DIS'; + } + } + + function numberAsNoun(number) { + var hundred = Math.floor((number % 1000) / 100), + ten = Math.floor((number % 100) / 10), + one = number % 10, + word = ''; + if (hundred > 0) { + word += numbersNouns[hundred] + 'vatlh'; + } + if (ten > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH'; + } + if (one > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[one]; + } + return (word === '') ? 'pagh' : word; + } + + hooks.defineLocale('tlh', { + months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'), + monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'), + monthsParseExact : true, + weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[DaHjaj] LT', + nextDay: '[wa’leS] LT', + nextWeek: 'LLL', + lastDay: '[wa’Hu’] LT', + lastWeek: 'LLL', + sameElse: 'L' + }, + relativeTime : { + future : translateFuture, + past : translatePast, + s : 'puS lup', + ss : translate$a, + m : 'wa’ tup', + mm : translate$a, + h : 'wa’ rep', + hh : translate$a, + d : 'wa’ jaj', + dd : translate$a, + M : 'wa’ jar', + MM : translate$a, + y : 'wa’ DIS', + yy : translate$a + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + var suffixes$4 = { + 1: '\'inci', + 5: '\'inci', + 8: '\'inci', + 70: '\'inci', + 80: '\'inci', + 2: '\'nci', + 7: '\'nci', + 20: '\'nci', + 50: '\'nci', + 3: '\'üncü', + 4: '\'üncü', + 100: '\'üncü', + 6: '\'ncı', + 9: '\'uncu', + 10: '\'uncu', + 30: '\'uncu', + 60: '\'ıncı', + 90: '\'ıncı' + }; + + hooks.defineLocale('tr', { + months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), + monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), + weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), + weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), + weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[yarın saat] LT', + nextWeek : '[gelecek] dddd [saat] LT', + lastDay : '[dün] LT', + lastWeek : '[geçen] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s sonra', + past : '%s önce', + s : 'birkaç saniye', + ss : '%d saniye', + m : 'bir dakika', + mm : '%d dakika', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir yıl', + yy : '%d yıl' + }, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'Do': + case 'DD': + return number; + default: + if (number === 0) { // special case for zero + return number + '\'ıncı'; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (suffixes$4[a] || suffixes$4[b] || suffixes$4[c]); + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. + // This is currently too difficult (maybe even impossible) to add. + hooks.defineLocale('tzl', { + months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'), + monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), + weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), + weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), + weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM [dallas] YYYY', + LLL : 'D. MMMM [dallas] YYYY HH.mm', + LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm' + }, + meridiemParse: /d\'o|d\'a/i, + isPM : function (input) { + return 'd\'o' === input.toLowerCase(); + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'd\'o' : 'D\'O'; + } else { + return isLower ? 'd\'a' : 'D\'A'; + } + }, + calendar : { + sameDay : '[oxhi à] LT', + nextDay : '[demà à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[ieiri à] LT', + lastWeek : '[sür el] dddd [lasteu à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'osprei %s', + past : 'ja%s', + s : processRelativeTime$7, + ss : processRelativeTime$7, + m : processRelativeTime$7, + mm : processRelativeTime$7, + h : processRelativeTime$7, + hh : processRelativeTime$7, + d : processRelativeTime$7, + dd : processRelativeTime$7, + M : processRelativeTime$7, + MM : processRelativeTime$7, + y : processRelativeTime$7, + yy : processRelativeTime$7 + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + function processRelativeTime$7(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['viensas secunds', '\'iensas secunds'], + 'ss': [number + ' secunds', '' + number + ' secunds'], + 'm': ['\'n míut', '\'iens míut'], + 'mm': [number + ' míuts', '' + number + ' míuts'], + 'h': ['\'n þora', '\'iensa þora'], + 'hh': [number + ' þoras', '' + number + ' þoras'], + 'd': ['\'n ziua', '\'iensa ziua'], + 'dd': [number + ' ziuas', '' + number + ' ziuas'], + 'M': ['\'n mes', '\'iens mes'], + 'MM': [number + ' mesen', '' + number + ' mesen'], + 'y': ['\'n ar', '\'iens ar'], + 'yy': [number + ' ars', '' + number + ' ars'] + }; + return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]); + } + + //! moment.js locale configuration + + hooks.defineLocale('tzm-latn', { + months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[asdkh g] LT', + nextDay: '[aska g] LT', + nextWeek: 'dddd [g] LT', + lastDay: '[assant g] LT', + lastWeek: 'dddd [g] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'dadkh s yan %s', + past : 'yan %s', + s : 'imik', + ss : '%d imik', + m : 'minuḍ', + mm : '%d minuḍ', + h : 'saɛa', + hh : '%d tassaɛin', + d : 'ass', + dd : '%d ossan', + M : 'ayowr', + MM : '%d iyyirn', + y : 'asgas', + yy : '%d isgasn' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('tzm', { + months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', + nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', + nextWeek: 'dddd [ⴴ] LT', + lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', + lastWeek: 'dddd [ⴴ] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', + past : 'ⵢⴰⵏ %s', + s : 'ⵉⵎⵉⴽ', + ss : '%d ⵉⵎⵉⴽ', + m : 'ⵎⵉⵏⵓⴺ', + mm : '%d ⵎⵉⵏⵓⴺ', + h : 'ⵙⴰⵄⴰ', + hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', + d : 'ⴰⵙⵙ', + dd : '%d oⵙⵙⴰⵏ', + M : 'ⴰⵢoⵓⵔ', + MM : '%d ⵉⵢⵢⵉⵔⵏ', + y : 'ⴰⵙⴳⴰⵙ', + yy : '%d ⵉⵙⴳⴰⵙⵏ' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js language configuration + + hooks.defineLocale('ug-cn', { + months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split( + '_' + ), + weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى', + LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm', + LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm' + }, + meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ( + meridiem === 'يېرىم كېچە' || + meridiem === 'سەھەر' || + meridiem === 'چۈشتىن بۇرۇن' + ) { + return hour; + } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') { + return hour + 12; + } else { + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return 'يېرىم كېچە'; + } else if (hm < 900) { + return 'سەھەر'; + } else if (hm < 1130) { + return 'چۈشتىن بۇرۇن'; + } else if (hm < 1230) { + return 'چۈش'; + } else if (hm < 1800) { + return 'چۈشتىن كېيىن'; + } else { + return 'كەچ'; + } + }, + calendar: { + sameDay: '[بۈگۈن سائەت] LT', + nextDay: '[ئەتە سائەت] LT', + nextWeek: '[كېلەركى] dddd [سائەت] LT', + lastDay: '[تۆنۈگۈن] LT', + lastWeek: '[ئالدىنقى] dddd [سائەت] LT', + sameElse: 'L' + }, + relativeTime: { + future: '%s كېيىن', + past: '%s بۇرۇن', + s: 'نەچچە سېكونت', + ss: '%d سېكونت', + m: 'بىر مىنۇت', + mm: '%d مىنۇت', + h: 'بىر سائەت', + hh: '%d سائەت', + d: 'بىر كۈن', + dd: '%d كۈن', + M: 'بىر ئاي', + MM: '%d ئاي', + y: 'بىر يىل', + yy: '%d يىل' + }, + + dayOfMonthOrdinalParse: /\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '-كۈنى'; + case 'w': + case 'W': + return number + '-ھەپتە'; + default: + return number; + } + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow: 1, // Monday is the first day of the week. + doy: 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + function plural$6(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function relativeTimeWithPlural$4(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд', + 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', + 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин', + 'dd': 'день_дні_днів', + 'MM': 'місяць_місяці_місяців', + 'yy': 'рік_роки_років' + }; + if (key === 'm') { + return withoutSuffix ? 'хвилина' : 'хвилину'; + } + else if (key === 'h') { + return withoutSuffix ? 'година' : 'годину'; + } + else { + return number + ' ' + plural$6(format[key], +number); + } + } + function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), + 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), + 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') + }; + + if (!m) { + return weekdays['nominative']; + } + + var nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? + 'accusative' : + ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? + 'genitive' : + 'nominative'); + return weekdays[nounCase][m.day()]; + } + function processHoursFunction(str) { + return function () { + return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; + }; + } + + hooks.defineLocale('uk', { + months : { + 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'), + 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_') + }, + monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), + weekdays : weekdaysCaseReplace, + weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY р.', + LLL : 'D MMMM YYYY р., HH:mm', + LLLL : 'dddd, D MMMM YYYY р., HH:mm' + }, + calendar : { + sameDay: processHoursFunction('[Сьогодні '), + nextDay: processHoursFunction('[Завтра '), + lastDay: processHoursFunction('[Вчора '), + nextWeek: processHoursFunction('[У] dddd ['), + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return processHoursFunction('[Минулої] dddd [').call(this); + case 1: + case 2: + case 4: + return processHoursFunction('[Минулого] dddd [').call(this); + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'за %s', + past : '%s тому', + s : 'декілька секунд', + ss : relativeTimeWithPlural$4, + m : relativeTimeWithPlural$4, + mm : relativeTimeWithPlural$4, + h : 'годину', + hh : relativeTimeWithPlural$4, + d : 'день', + dd : relativeTimeWithPlural$4, + M : 'місяць', + MM : relativeTimeWithPlural$4, + y : 'рік', + yy : relativeTimeWithPlural$4 + }, + // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason + meridiemParse: /ночі|ранку|дня|вечора/, + isPM: function (input) { + return /^(дня|вечора)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночі'; + } else if (hour < 12) { + return 'ранку'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечора'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return number + '-й'; + case 'D': + return number + '-го'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + var months$8 = [ + 'جنوری', + 'فروری', + 'مارچ', + 'اپریل', + 'مئی', + 'جون', + 'جولائی', + 'اگست', + 'ستمبر', + 'اکتوبر', + 'نومبر', + 'دسمبر' + ]; + var days$2 = [ + 'اتوار', + 'پیر', + 'منگل', + 'بدھ', + 'جمعرات', + 'جمعہ', + 'ہفتہ' + ]; + + hooks.defineLocale('ur', { + months : months$8, + monthsShort : months$8, + weekdays : days$2, + weekdaysShort : days$2, + weekdaysMin : days$2, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd، D MMMM YYYY HH:mm' + }, + meridiemParse: /صبح|شام/, + isPM : function (input) { + return 'شام' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'صبح'; + } + return 'شام'; + }, + calendar : { + sameDay : '[آج بوقت] LT', + nextDay : '[کل بوقت] LT', + nextWeek : 'dddd [بوقت] LT', + lastDay : '[گذشتہ روز بوقت] LT', + lastWeek : '[گذشتہ] dddd [بوقت] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s بعد', + past : '%s قبل', + s : 'چند سیکنڈ', + ss : '%d سیکنڈ', + m : 'ایک منٹ', + mm : '%d منٹ', + h : 'ایک گھنٹہ', + hh : '%d گھنٹے', + d : 'ایک دن', + dd : '%d دن', + M : 'ایک ماہ', + MM : '%d ماہ', + y : 'ایک سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('uz-latn', { + months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'), + monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'), + weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'), + weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'), + weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' + }, + calendar : { + sameDay : '[Bugun soat] LT [da]', + nextDay : '[Ertaga] LT [da]', + nextWeek : 'dddd [kuni soat] LT [da]', + lastDay : '[Kecha soat] LT [da]', + lastWeek : '[O\'tgan] dddd [kuni soat] LT [da]', + sameElse : 'L' + }, + relativeTime : { + future : 'Yaqin %s ichida', + past : 'Bir necha %s oldin', + s : 'soniya', + ss : '%d soniya', + m : 'bir daqiqa', + mm : '%d daqiqa', + h : 'bir soat', + hh : '%d soat', + d : 'bir kun', + dd : '%d kun', + M : 'bir oy', + MM : '%d oy', + y : 'bir yil', + yy : '%d yil' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('uz', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), + weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), + weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' + }, + calendar : { + sameDay : '[Бугун соат] LT [да]', + nextDay : '[Эртага] LT [да]', + nextWeek : 'dddd [куни соат] LT [да]', + lastDay : '[Кеча соат] LT [да]', + lastWeek : '[Утган] dddd [куни соат] LT [да]', + sameElse : 'L' + }, + relativeTime : { + future : 'Якин %s ичида', + past : 'Бир неча %s олдин', + s : 'фурсат', + ss : '%d фурсат', + m : 'бир дакика', + mm : '%d дакика', + h : 'бир соат', + hh : '%d соат', + d : 'бир кун', + dd : '%d кун', + M : 'бир ой', + MM : '%d ой', + y : 'бир йил', + yy : '%d йил' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('vi', { + months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), + monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), + monthsParseExact : true, + weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), + weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysParseExact : true, + meridiemParse: /sa|ch/i, + isPM : function (input) { + return /^ch$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'sa' : 'SA'; + } else { + return isLower ? 'ch' : 'CH'; + } + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [năm] YYYY', + LLL : 'D MMMM [năm] YYYY HH:mm', + LLLL : 'dddd, D MMMM [năm] YYYY HH:mm', + l : 'DD/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Hôm nay lúc] LT', + nextDay: '[Ngày mai lúc] LT', + nextWeek: 'dddd [tuần tới lúc] LT', + lastDay: '[Hôm qua lúc] LT', + lastWeek: 'dddd [tuần rồi lúc] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s tới', + past : '%s trước', + s : 'vài giây', + ss : '%d giây' , + m : 'một phút', + mm : '%d phút', + h : 'một giờ', + hh : '%d giờ', + d : 'một ngày', + dd : '%d ngày', + M : 'một tháng', + MM : '%d tháng', + y : 'một năm', + yy : '%d năm' + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('x-pseudo', { + months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'), + monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'), + monthsParseExact : true, + weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'), + weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'), + weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[T~ódá~ý át] LT', + nextDay : '[T~ómó~rró~w át] LT', + nextWeek : 'dddd [át] LT', + lastDay : '[Ý~ést~érdá~ý át] LT', + lastWeek : '[L~ást] dddd [át] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'í~ñ %s', + past : '%s á~gó', + s : 'á ~féw ~sécó~ñds', + ss : '%d s~écóñ~ds', + m : 'á ~míñ~úté', + mm : '%d m~íñú~tés', + h : 'á~ñ hó~úr', + hh : '%d h~óúrs', + d : 'á ~dáý', + dd : '%d d~áýs', + M : 'á ~móñ~th', + MM : '%d m~óñt~hs', + y : 'á ~ýéár', + yy : '%d ý~éárs' + }, + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('yo', { + months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'), + monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'), + weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'), + weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'), + weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Ònì ni] LT', + nextDay : '[Ọ̀la ni] LT', + nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT', + lastDay : '[Àna ni] LT', + lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ní %s', + past : '%s kọjá', + s : 'ìsẹjú aayá die', + ss :'aayá %d', + m : 'ìsẹjú kan', + mm : 'ìsẹjú %d', + h : 'wákati kan', + hh : 'wákati %d', + d : 'ọjọ́ kan', + dd : 'ọjọ́ %d', + M : 'osù kan', + MM : 'osù %d', + y : 'ọdún kan', + yy : 'ọdún %d' + }, + dayOfMonthOrdinalParse : /ọjọ́\s\d{1,2}/, + ordinal : 'ọjọ́ %d', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('zh-cn', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日Ah点mm分', + LLLL : 'YYYY年M月D日ddddAh点mm分', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || + meridiem === '上午') { + return hour; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } else { + // '中午' + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', + sameElse : 'L' + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '周'; + default: + return number; + } + }, + relativeTime : { + future : '%s内', + past : '%s前', + s : '几秒', + ss : '%d 秒', + m : '1 分钟', + mm : '%d 分钟', + h : '1 小时', + hh : '%d 小时', + d : '1 天', + dd : '%d 天', + M : '1 个月', + MM : '%d 个月', + y : '1 年', + yy : '%d 年' + }, + week : { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('zh-hk', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日dddd HH:mm', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', + sameElse : 'L' + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal : function (number, period) { + switch (period) { + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; + default : + return number; + } + }, + relativeTime : { + future : '%s內', + past : '%s前', + s : '幾秒', + ss : '%d 秒', + m : '1 分鐘', + mm : '%d 分鐘', + h : '1 小時', + hh : '%d 小時', + d : '1 天', + dd : '%d 天', + M : '1 個月', + MM : '%d 個月', + y : '1 年', + yy : '%d 年' + } + }); + + //! moment.js locale configuration + + hooks.defineLocale('zh-tw', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日dddd HH:mm', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : '[今天] LT', + nextDay : '[明天] LT', + nextWeek : '[下]dddd LT', + lastDay : '[昨天] LT', + lastWeek : '[上]dddd LT', + sameElse : 'L' + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal : function (number, period) { + switch (period) { + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; + default : + return number; + } + }, + relativeTime : { + future : '%s內', + past : '%s前', + s : '幾秒', + ss : '%d 秒', + m : '1 分鐘', + mm : '%d 分鐘', + h : '1 小時', + hh : '%d 小時', + d : '1 天', + dd : '%d 天', + M : '1 個月', + MM : '%d 個月', + y : '1 年', + yy : '%d 年' + } + }); + + hooks.locale('en'); + + return hooks; + +}))); diff --git a/nodejs/node_modules/moment/min/moment-with-locales.min.js b/nodejs/node_modules/moment/min/moment-with-locales.min.js new file mode 100755 index 0000000..e7320a7 --- /dev/null +++ b/nodejs/node_modules/moment/min/moment-with-locales.min.js @@ -0,0 +1 @@ +!function(e,a){"object"==typeof exports&&"undefined"!=typeof module?module.exports=a():"function"==typeof define&&define.amd?define(a):e.moment=a()}(this,function(){"use strict";var e,n;function l(){return e.apply(null,arguments)}function _(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function i(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function o(e){return void 0===e}function m(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function u(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function M(e,a){var t,s=[];for(t=0;t>>0,s=0;sTe(e)?(d=e+1,r=_-Te(e)):(d=e,r=_),{year:d,dayOfYear:r}}function Ie(e,a,t){var s,n,d=Ne(e.year(),a,t),r=Math.floor((e.dayOfYear()-d-1)/7)+1;return r<1?s=r+Ce(n=e.year()-1,a,t):r>Ce(e.year(),a,t)?(s=r-Ce(e.year(),a,t),n=e.year()+1):(n=e.year(),s=r),{week:s,year:n}}function Ce(e,a,t){var s=Ne(e,a,t),n=Ne(e+1,a,t);return(Te(e)-s+n)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),P("week","w"),P("isoWeek","W"),A("week",5),A("isoWeek",5),ie("w",B),ie("ww",B,V),ie("W",B),ie("WW",B,V),Me(["w","ww","W","WW"],function(e,a,t,s){a[s.substr(0,1)]=g(e)});I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),P("day","d"),P("weekday","e"),P("isoWeekday","E"),A("day",11),A("weekday",11),A("isoWeekday",11),ie("d",B),ie("e",B),ie("E",B),ie("dd",function(e,a){return a.weekdaysMinRegex(e)}),ie("ddd",function(e,a){return a.weekdaysShortRegex(e)}),ie("dddd",function(e,a){return a.weekdaysRegex(e)}),Me(["dd","ddd","dddd"],function(e,a,t,s){var n=t._locale.weekdaysParse(e,s,t._strict);null!=n?a.d=n:Y(t).invalidWeekday=e}),Me(["d","e","E"],function(e,a,t,s){a[s]=g(e)});var Ge="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Ue="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var Ve="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var Ke=re;var $e=re;var Ze=re;function Be(){function e(e,a){return a.length-e.length}var a,t,s,n,d,r=[],_=[],i=[],o=[];for(a=0;a<7;a++)t=c([2e3,1]).day(a),s=this.weekdaysMin(t,""),n=this.weekdaysShort(t,""),d=this.weekdays(t,""),r.push(s),_.push(n),i.push(d),o.push(s),o.push(n),o.push(d);for(r.sort(e),_.sort(e),i.sort(e),o.sort(e),a=0;a<7;a++)_[a]=me(_[a]),i[a]=me(i[a]),o[a]=me(o[a]);this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+_.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function qe(){return this.hours()%12||12}function Qe(e,a){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function Xe(e,a){return a._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,qe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+qe.apply(this)+F(this.minutes(),2)}),I("hmmss",0,0,function(){return""+qe.apply(this)+F(this.minutes(),2)+F(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+F(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+F(this.minutes(),2)+F(this.seconds(),2)}),Qe("a",!0),Qe("A",!1),P("hour","h"),A("hour",13),ie("a",Xe),ie("A",Xe),ie("H",B),ie("h",B),ie("k",B),ie("HH",B,V),ie("hh",B,V),ie("kk",B,V),ie("hmm",q),ie("hmmss",Q),ie("Hmm",q),ie("Hmmss",Q),le(["H","HH"],Ye),le(["k","kk"],function(e,a,t){var s=g(e);a[Ye]=24===s?0:s}),le(["a","A"],function(e,a,t){t._isPm=t._locale.isPM(e),t._meridiem=e}),le(["h","hh"],function(e,a,t){a[Ye]=g(e),Y(t).bigHour=!0}),le("hmm",function(e,a,t){var s=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s)),Y(t).bigHour=!0}),le("hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s,2)),a[fe]=g(e.substr(n)),Y(t).bigHour=!0}),le("Hmm",function(e,a,t){var s=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s))}),le("Hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s,2)),a[fe]=g(e.substr(n))});var ea,aa=Se("Hours",!0),ta={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Pe,monthsShort:Oe,week:{dow:0,doy:6},weekdays:Ge,weekdaysMin:Ve,weekdaysShort:Ue,meridiemParse:/[ap]\.?m?\.?/i},sa={},na={};function da(e){return e?e.toLowerCase().replace("_","-"):e}function ra(e){var a=null;if(!sa[e]&&"undefined"!=typeof module&&module&&module.exports)try{a=ea._abbr,require("./locale/"+e),_a(a)}catch(e){}return sa[e]}function _a(e,a){var t;return e&&((t=o(a)?oa(e):ia(e,a))?ea=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ea._abbr}function ia(e,a){if(null!==a){var t,s=ta;if(a.abbr=e,null!=sa[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=sa[e]._config;else if(null!=a.parentLocale)if(null!=sa[a.parentLocale])s=sa[a.parentLocale]._config;else{if(null==(t=ra(a.parentLocale)))return na[a.parentLocale]||(na[a.parentLocale]=[]),na[a.parentLocale].push({name:e,config:a}),null;s=t._config}return sa[e]=new j(b(s,a)),na[e]&&na[e].forEach(function(e){ia(e.name,e.config)}),_a(e),sa[e]}return delete sa[e],null}function oa(e){var a;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return ea;if(!_(e)){if(a=ra(e))return a;e=[e]}return function(e){for(var a,t,s,n,d=0;d=a&&r(n,t,!0)>=a-1)break;a--}d++}return ea}(e)}function ma(e){var a,t=e._a;return t&&-2===Y(e).overflow&&(a=t[Le]<0||11je(t[he],t[Le])?ce:t[Ye]<0||24Ce(t,d,r)?Y(e)._overflowWeeks=!0:null!=i?Y(e)._overflowWeekday=!0:(_=Re(t,s,n,d,r),e._a[he]=_.year,e._dayOfYear=_.dayOfYear)}(e),null!=e._dayOfYear&&(d=ua(e._a[he],s[he]),(e._dayOfYear>Te(d)||0===e._dayOfYear)&&(Y(e)._overflowDayOfYear=!0),t=Je(d,0,e._dayOfYear),e._a[Le]=t.getUTCMonth(),e._a[ce]=t.getUTCDate()),a=0;a<3&&null==e._a[a];++a)e._a[a]=r[a]=s[a];for(;a<7;a++)e._a[a]=r[a]=null==e._a[a]?2===a?1:0:e._a[a];24===e._a[Ye]&&0===e._a[ye]&&0===e._a[fe]&&0===e._a[ke]&&(e._nextDay=!0,e._a[Ye]=0),e._d=(e._useUTC?Je:function(e,a,t,s,n,d,r){var _=new Date(e,a,t,s,n,d,r);return e<100&&0<=e&&isFinite(_.getFullYear())&&_.setFullYear(e),_}).apply(null,r),n=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[Ye]=24),e._w&&void 0!==e._w.d&&e._w.d!==n&&(Y(e).weekdayMismatch=!0)}}var Ma=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ha=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,La=/Z|[+-]\d\d(?::?\d\d)?/,ca=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Ya=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],ya=/^\/?Date\((\-?\d+)/i;function fa(e){var a,t,s,n,d,r,_=e._i,i=Ma.exec(_)||ha.exec(_);if(i){for(Y(e).iso=!0,a=0,t=ca.length;at.valueOf():t.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},it.isLocal=function(){return!!this.isValid()&&!this._isUTC},it.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},it.isUtc=Na,it.isUTC=Na,it.zoneAbbr=function(){return this._isUTC?"UTC":""},it.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},it.dates=t("dates accessor is deprecated. Use date instead.",tt),it.months=t("months accessor is deprecated. Use month instead",Ee),it.years=t("years accessor is deprecated. Use year instead",ve),it.zone=t("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,a),this):-this.utcOffset()}),it.isDSTShifted=t("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e={};if(k(e,this),(e=wa(e))._a){var a=e._isUTC?c(e._a):Sa(e._a);this._isDSTShifted=this.isValid()&&0>>0,s=0;sDe(e)?(r=e+1,a=o-De(e)):(r=e,a=o),{year:r,dayOfYear:a}}function Ie(e,t,n){var s,i,r=Ve(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+Ae(i=e.year()-1,t,n):a>Ae(e.year(),t,n)?(s=a-Ae(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function Ae(e,t,n){var s=Ve(e,t,n),i=Ve(e+1,t,n);return(De(e)-s+i)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),H("week","w"),H("isoWeek","W"),L("week",5),L("isoWeek",5),ue("w",B),ue("ww",B,z),ue("W",B),ue("WW",B,z),fe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=k(e)});I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),H("day","d"),H("weekday","e"),H("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),ue("d",B),ue("e",B),ue("E",B),ue("dd",function(e,t){return t.weekdaysMinRegex(e)}),ue("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ue("dddd",function(e,t){return t.weekdaysRegex(e)}),fe(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:g(n).invalidWeekday=e}),fe(["d","e","E"],function(e,t,n,s){t[s]=k(e)});var je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var ze="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var $e=ae;var qe=ae;var Je=ae;function Be(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=y([2e3,1]).day(t),s=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=de(o[t]),u[t]=de(u[t]),l[t]=de(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function Qe(){return this.hours()%12||12}function Xe(e,t){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Ke(e,t){return t._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,Qe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)}),I("hmmss",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)+U(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+U(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+U(this.minutes(),2)+U(this.seconds(),2)}),Xe("a",!0),Xe("A",!1),H("hour","h"),L("hour",13),ue("a",Ke),ue("A",Ke),ue("H",B),ue("h",B),ue("k",B),ue("HH",B,z),ue("hh",B,z),ue("kk",B,z),ue("hmm",Q),ue("hmmss",X),ue("Hmm",Q),ue("Hmmss",X),ce(["H","HH"],ge),ce(["k","kk"],function(e,t,n){var s=k(e);t[ge]=24===s?0:s}),ce(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ce(["h","hh"],function(e,t,n){t[ge]=k(e),g(n).bigHour=!0}),ce("hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s)),g(n).bigHour=!0}),ce("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i)),g(n).bigHour=!0}),ce("Hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s))}),ce("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:He,monthsShort:Re,week:{dow:0,doy:6},weekdays:je,weekdaysMin:ze,weekdaysShort:Ze,meridiemParse:/[ap]\.?m?\.?/i},st={},it={};function rt(e){return e?e.toLowerCase().replace("_","-"):e}function at(e){var t=null;if(!st[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),ot(t)}catch(e){}return st[e]}function ot(e,t){var n;return e&&((n=l(t)?lt(e):ut(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function ut(e,t){if(null!==t){var n,s=nt;if(t.abbr=e,null!=st[e])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=st[e]._config;else if(null!=t.parentLocale)if(null!=st[t.parentLocale])s=st[t.parentLocale]._config;else{if(null==(n=at(t.parentLocale)))return it[t.parentLocale]||(it[t.parentLocale]=[]),it[t.parentLocale].push({name:e,config:t}),null;s=n._config}return st[e]=new P(b(s,t)),it[e]&&it[e].forEach(function(e){ut(e.name,e.config)}),ot(e),st[e]}return delete st[e],null}function lt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!o(e)){if(t=at(e))return t;e=[e]}return function(e){for(var t,n,s,i,r=0;r=t&&a(i,n,!0)>=t-1)break;t--}r++}return et}(e)}function dt(e){var t,n=e._a;return n&&-2===g(e).overflow&&(t=n[_e]<0||11Pe(n[me],n[_e])?ye:n[ge]<0||24Ae(n,r,a)?g(e)._overflowWeeks=!0:null!=u?g(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[me]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=ht(e._a[me],s[me]),(e._dayOfYear>De(r)||0===e._dayOfYear)&&(g(e)._overflowDayOfYear=!0),n=Ge(r,0,e._dayOfYear),e._a[_e]=n.getUTCMonth(),e._a[ye]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=a[t]=s[t];for(;t<7;t++)e._a[t]=a[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[pe]&&0===e._a[ve]&&0===e._a[we]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Ge:function(e,t,n,s,i,r,a){var o=new Date(e,t,n,s,i,r,a);return e<100&&0<=e&&isFinite(o.getFullYear())&&o.setFullYear(e),o}).apply(null,a),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(g(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_t=/Z|[+-]\d\d(?::?\d\d)?/,yt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],gt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],pt=/^\/?Date\((\-?\d+)/i;function vt(e){var t,n,s,i,r,a,o=e._i,u=ft.exec(o)||mt.exec(o);if(u){for(g(e).iso=!0,t=0,n=yt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},ln.isLocal=function(){return!!this.isValid()&&!this._isUTC},ln.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},ln.isUtc=Vt,ln.isUTC=Vt,ln.zoneAbbr=function(){return this._isUTC?"UTC":""},ln.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},ln.dates=n("dates accessor is deprecated. Use date instead.",nn),ln.months=n("months accessor is deprecated. Use month instead",Fe),ln.years=n("years accessor is deprecated. Use year instead",Oe),ln.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),ln.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var e={};if(w(e,this),(e=Yt(e))._a){var t=e._isUTC?y(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 string); + interface CalendarSpec { + sameDay?: CalendarSpecVal; + nextDay?: CalendarSpecVal; + lastDay?: CalendarSpecVal; + nextWeek?: CalendarSpecVal; + lastWeek?: CalendarSpecVal; + sameElse?: CalendarSpecVal; + + // any additional properties might be used with moment.calendarFormat + [x: string]: CalendarSpecVal | void; // undefined + } + + type RelativeTimeSpecVal = ( + string | + ((n: number, withoutSuffix: boolean, + key: RelativeTimeKey, isFuture: boolean) => string) + ); + type RelativeTimeFuturePastVal = string | ((relTime: string) => string); + + interface RelativeTimeSpec { + future: RelativeTimeFuturePastVal; + past: RelativeTimeFuturePastVal; + s: RelativeTimeSpecVal; + ss: RelativeTimeSpecVal; + m: RelativeTimeSpecVal; + mm: RelativeTimeSpecVal; + h: RelativeTimeSpecVal; + hh: RelativeTimeSpecVal; + d: RelativeTimeSpecVal; + dd: RelativeTimeSpecVal; + M: RelativeTimeSpecVal; + MM: RelativeTimeSpecVal; + y: RelativeTimeSpecVal; + yy: RelativeTimeSpecVal; + } + + interface LongDateFormatSpec { + LTS: string; + LT: string; + L: string; + LL: string; + LLL: string; + LLLL: string; + + // lets forget for a sec that any upper/lower permutation will also work + lts?: string; + lt?: string; + l?: string; + ll?: string; + lll?: string; + llll?: string; + } + + type MonthWeekdayFn = (momentToFormat: Moment, format?: string) => string; + type WeekdaySimpleFn = (momentToFormat: Moment) => string; + + interface LocaleSpecification { + months?: string[] | StandaloneFormatSpec | MonthWeekdayFn; + monthsShort?: string[] | StandaloneFormatSpec | MonthWeekdayFn; + + weekdays?: string[] | StandaloneFormatSpec | MonthWeekdayFn; + weekdaysShort?: string[] | StandaloneFormatSpec | WeekdaySimpleFn; + weekdaysMin?: string[] | StandaloneFormatSpec | WeekdaySimpleFn; + + meridiemParse?: RegExp; + meridiem?: (hour: number, minute:number, isLower: boolean) => string; + + isPM?: (input: string) => boolean; + + longDateFormat?: LongDateFormatSpec; + calendar?: CalendarSpec; + relativeTime?: RelativeTimeSpec; + invalidDate?: string; + ordinal?: (n: number) => string; + ordinalParse?: RegExp; + + week?: WeekSpec; + + // Allow anything: in general any property that is passed as locale spec is + // put in the locale object so it can be used by locale functions + [x: string]: any; + } + + interface MomentObjectOutput { + years: number; + /* One digit */ + months: number; + /* Day of the month */ + date: number; + hours: number; + minutes: number; + seconds: number; + milliseconds: number; + } + + interface Duration { + clone(): Duration; + + humanize(withSuffix?: boolean): string; + + abs(): Duration; + + as(units: unitOfTime.Base): number; + get(units: unitOfTime.Base): number; + + milliseconds(): number; + asMilliseconds(): number; + + seconds(): number; + asSeconds(): number; + + minutes(): number; + asMinutes(): number; + + hours(): number; + asHours(): number; + + days(): number; + asDays(): number; + + weeks(): number; + asWeeks(): number; + + months(): number; + asMonths(): number; + + years(): number; + asYears(): number; + + add(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration; + subtract(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration; + + locale(): string; + locale(locale: LocaleSpecifier): Duration; + localeData(): Locale; + + toISOString(): string; + toJSON(): string; + + /** + * @deprecated since version 2.8.0 + */ + lang(locale: LocaleSpecifier): Moment; + /** + * @deprecated since version 2.8.0 + */ + lang(): Locale; + /** + * @deprecated + */ + toIsoString(): string; + } + + interface MomentRelativeTime { + future: any; + past: any; + s: any; + ss: any; + m: any; + mm: any; + h: any; + hh: any; + d: any; + dd: any; + M: any; + MM: any; + y: any; + yy: any; + } + + interface MomentLongDateFormat { + L: string; + LL: string; + LLL: string; + LLLL: string; + LT: string; + LTS: string; + + l?: string; + ll?: string; + lll?: string; + llll?: string; + lt?: string; + lts?: string; + } + + interface MomentParsingFlags { + empty: boolean; + unusedTokens: string[]; + unusedInput: string[]; + overflow: number; + charsLeftOver: number; + nullInput: boolean; + invalidMonth: string | void; // null + invalidFormat: boolean; + userInvalidated: boolean; + iso: boolean; + parsedDateParts: any[]; + meridiem: string | void; // null + } + + interface MomentParsingFlagsOpt { + empty?: boolean; + unusedTokens?: string[]; + unusedInput?: string[]; + overflow?: number; + charsLeftOver?: number; + nullInput?: boolean; + invalidMonth?: string; + invalidFormat?: boolean; + userInvalidated?: boolean; + iso?: boolean; + parsedDateParts?: any[]; + meridiem?: string; + } + + interface MomentBuiltinFormat { + __momentBuiltinFormatBrand: any; + } + + type MomentFormatSpecification = string | MomentBuiltinFormat | (string | MomentBuiltinFormat)[]; + + namespace unitOfTime { + type Base = ( + "year" | "years" | "y" | + "month" | "months" | "M" | + "week" | "weeks" | "w" | + "day" | "days" | "d" | + "hour" | "hours" | "h" | + "minute" | "minutes" | "m" | + "second" | "seconds" | "s" | + "millisecond" | "milliseconds" | "ms" + ); + + type _quarter = "quarter" | "quarters" | "Q"; + type _isoWeek = "isoWeek" | "isoWeeks" | "W"; + type _date = "date" | "dates" | "D"; + type DurationConstructor = Base | _quarter; + + type DurationAs = Base; + + type StartOf = Base | _quarter | _isoWeek | _date; + + type Diff = Base | _quarter; + + type MomentConstructor = Base | _date; + + type All = Base | _quarter | _isoWeek | _date | + "weekYear" | "weekYears" | "gg" | + "isoWeekYear" | "isoWeekYears" | "GG" | + "dayOfYear" | "dayOfYears" | "DDD" | + "weekday" | "weekdays" | "e" | + "isoWeekday" | "isoWeekdays" | "E"; + } + + interface MomentInputObject { + years?: number; + year?: number; + y?: number; + + months?: number; + month?: number; + M?: number; + + days?: number; + day?: number; + d?: number; + + dates?: number; + date?: number; + D?: number; + + hours?: number; + hour?: number; + h?: number; + + minutes?: number; + minute?: number; + m?: number; + + seconds?: number; + second?: number; + s?: number; + + milliseconds?: number; + millisecond?: number; + ms?: number; + } + + interface DurationInputObject extends MomentInputObject { + quarters?: number; + quarter?: number; + Q?: number; + + weeks?: number; + week?: number; + w?: number; + } + + interface MomentSetObject extends MomentInputObject { + weekYears?: number; + weekYear?: number; + gg?: number; + + isoWeekYears?: number; + isoWeekYear?: number; + GG?: number; + + quarters?: number; + quarter?: number; + Q?: number; + + weeks?: number; + week?: number; + w?: number; + + isoWeeks?: number; + isoWeek?: number; + W?: number; + + dayOfYears?: number; + dayOfYear?: number; + DDD?: number; + + weekdays?: number; + weekday?: number; + e?: number; + + isoWeekdays?: number; + isoWeekday?: number; + E?: number; + } + + interface FromTo { + from: MomentInput; + to: MomentInput; + } + + type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined + type DurationInputArg1 = Duration | number | string | FromTo | DurationInputObject | void; // null | undefined + type DurationInputArg2 = unitOfTime.DurationConstructor; + type LocaleSpecifier = string | Moment | Duration | string[] | boolean; + + interface MomentCreationData { + input: MomentInput; + format?: MomentFormatSpecification; + locale: Locale; + isUTC: boolean; + strict?: boolean; + } + + interface Moment extends Object { + format(format?: string): string; + + startOf(unitOfTime: unitOfTime.StartOf): Moment; + endOf(unitOfTime: unitOfTime.StartOf): Moment; + + add(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment; + /** + * @deprecated reverse syntax + */ + add(unit: unitOfTime.DurationConstructor, amount: number|string): Moment; + + subtract(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment; + /** + * @deprecated reverse syntax + */ + subtract(unit: unitOfTime.DurationConstructor, amount: number|string): Moment; + + calendar(time?: MomentInput, formats?: CalendarSpec): string; + + clone(): Moment; + + /** + * @return Unix timestamp in milliseconds + */ + valueOf(): number; + + // current date/time in local mode + local(keepLocalTime?: boolean): Moment; + isLocal(): boolean; + + // current date/time in UTC mode + utc(keepLocalTime?: boolean): Moment; + isUTC(): boolean; + /** + * @deprecated use isUTC + */ + isUtc(): boolean; + + parseZone(): Moment; + isValid(): boolean; + invalidAt(): number; + + hasAlignedHourOffset(other?: MomentInput): boolean; + + creationData(): MomentCreationData; + parsingFlags(): MomentParsingFlags; + + year(y: number): Moment; + year(): number; + /** + * @deprecated use year(y) + */ + years(y: number): Moment; + /** + * @deprecated use year() + */ + years(): number; + quarter(): number; + quarter(q: number): Moment; + quarters(): number; + quarters(q: number): Moment; + month(M: number|string): Moment; + month(): number; + /** + * @deprecated use month(M) + */ + months(M: number|string): Moment; + /** + * @deprecated use month() + */ + months(): number; + day(d: number|string): Moment; + day(): number; + days(d: number|string): Moment; + days(): number; + date(d: number): Moment; + date(): number; + /** + * @deprecated use date(d) + */ + dates(d: number): Moment; + /** + * @deprecated use date() + */ + dates(): number; + hour(h: number): Moment; + hour(): number; + hours(h: number): Moment; + hours(): number; + minute(m: number): Moment; + minute(): number; + minutes(m: number): Moment; + minutes(): number; + second(s: number): Moment; + second(): number; + seconds(s: number): Moment; + seconds(): number; + millisecond(ms: number): Moment; + millisecond(): number; + milliseconds(ms: number): Moment; + milliseconds(): number; + weekday(): number; + weekday(d: number): Moment; + isoWeekday(): number; + isoWeekday(d: number|string): Moment; + weekYear(): number; + weekYear(d: number): Moment; + isoWeekYear(): number; + isoWeekYear(d: number): Moment; + week(): number; + week(d: number): Moment; + weeks(): number; + weeks(d: number): Moment; + isoWeek(): number; + isoWeek(d: number): Moment; + isoWeeks(): number; + isoWeeks(d: number): Moment; + weeksInYear(): number; + isoWeeksInYear(): number; + dayOfYear(): number; + dayOfYear(d: number): Moment; + + from(inp: MomentInput, suffix?: boolean): string; + to(inp: MomentInput, suffix?: boolean): string; + fromNow(withoutSuffix?: boolean): string; + toNow(withoutPrefix?: boolean): string; + + diff(b: MomentInput, unitOfTime?: unitOfTime.Diff, precise?: boolean): number; + + toArray(): number[]; + toDate(): Date; + toISOString(keepOffset?: boolean): string; + inspect(): string; + toJSON(): string; + unix(): number; + + isLeapYear(): boolean; + /** + * @deprecated in favor of utcOffset + */ + zone(): number; + zone(b: number|string): Moment; + utcOffset(): number; + utcOffset(b: number|string, keepLocalTime?: boolean): Moment; + isUtcOffset(): boolean; + daysInMonth(): number; + isDST(): boolean; + + zoneAbbr(): string; + zoneName(): string; + + isBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean; + isAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean; + isSame(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean; + isSameOrAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean; + isSameOrBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean; + isBetween(a: MomentInput, b: MomentInput, granularity?: unitOfTime.StartOf, inclusivity?: "()" | "[)" | "(]" | "[]"): boolean; + + /** + * @deprecated as of 2.8.0, use locale + */ + lang(language: LocaleSpecifier): Moment; + /** + * @deprecated as of 2.8.0, use locale + */ + lang(): Locale; + + locale(): string; + locale(locale: LocaleSpecifier): Moment; + + localeData(): Locale; + + /** + * @deprecated no reliable implementation + */ + isDSTShifted(): boolean; + + // NOTE(constructor): Same as moment constructor + /** + * @deprecated as of 2.7.0, use moment.min/max + */ + max(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment; + /** + * @deprecated as of 2.7.0, use moment.min/max + */ + max(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment; + + // NOTE(constructor): Same as moment constructor + /** + * @deprecated as of 2.7.0, use moment.min/max + */ + min(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment; + /** + * @deprecated as of 2.7.0, use moment.min/max + */ + min(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment; + + get(unit: unitOfTime.All): number; + set(unit: unitOfTime.All, value: number): Moment; + set(objectLiteral: MomentSetObject): Moment; + + toObject(): MomentObjectOutput; + } + + export var version: string; + export var fn: Moment; + + // NOTE(constructor): Same as moment constructor + export function utc(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment; + export function utc(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment; + + export function unix(timestamp: number): Moment; + + export function invalid(flags?: MomentParsingFlagsOpt): Moment; + export function isMoment(m: any): m is Moment; + export function isDate(m: any): m is Date; + export function isDuration(d: any): d is Duration; + + /** + * @deprecated in 2.8.0 + */ + export function lang(language?: string): string; + /** + * @deprecated in 2.8.0 + */ + export function lang(language?: string, definition?: Locale): string; + + export function locale(language?: string): string; + export function locale(language?: string[]): string; + export function locale(language?: string, definition?: LocaleSpecification | void): string; // null | undefined + + export function localeData(key?: string | string[]): Locale; + + export function duration(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration; + + // NOTE(constructor): Same as moment constructor + export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment; + export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment; + + export function months(): string[]; + export function months(index: number): string; + export function months(format: string): string[]; + export function months(format: string, index: number): string; + export function monthsShort(): string[]; + export function monthsShort(index: number): string; + export function monthsShort(format: string): string[]; + export function monthsShort(format: string, index: number): string; + + export function weekdays(): string[]; + export function weekdays(index: number): string; + export function weekdays(format: string): string[]; + export function weekdays(format: string, index: number): string; + export function weekdays(localeSorted: boolean): string[]; + export function weekdays(localeSorted: boolean, index: number): string; + export function weekdays(localeSorted: boolean, format: string): string[]; + export function weekdays(localeSorted: boolean, format: string, index: number): string; + export function weekdaysShort(): string[]; + export function weekdaysShort(index: number): string; + export function weekdaysShort(format: string): string[]; + export function weekdaysShort(format: string, index: number): string; + export function weekdaysShort(localeSorted: boolean): string[]; + export function weekdaysShort(localeSorted: boolean, index: number): string; + export function weekdaysShort(localeSorted: boolean, format: string): string[]; + export function weekdaysShort(localeSorted: boolean, format: string, index: number): string; + export function weekdaysMin(): string[]; + export function weekdaysMin(index: number): string; + export function weekdaysMin(format: string): string[]; + export function weekdaysMin(format: string, index: number): string; + export function weekdaysMin(localeSorted: boolean): string[]; + export function weekdaysMin(localeSorted: boolean, index: number): string; + export function weekdaysMin(localeSorted: boolean, format: string): string[]; + export function weekdaysMin(localeSorted: boolean, format: string, index: number): string; + + export function min(moments: Moment[]): Moment; + export function min(...moments: Moment[]): Moment; + export function max(moments: Moment[]): Moment; + export function max(...moments: Moment[]): Moment; + + /** + * Returns unix time in milliseconds. Overwrite for profit. + */ + export function now(): number; + + export function defineLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null + export function updateLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null + + export function locales(): string[]; + + export function normalizeUnits(unit: unitOfTime.All): string; + export function relativeTimeThreshold(threshold: string): number | boolean; + export function relativeTimeThreshold(threshold: string, limit: number): boolean; + export function relativeTimeRounding(fn: (num: number) => number): boolean; + export function relativeTimeRounding(): (num: number) => number; + export function calendarFormat(m: Moment, now: Moment): string; + + export function parseTwoDigitYear(input: string): number; + + /** + * Constant used to enable explicit ISO_8601 format parsing. + */ + export var ISO_8601: MomentBuiltinFormat; + export var RFC_2822: MomentBuiltinFormat; + + export var defaultFormat: string; + export var defaultFormatUtc: string; + + export var HTML5_FMT: { + DATETIME_LOCAL: string, + DATETIME_LOCAL_SECONDS: string, + DATETIME_LOCAL_MS: string, + DATE: string, + TIME: string, + TIME_SECONDS: string, + TIME_MS: string, + WEEK: string, + MONTH: string + }; + +} + +export = moment; diff --git a/nodejs/node_modules/moment/moment.js b/nodejs/node_modules/moment/moment.js new file mode 100755 index 0000000..1c18684 --- /dev/null +++ b/nodejs/node_modules/moment/moment.js @@ -0,0 +1,4506 @@ +//! moment.js + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.moment = factory() +}(this, (function () { 'use strict'; + + var hookCallback; + + function hooks () { + return hookCallback.apply(null, arguments); + } + + // This is done to register the method called with moment() + // without creating circular dependencies. + function setHookCallback (callback) { + hookCallback = callback; + } + + function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; + } + + function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; + } + + function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return (Object.getOwnPropertyNames(obj).length === 0); + } else { + var k; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + return true; + } + } + + function isUndefined(input) { + return input === void 0; + } + + function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; + } + + function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; + } + + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } + + function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); + } + + function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; + } + + function createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); + } + + function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false, + parsedDateParts : [], + meridiem : null, + rfc2822 : false, + weekdayMismatch : false + }; + } + + function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; + } + + var some; + if (Array.prototype.some) { + some = Array.prototype.some; + } else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; + } + + function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); + var isNowValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.weekdayMismatch && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); + + if (m._strict) { + isNowValid = isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } + else { + return isNowValid; + } + } + return m._isValid; + } + + function createInvalid (flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; + } + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + var momentProperties = hooks.momentProperties = []; + + function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; + } + + var updateInProgress = false; + + // Moment prototype object + function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } + } + + function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); + } + + function absFloor (number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } + } + + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; + } + + // compare two arrays, return the number of differences + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; + } + + function warn(msg) { + if (hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + if (firstTime) { + var args = []; + var arg; + for (var i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + var deprecations = {}; + + function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } + + hooks.suppressDeprecationWarnings = false; + hooks.deprecationHandler = null; + + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } + + function set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + (/\d{1,2}/).source); + } + + function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + for (prop in parentConfig) { + if (hasOwnProp(parentConfig, prop) && + !hasOwnProp(childConfig, prop) && + isObject(parentConfig[prop])) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + return res; + } + + function Locale(config) { + if (config != null) { + this.set(config); + } + } + + var keys; + + if (Object.keys) { + keys = Object.keys; + } else { + keys = function (obj) { + var i, res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; + } + + var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }; + + function calendar (key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; + } + + var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }; + + function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + + return this._longDateFormat[key]; + } + + var defaultInvalidDate = 'Invalid date'; + + function invalidDate () { + return this._invalidDate; + } + + var defaultOrdinal = '%d'; + var defaultDayOfMonthOrdinalParse = /\d{1,2}/; + + function ordinal (number) { + return this._ordinal.replace('%d', number); + } + + var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }; + + function relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); + } + + function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); + } + + var aliases = {}; + + function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + } + + function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; + } + + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; + } + + var priorities = {}; + + function addUnitPriority(unit, priority) { + priorities[unit] = priority; + } + + function getPrioritizedUnits(unitsObj) { + var units = []; + for (var u in unitsObj) { + units.push({unit: u, priority: priorities[u]}); + } + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; + } + + function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; + } + + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + + var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + + var formatFunctions = {}; + + var formatTokenFunctions = {}; + + // token: 'M' + // padded: ['MM', 2] + // ordinal: 'Mo' + // callback: function () { this.month() + 1 } + function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } + } + + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); + } + + function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = '', i; + for (i = 0; i < length; i++) { + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; + } + return output; + }; + } + + // format date using native date object + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + + return formatFunctions[format](m); + } + + function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; + } + + var match1 = /\d/; // 0 - 9 + var match2 = /\d\d/; // 00 - 99 + var match3 = /\d{3}/; // 000 - 999 + var match4 = /\d{4}/; // 0000 - 9999 + var match6 = /[+-]?\d{6}/; // -999999 - 999999 + var match1to2 = /\d\d?/; // 0 - 99 + var match3to4 = /\d\d\d\d?/; // 999 - 9999 + var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 + var match1to3 = /\d{1,3}/; // 0 - 999 + var match1to4 = /\d{1,4}/; // 0 - 9999 + var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 + + var matchUnsigned = /\d+/; // 0 - inf + var matchSigned = /[+-]?\d+/; // -inf - inf + + var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z + var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + + var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 + + // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months + var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; + + var regexes = {}; + + function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; + } + + function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); + } + + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); + } + + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + var tokens = {}; + + function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } + } + + function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); + } + + function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } + } + + var YEAR = 0; + var MONTH = 1; + var DATE = 2; + var HOUR = 3; + var MINUTE = 4; + var SECOND = 5; + var MILLISECOND = 6; + var WEEK = 7; + var WEEKDAY = 8; + + // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); + + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); + + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + + // ALIASES + + addUnitAlias('year', 'y'); + + // PRIORITIES + + addUnitPriority('year', 1); + + // PARSING + + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); + + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); + + // HELPERS + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + + // HOOKS + + hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; + + // MOMENTS + + var getSetYear = makeGetSet('FullYear', true); + + function getIsLeapYear () { + return isLeapYear(this.year()); + } + + function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; + } + + function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; + } + + function set$1 (mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } + else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + } + + // MOMENTS + + function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; + } + + + function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; + } + + function mod(n, x) { + return ((n % x) + x) % x; + } + + var indexOf; + + if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; + } else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; + } + + function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); + } + + // FORMATTING + + addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; + }); + + addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); + }); + + addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); + }); + + // ALIASES + + addUnitAlias('month', 'M'); + + // PRIORITY + + addUnitPriority('month', 8); + + // PARSING + + addRegexToken('M', match1to2); + addRegexToken('MM', match1to2, match2); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); + + addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; + }); + + addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } + }); + + // LOCALES + + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; + var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); + function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } + return isArray(this._months) ? this._months[m.month()] : + this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; + } + + var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); + function localeMonthsShort (m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : + this._monthsShort['standalone']; + } + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + function handleStrictParse(monthName, format, strict) { + var i, ii, mom, llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; + + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } + } + + // MOMENTS + + function setMonth (mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (!isNumber(value)) { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } + } + + function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); + } + + var defaultMonthsShortRegex = matchWord; + function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } + } + + var defaultMonthsRegex = matchWord; + function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } + } + + function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + } + + function createDate (y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date = new Date(y, m, d, h, M, s, ms); + + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { + date.setFullYear(y); + } + return date; + } + + function createUTCDate (y) { + var date = new Date(Date.UTC.apply(null, arguments)); + + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + return date; + } + + // start-of-first-week - start-of-year + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; + } + + // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; + } + + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; + } + + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; + } + + // FORMATTING + + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + + // ALIASES + + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); + + // PRIORITIES + + addUnitPriority('week', 5); + addUnitPriority('isoWeek', 5); + + // PARSING + + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); + + addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + }); + + // HELPERS + + // LOCALES + + function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } + + var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + }; + + function localeFirstDayOfWeek () { + return this._week.dow; + } + + function localeFirstDayOfYear () { + return this._week.doy; + } + + // MOMENTS + + function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + // FORMATTING + + addFormatToken('d', 0, 'do', 'day'); + + addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); + }); + + addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); + }); + + addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); + }); + + addFormatToken('e', 0, 0, 'weekday'); + addFormatToken('E', 0, 0, 'isoWeekday'); + + // ALIASES + + addUnitAlias('day', 'd'); + addUnitAlias('weekday', 'e'); + addUnitAlias('isoWeekday', 'E'); + + // PRIORITY + addUnitPriority('day', 11); + addUnitPriority('weekday', 11); + addUnitPriority('isoWeekday', 11); + + // PARSING + + addRegexToken('d', match1to2); + addRegexToken('e', match1to2); + addRegexToken('E', match1to2); + addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); + }); + addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); + }); + addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); + }); + + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } + }); + + addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); + }); + + // HELPERS + + function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; + } + + function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + return isNaN(input) ? null : input; + } + + // LOCALES + + var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); + function localeWeekdays (m, format) { + if (!m) { + return isArray(this._weekdays) ? this._weekdays : + this._weekdays['standalone']; + } + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; + } + + var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); + function localeWeekdaysShort (m) { + return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; + } + + var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); + function localeWeekdaysMin (m) { + return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; + } + + function handleStrictParse$1(weekdayName, format, strict) { + var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; + + if (this._weekdaysParseExact) { + return handleStrictParse$1.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + } + + // MOMENTS + + function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + } + + function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + } + + function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } + } + + var defaultWeekdaysRegex = matchWord; + function weekdaysRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + return this._weekdaysStrictRegex && isStrict ? + this._weekdaysStrictRegex : this._weekdaysRegex; + } + } + + var defaultWeekdaysShortRegex = matchWord; + function weekdaysShortRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + return this._weekdaysShortStrictRegex && isStrict ? + this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } + } + + var defaultWeekdaysMinRegex = matchWord; + function weekdaysMinRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + return this._weekdaysMinStrictRegex && isStrict ? + this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } + } + + + function computeWeekdaysParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], + i, mom, minp, shortp, longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); + } + + // FORMATTING + + function hFormat() { + return this.hours() % 12 || 12; + } + + function kFormat() { + return this.hours() || 24; + } + + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + addFormatToken('k', ['kk', 2], 0, kFormat); + + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); + + addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + + addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); + } + + meridiem('a', true); + meridiem('A', false); + + // ALIASES + + addUnitAlias('hour', 'h'); + + // PRIORITY + addUnitPriority('hour', 13); + + // PARSING + + function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; + } + + addRegexToken('a', matchMeridiem); + addRegexToken('A', matchMeridiem); + addRegexToken('H', match1to2); + addRegexToken('h', match1to2); + addRegexToken('k', match1to2); + addRegexToken('HH', match1to2, match2); + addRegexToken('hh', match1to2, match2); + addRegexToken('kk', match1to2, match2); + + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); + + addParseToken(['H', 'HH'], HOUR); + addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; + }); + addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; + }); + addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); + + // LOCALES + + function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); + } + + var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; + function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + } + + + // MOMENTS + + // Setting the hour should keep the time, because the user explicitly + // specified which hour they want. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + var getSetHour = makeGetSet('Hours', true); + + var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, + + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, + + week: defaultLocaleWeek, + + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, + + meridiemParse: defaultLocaleMeridiemParse + }; + + // internal storage for locale config files + var locales = {}; + var localeFamilies = {}; + var globalLocale; + + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; + } + + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return globalLocale; + } + + function loadLocale(name) { + var oldLocale = null; + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { + try { + oldLocale = globalLocale._abbr; + var aliasedRequire = require; + aliasedRequire('./locale/' + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} + } + return locales[name]; + } + + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + function getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } + else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + else { + if ((typeof console !== 'undefined') && console.warn) { + //warn user if arguments are passed but the locale could not be set + console.warn('Locale ' + key + ' not found. Did you forget to load it?'); + } + } + } + + return globalLocale._abbr; + } + + function defineLocale (name, config) { + if (config !== null) { + var locale, parentConfig = baseConfig; + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale ' + + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + locale = loadLocale(config.parentLocale); + if (locale != null) { + parentConfig = locale._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } + } + } + locales[name] = new Locale(mergeConfigs(parentConfig, config)); + + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } + + // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); + + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + } + + function updateLocale(name, config) { + if (config != null) { + var locale, tmpLocale, parentConfig = baseConfig; + // MERGE + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + config = mergeConfigs(parentConfig, config); + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + + // backwards compat for now: also set the locale + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; + } + + // returns locale data + function getLocale (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); + } + + function listLocales() { + return keys(locales); + } + + function checkOverflow (m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; + } + + // Pick the first defined of two or three arguments. + function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; + } + + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + } + + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function configFromArray (config) { + var i, date, input = [], currentDate, expectedWeekday, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); + + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + + // check for mismatching day of week + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { + getParsingFlags(config).weekdayMismatch = true; + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + var curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to begining of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + } + + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + + var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + + var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] + ]; + + // iso time formats and regexes + var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] + ]; + + var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + + // date from iso format + function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } + } + + // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 + var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; + + function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10) + ]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; + } + + function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; + } + + function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + + function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; + } + + var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 + }; + + function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; + } + } + + // date and time from ref 2822 format + function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } + } + + // date from iso format or fallback + function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); + } + + hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged and will be removed in an upcoming major release. Please refer to ' + + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); + + // constant that refers to the ISO standard + hooks.ISO_8601 = function () {}; + + // constant that refers to the RFC 2822 form + hooks.RFC_2822 = function () {}; + + // date from string and format string + function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + config._a = []; + getParsingFlags(config).empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; + + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } + else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } + + // clear _12h flag if hour is <= 12 + if (config._a[HOUR] <= 12 && + getParsingFlags(config).bigHour === true && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; + } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + + configFromArray(config); + checkOverflow(config); + } + + + function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } + } + + // date from string and array of format strings + function configFromStringAndArray(config) { + var tempConfig, + bestMoment, + + scoreToBeat, + i, + currentScore; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (!isValid(tempConfig)) { + continue; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; + + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); + } + + function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + + configFromArray(config); + } + + function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; + } + + function prepareConfig (config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || getLocale(config._l); + + if (input === null || (format === undefined && input === '')) { + return createInvalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } + + if (!isValid(config)) { + config._d = null; + } + + return config; + } + + function configFromInput(config) { + var input = config._i; + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } + } + + function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; + + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } + + if ((isObject(input) && isObjectEmpty(input)) || + (isArray(input) && input.length === 0)) { + input = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + + return createFromConfig(c); + } + + function createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); + } + + var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + } + ); + + var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + } + ); + + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + // TODO: Use [].sort instead? + function min () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + } + + function max () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + } + + var now = function () { + return Date.now ? Date.now() : +(new Date()); + }; + + var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + + function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } + } + + var unitHasDecimal = false; + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; + } + + function isValid$1() { + return this._isValid; + } + + function createInvalid$1() { + return createDuration(NaN); + } + + function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + this._isValid = isDurationValid(normalizedInput); + + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = getLocale(); + + this._bubble(); + } + + function isDuration (obj) { + return obj instanceof Duration; + } + + function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } + + // FORMATTING + + function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); + } + + offset('Z', ':'); + offset('ZZ', ''); + + // PARSING + + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); + addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); + }); + + // HELPERS + + // timezone chunker + // '+10:00' > ['10', '00'] + // '-1530' > ['-15', '30'] + var chunkOffset = /([\+\-]|\d\d)/gi; + + function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher); + + if (matches === null) { + return null; + } + + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + + return minutes === 0 ? + 0 : + parts[0] === '+' ? minutes : -minutes; + } + + // Return a moment from input, that is local/utc/zone equivalent to model. + function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); + // Use low-level api, because this fn is low-level api. + res._d.setTime(res._d.valueOf() + diff); + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } + } + + function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; + } + + // HOOKS + + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + hooks.updateOffset = function () {}; + + // MOMENTS + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + function getSetOffset (input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract(this, createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } + } + + function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } + } + + function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); + } + + function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; + } + + function setOffsetToParsedOffset () { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } + else { + this.utcOffset(0, true); + } + } + return this; + } + + function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } + input = input ? createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; + } + + function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); + } + + function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; + } + + function isLocal () { + return this.isValid() ? !this._isUTC : false; + } + + function isUtcOffset () { + return this.isValid() ? this._isUTC : false; + } + + function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; + } + + // ASP.NET json date format regex + var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; + + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + // and further modified to allow for strings containing both week and day + var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + + function createDuration (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms : input._milliseconds, + d : input._days, + M : input._months + }; + } else if (isNumber(input)) { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; + duration = { + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) + }; + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + return ret; + } + + createDuration.fn = Duration.prototype; + createDuration.invalid = createInvalid$1; + + function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + } + + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; + } + + function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } + + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } + + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; + } + + function addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } + } + + var add = createAdder(1, 'add'); + var subtract = createAdder(-1, 'subtract'); + + function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + } + + function calendar$1 (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; + + var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); + } + + function clone () { + return new Moment(this); + } + + function isAfter (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } + } + + function isBefore (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } + } + + function isBetween (from, to, units, inclusivity) { + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && + (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); + } + + function isSame (input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + } + } + + function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input,units); + } + + function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input,units); + } + + function diff (input, units, asFloat) { + var that, + zoneDelta, + output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + switch (units) { + case 'year': output = monthDiff(this, that) / 12; break; + case 'month': output = monthDiff(this, that); break; + case 'quarter': output = monthDiff(this, that) / 3; break; + case 'second': output = (this - that) / 1e3; break; // 1000 + case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 + case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 + case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst + case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: output = this - that; + } + + return asFloat ? output : absFloor(output); + } + + function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; + } + + hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + + function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + } + + function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + var utc = keepOffset !== true; + var m = utc ? this.clone().utc() : this; + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { + return this.toDate().toISOString(); + } else { + return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); + } + } + return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + + /** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ + function inspect () { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment'; + var zone = ''; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + var prefix = '[' + func + '("]'; + var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; + + return this.format(prefix + year + datetime + suffix); + } + + function format (inputString) { + if (!inputString) { + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; + } + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); + } + + function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function fromNow (withoutSuffix) { + return this.from(createLocal(), withoutSuffix); + } + + function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function toNow (withoutSuffix) { + return this.to(createLocal(), withoutSuffix); + } + + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } + } + + var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ); + + function localeData () { + return this._locale; + } + + function startOf (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + case 'date': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } + if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; + } + + function endOf (units) { + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond') { + return this; + } + + // 'date' is an alias for 'day', so it should be considered as such. + if (units === 'date') { + units = 'day'; + } + + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + } + + function valueOf () { + return this._d.valueOf() - ((this._offset || 0) * 60000); + } + + function unix () { + return Math.floor(this.valueOf() / 1000); + } + + function toDate () { + return new Date(this.valueOf()); + } + + function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; + } + + function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; + } + + function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; + } + + function isValid$2 () { + return isValid(this); + } + + function parsingFlags () { + return extend({}, getParsingFlags(this)); + } + + function invalidAt () { + return getParsingFlags(this).overflow; + } + + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; + } + + // FORMATTING + + addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; + }); + + addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; + }); + + function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); + } + + addWeekYearFormatToken('gggg', 'weekYear'); + addWeekYearFormatToken('ggggg', 'weekYear'); + addWeekYearFormatToken('GGGG', 'isoWeekYear'); + addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + + // ALIASES + + addUnitAlias('weekYear', 'gg'); + addUnitAlias('isoWeekYear', 'GG'); + + // PRIORITY + + addUnitPriority('weekYear', 1); + addUnitPriority('isoWeekYear', 1); + + + // PARSING + + addRegexToken('G', matchSigned); + addRegexToken('g', matchSigned); + addRegexToken('GG', match1to2, match2); + addRegexToken('gg', match1to2, match2); + addRegexToken('GGGG', match1to4, match4); + addRegexToken('gggg', match1to4, match4); + addRegexToken('GGGGG', match1to6, match6); + addRegexToken('ggggg', match1to6, match6); + + addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); + }); + + addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); + }); + + // MOMENTS + + function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); + } + + function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); + } + + function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); + } + + function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + } + + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } + } + + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; + } + + // FORMATTING + + addFormatToken('Q', 0, 'Qo', 'quarter'); + + // ALIASES + + addUnitAlias('quarter', 'Q'); + + // PRIORITY + + addUnitPriority('quarter', 7); + + // PARSING + + addRegexToken('Q', match1); + addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; + }); + + // MOMENTS + + function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + } + + // FORMATTING + + addFormatToken('D', ['DD', 2], 'Do', 'date'); + + // ALIASES + + addUnitAlias('date', 'D'); + + // PRIORITY + addUnitPriority('date', 9); + + // PARSING + + addRegexToken('D', match1to2); + addRegexToken('DD', match1to2, match2); + addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? + (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : + locale._dayOfMonthOrdinalParseLenient; + }); + + addParseToken(['D', 'DD'], DATE); + addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0]); + }); + + // MOMENTS + + var getSetDayOfMonth = makeGetSet('Date', true); + + // FORMATTING + + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + + // ALIASES + + addUnitAlias('dayOfYear', 'DDD'); + + // PRIORITY + addUnitPriority('dayOfYear', 4); + + // PARSING + + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); + + // HELPERS + + // MOMENTS + + function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + } + + // FORMATTING + + addFormatToken('m', ['mm', 2], 0, 'minute'); + + // ALIASES + + addUnitAlias('minute', 'm'); + + // PRIORITY + + addUnitPriority('minute', 14); + + // PARSING + + addRegexToken('m', match1to2); + addRegexToken('mm', match1to2, match2); + addParseToken(['m', 'mm'], MINUTE); + + // MOMENTS + + var getSetMinute = makeGetSet('Minutes', false); + + // FORMATTING + + addFormatToken('s', ['ss', 2], 0, 'second'); + + // ALIASES + + addUnitAlias('second', 's'); + + // PRIORITY + + addUnitPriority('second', 15); + + // PARSING + + addRegexToken('s', match1to2); + addRegexToken('ss', match1to2, match2); + addParseToken(['s', 'ss'], SECOND); + + // MOMENTS + + var getSetSecond = makeGetSet('Seconds', false); + + // FORMATTING + + addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); + }); + + addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); + }); + + addFormatToken(0, ['SSS', 3], 0, 'millisecond'); + addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; + }); + addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; + }); + addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; + }); + addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; + }); + addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; + }); + addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; + }); + + + // ALIASES + + addUnitAlias('millisecond', 'ms'); + + // PRIORITY + + addUnitPriority('millisecond', 16); + + // PARSING + + addRegexToken('S', match1to3, match1); + addRegexToken('SS', match1to3, match2); + addRegexToken('SSS', match1to3, match3); + + var token; + for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); + } + + function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); + } + + for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); + } + // MOMENTS + + var getSetMillisecond = makeGetSet('Milliseconds', false); + + // FORMATTING + + addFormatToken('z', 0, 0, 'zoneAbbr'); + addFormatToken('zz', 0, 0, 'zoneName'); + + // MOMENTS + + function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; + } + + function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; + } + + var proto = Moment.prototype; + + proto.add = add; + proto.calendar = calendar$1; + proto.clone = clone; + proto.diff = diff; + proto.endOf = endOf; + proto.format = format; + proto.from = from; + proto.fromNow = fromNow; + proto.to = to; + proto.toNow = toNow; + proto.get = stringGet; + proto.invalidAt = invalidAt; + proto.isAfter = isAfter; + proto.isBefore = isBefore; + proto.isBetween = isBetween; + proto.isSame = isSame; + proto.isSameOrAfter = isSameOrAfter; + proto.isSameOrBefore = isSameOrBefore; + proto.isValid = isValid$2; + proto.lang = lang; + proto.locale = locale; + proto.localeData = localeData; + proto.max = prototypeMax; + proto.min = prototypeMin; + proto.parsingFlags = parsingFlags; + proto.set = stringSet; + proto.startOf = startOf; + proto.subtract = subtract; + proto.toArray = toArray; + proto.toObject = toObject; + proto.toDate = toDate; + proto.toISOString = toISOString; + proto.inspect = inspect; + proto.toJSON = toJSON; + proto.toString = toString; + proto.unix = unix; + proto.valueOf = valueOf; + proto.creationData = creationData; + proto.year = getSetYear; + proto.isLeapYear = getIsLeapYear; + proto.weekYear = getSetWeekYear; + proto.isoWeekYear = getSetISOWeekYear; + proto.quarter = proto.quarters = getSetQuarter; + proto.month = getSetMonth; + proto.daysInMonth = getDaysInMonth; + proto.week = proto.weeks = getSetWeek; + proto.isoWeek = proto.isoWeeks = getSetISOWeek; + proto.weeksInYear = getWeeksInYear; + proto.isoWeeksInYear = getISOWeeksInYear; + proto.date = getSetDayOfMonth; + proto.day = proto.days = getSetDayOfWeek; + proto.weekday = getSetLocaleDayOfWeek; + proto.isoWeekday = getSetISODayOfWeek; + proto.dayOfYear = getSetDayOfYear; + proto.hour = proto.hours = getSetHour; + proto.minute = proto.minutes = getSetMinute; + proto.second = proto.seconds = getSetSecond; + proto.millisecond = proto.milliseconds = getSetMillisecond; + proto.utcOffset = getSetOffset; + proto.utc = setOffsetToUTC; + proto.local = setOffsetToLocal; + proto.parseZone = setOffsetToParsedOffset; + proto.hasAlignedHourOffset = hasAlignedHourOffset; + proto.isDST = isDaylightSavingTime; + proto.isLocal = isLocal; + proto.isUtcOffset = isUtcOffset; + proto.isUtc = isUtc; + proto.isUTC = isUtc; + proto.zoneAbbr = getZoneAbbr; + proto.zoneName = getZoneName; + proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); + proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); + proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); + proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); + proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); + + function createUnix (input) { + return createLocal(input * 1000); + } + + function createInZone () { + return createLocal.apply(null, arguments).parseZone(); + } + + function preParsePostFormat (string) { + return string; + } + + var proto$1 = Locale.prototype; + + proto$1.calendar = calendar; + proto$1.longDateFormat = longDateFormat; + proto$1.invalidDate = invalidDate; + proto$1.ordinal = ordinal; + proto$1.preparse = preParsePostFormat; + proto$1.postformat = preParsePostFormat; + proto$1.relativeTime = relativeTime; + proto$1.pastFuture = pastFuture; + proto$1.set = set; + + proto$1.months = localeMonths; + proto$1.monthsShort = localeMonthsShort; + proto$1.monthsParse = localeMonthsParse; + proto$1.monthsRegex = monthsRegex; + proto$1.monthsShortRegex = monthsShortRegex; + proto$1.week = localeWeek; + proto$1.firstDayOfYear = localeFirstDayOfYear; + proto$1.firstDayOfWeek = localeFirstDayOfWeek; + + proto$1.weekdays = localeWeekdays; + proto$1.weekdaysMin = localeWeekdaysMin; + proto$1.weekdaysShort = localeWeekdaysShort; + proto$1.weekdaysParse = localeWeekdaysParse; + + proto$1.weekdaysRegex = weekdaysRegex; + proto$1.weekdaysShortRegex = weekdaysShortRegex; + proto$1.weekdaysMinRegex = weekdaysMinRegex; + + proto$1.isPM = localeIsPM; + proto$1.meridiem = localeMeridiem; + + function get$1 (format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); + return locale[field](utc, format); + } + + function listMonthsImpl (format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return get$1(format, index, field, 'month'); + } + + var i; + var out = []; + for (i = 0; i < 12; i++) { + out[i] = get$1(format, i, field, 'month'); + } + return out; + } + + // () + // (5) + // (fmt, 5) + // (fmt) + // (true) + // (true, 5) + // (true, fmt, 5) + // (true, fmt) + function listWeekdaysImpl (localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0; + + if (index != null) { + return get$1(format, (index + shift) % 7, field, 'day'); + } + + var i; + var out = []; + for (i = 0; i < 7; i++) { + out[i] = get$1(format, (i + shift) % 7, field, 'day'); + } + return out; + } + + function listMonths (format, index) { + return listMonthsImpl(format, index, 'months'); + } + + function listMonthsShort (format, index) { + return listMonthsImpl(format, index, 'monthsShort'); + } + + function listWeekdays (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); + } + + function listWeekdaysShort (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); + } + + function listWeekdaysMin (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); + } + + getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + // Side effect imports + + hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); + hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); + + var mathAbs = Math.abs; + + function abs () { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; + } + + function addSubtract$1 (duration, input, value, direction) { + var other = createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); + } + + // supports only 2.0-style add(1, 's') or add(duration) + function add$1 (input, value) { + return addSubtract$1(this, input, value, 1); + } + + // supports only 2.0-style subtract(1, 's') or subtract(duration) + function subtract$1 (input, value) { + return addSubtract$1(this, input, value, -1); + } + + function absCeil (number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } + } + + function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; + + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; + } + + function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; + } + + function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; + } + + function as (units) { + if (!this.isValid()) { + return NaN; + } + var days; + var months; + var milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } + } + + // TODO: Use this.as('ms')? + function valueOf$1 () { + if (!this.isValid()) { + return NaN; + } + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); + } + + function makeAs (alias) { + return function () { + return this.as(alias); + }; + } + + var asMilliseconds = makeAs('ms'); + var asSeconds = makeAs('s'); + var asMinutes = makeAs('m'); + var asHours = makeAs('h'); + var asDays = makeAs('d'); + var asWeeks = makeAs('w'); + var asMonths = makeAs('M'); + var asYears = makeAs('y'); + + function clone$1 () { + return createDuration(this); + } + + function get$2 (units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; + } + + function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; + } + + var milliseconds = makeGetter('milliseconds'); + var seconds = makeGetter('seconds'); + var minutes = makeGetter('minutes'); + var hours = makeGetter('hours'); + var days = makeGetter('days'); + var months = makeGetter('months'); + var years = makeGetter('years'); + + function weeks () { + return absFloor(this.days() / 7); + } + + var round = Math.round; + var thresholds = { + ss: 44, // a few seconds to seconds + s : 45, // seconds to minute + m : 45, // minutes to hour + h : 22, // hours to day + d : 26, // days to month + M : 11 // months to year + }; + + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } + + function relativeTime$1 (posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + + var a = seconds <= thresholds.ss && ['s', seconds] || + seconds < thresholds.s && ['ss', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); + } + + // This function allows you to set the rounding function for relative time strings + function getSetRelativeTimeRounding (roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + if (typeof(roundingFunction) === 'function') { + round = roundingFunction; + return true; + } + return false; + } + + // This function allows you to set a threshold for relative time strings + function getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } + return true; + } + + function humanize (withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var locale = this.localeData(); + var output = relativeTime$1(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); + } + + var abs$1 = Math.abs; + + function sign(x) { + return ((x > 0) - (x < 0)) || +x; + } + + function toISOString$1() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs$1(this._milliseconds) / 1000; + var days = abs$1(this._days); + var months = abs$1(this._months); + var minutes, hours, years; + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + + return totalSign + 'P' + + (Y ? ymSign + Y + 'Y' : '') + + (M ? ymSign + M + 'M' : '') + + (D ? daysSign + D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? hmsSign + h + 'H' : '') + + (m ? hmsSign + m + 'M' : '') + + (s ? hmsSign + s + 'S' : ''); + } + + var proto$2 = Duration.prototype; + + proto$2.isValid = isValid$1; + proto$2.abs = abs; + proto$2.add = add$1; + proto$2.subtract = subtract$1; + proto$2.as = as; + proto$2.asMilliseconds = asMilliseconds; + proto$2.asSeconds = asSeconds; + proto$2.asMinutes = asMinutes; + proto$2.asHours = asHours; + proto$2.asDays = asDays; + proto$2.asWeeks = asWeeks; + proto$2.asMonths = asMonths; + proto$2.asYears = asYears; + proto$2.valueOf = valueOf$1; + proto$2._bubble = bubble; + proto$2.clone = clone$1; + proto$2.get = get$2; + proto$2.milliseconds = milliseconds; + proto$2.seconds = seconds; + proto$2.minutes = minutes; + proto$2.hours = hours; + proto$2.days = days; + proto$2.weeks = weeks; + proto$2.months = months; + proto$2.years = years; + proto$2.humanize = humanize; + proto$2.toISOString = toISOString$1; + proto$2.toString = toISOString$1; + proto$2.toJSON = toISOString$1; + proto$2.locale = locale; + proto$2.localeData = localeData; + + proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); + proto$2.lang = lang; + + // Side effect imports + + // FORMATTING + + addFormatToken('X', 0, 0, 'unix'); + addFormatToken('x', 0, 0, 'valueOf'); + + // PARSING + + addRegexToken('x', matchSigned); + addRegexToken('X', matchTimestamp); + addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); + }); + addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); + }); + + // Side effect imports + + + hooks.version = '2.22.2'; + + setHookCallback(createLocal); + + hooks.fn = proto; + hooks.min = min; + hooks.max = max; + hooks.now = now; + hooks.utc = createUTC; + hooks.unix = createUnix; + hooks.months = listMonths; + hooks.isDate = isDate; + hooks.locale = getSetGlobalLocale; + hooks.invalid = createInvalid; + hooks.duration = createDuration; + hooks.isMoment = isMoment; + hooks.weekdays = listWeekdays; + hooks.parseZone = createInZone; + hooks.localeData = getLocale; + hooks.isDuration = isDuration; + hooks.monthsShort = listMonthsShort; + hooks.weekdaysMin = listWeekdaysMin; + hooks.defineLocale = defineLocale; + hooks.updateLocale = updateLocale; + hooks.locales = listLocales; + hooks.weekdaysShort = listWeekdaysShort; + hooks.normalizeUnits = normalizeUnits; + hooks.relativeTimeRounding = getSetRelativeTimeRounding; + hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; + hooks.calendarFormat = getCalendarFormat; + hooks.prototype = proto; + + // currently HTML5 input type only supports 24-hour formats + hooks.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'YYYY-[W]WW', // + MONTH: 'YYYY-MM' // + }; + + return hooks; + +}))); diff --git a/nodejs/node_modules/moment/package.js b/nodejs/node_modules/moment/package.js new file mode 100755 index 0000000..aba8d50 --- /dev/null +++ b/nodejs/node_modules/moment/package.js @@ -0,0 +1,11 @@ +var profile = { + resourceTags: { + ignore: function(filename, mid){ + // only include moment/moment + return mid != "moment/moment"; + }, + amd: function(filename, mid){ + return /\.js$/.test(filename); + } + } +}; diff --git a/nodejs/node_modules/moment/package.json b/nodejs/node_modules/moment/package.json new file mode 100755 index 0000000..a60949f --- /dev/null +++ b/nodejs/node_modules/moment/package.json @@ -0,0 +1,150 @@ +{ + "_args": [ + [ + "moment@2.22.2", + "/www/wwwroot/Adminx.cc/nodejs" + ] + ], + "_from": "moment@2.22.2", + "_id": "moment@2.22.2", + "_inBundle": false, + "_integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "_location": "/moment", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "moment@2.22.2", + "name": "moment", + "escapedName": "moment", + "rawSpec": "2.22.2", + "saveSpec": null, + "fetchSpec": "2.22.2" + }, + "_requiredBy": [ + "/moment-timezone" + ], + "_resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "_spec": "2.22.2", + "_where": "/www/wwwroot/Adminx.cc/nodejs", + "author": { + "name": "Iskren Ivov Chernev", + "email": "iskren.chernev@gmail.com", + "url": "https://github.com/ichernev" + }, + "bugs": { + "url": "https://github.com/moment/moment/issues" + }, + "contributors": [ + { + "name": "Tim Wood", + "email": "washwithcare@gmail.com", + "url": "http://timwoodcreates.com/" + }, + { + "name": "Rocky Meza", + "url": "http://rockymeza.com" + }, + { + "name": "Matt Johnson", + "email": "mj1856@hotmail.com", + "url": "http://codeofmatt.com" + }, + { + "name": "Isaac Cambron", + "email": "isaac@isaaccambron.com", + "url": "http://isaaccambron.com" + }, + { + "name": "Andre Polykanine", + "email": "andre@oire.org", + "url": "https://github.com/oire" + } + ], + "description": "Parse, validate, manipulate, and display dates", + "devDependencies": { + "benchmark": "latest", + "coveralls": "^2.11.2", + "es6-promise": "latest", + "grunt": "~0.4", + "grunt-benchmark": "latest", + "grunt-cli": "latest", + "grunt-contrib-clean": "latest", + "grunt-contrib-concat": "latest", + "grunt-contrib-copy": "latest", + "grunt-contrib-jshint": "latest", + "grunt-contrib-uglify": "latest", + "grunt-contrib-watch": "latest", + "grunt-env": "latest", + "grunt-exec": "latest", + "grunt-jscs": "latest", + "grunt-karma": "latest", + "grunt-nuget": "latest", + "grunt-string-replace": "latest", + "karma": "latest", + "karma-chrome-launcher": "latest", + "karma-firefox-launcher": "latest", + "karma-qunit": "latest", + "karma-sauce-launcher": "latest", + "load-grunt-tasks": "~3.5.2", + "node-qunit": "^1.0.0", + "nyc": "^2.1.4", + "qunit": "^2.6.0", + "rollup": "latest", + "spacejam": "latest", + "typescript": "^1.8.10", + "uglify-js": "latest" + }, + "dojoBuild": "package.js", + "ender": "./ender.js", + "engines": { + "node": "*" + }, + "homepage": "http://momentjs.com", + "jsnext:main": "./src/moment.js", + "jspm": { + "files": [ + "moment.js", + "moment.d.ts", + "locale" + ], + "map": { + "moment": "./moment" + }, + "buildConfig": { + "uglify": true + } + }, + "keywords": [ + "moment", + "date", + "time", + "parse", + "format", + "validate", + "i18n", + "l10n", + "ender" + ], + "license": "MIT", + "main": "./moment.js", + "name": "moment", + "repository": { + "type": "git", + "url": "git+https://github.com/moment/moment.git" + }, + "scripts": { + "coverage": "nyc npm test && nyc report", + "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", + "test": "grunt test", + "typescript-test": "tsc --project typing-tests" + }, + "spm": { + "main": "moment.js", + "output": [ + "locale/*.js" + ] + }, + "typings": "./moment.d.ts", + "version": "2.22.2" +} diff --git a/nodejs/node_modules/moment/src/lib/create/check-overflow.js b/nodejs/node_modules/moment/src/lib/create/check-overflow.js new file mode 100755 index 0000000..41b539f --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/check-overflow.js @@ -0,0 +1,34 @@ +import { daysInMonth } from '../units/month'; +import { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND, WEEK, WEEKDAY } from '../units/constants'; +import getParsingFlags from '../create/parsing-flags'; + +export default function checkOverflow (m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; +} + diff --git a/nodejs/node_modules/moment/src/lib/create/date-from-array.js b/nodejs/node_modules/moment/src/lib/create/date-from-array.js new file mode 100755 index 0000000..59b57b0 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/date-from-array.js @@ -0,0 +1,21 @@ +export function createDate (y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date = new Date(y, m, d, h, M, s, ms); + + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { + date.setFullYear(y); + } + return date; +} + +export function createUTCDate (y) { + var date = new Date(Date.UTC.apply(null, arguments)); + + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + return date; +} diff --git a/nodejs/node_modules/moment/src/lib/create/from-anything.js b/nodejs/node_modules/moment/src/lib/create/from-anything.js new file mode 100755 index 0000000..e692679 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/from-anything.js @@ -0,0 +1,110 @@ +import isArray from '../utils/is-array'; +import isObject from '../utils/is-object'; +import isObjectEmpty from '../utils/is-object-empty'; +import isUndefined from '../utils/is-undefined'; +import isNumber from '../utils/is-number'; +import isDate from '../utils/is-date'; +import map from '../utils/map'; +import { createInvalid } from './valid'; +import { Moment, isMoment } from '../moment/constructor'; +import { getLocale } from '../locale/locales'; +import { hooks } from '../utils/hooks'; +import checkOverflow from './check-overflow'; +import { isValid } from './valid'; + +import { configFromStringAndArray } from './from-string-and-array'; +import { configFromStringAndFormat } from './from-string-and-format'; +import { configFromString } from './from-string'; +import { configFromArray } from './from-array'; +import { configFromObject } from './from-object'; + +function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; +} + +export function prepareConfig (config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || getLocale(config._l); + + if (input === null || (format === undefined && input === '')) { + return createInvalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } + + if (!isValid(config)) { + config._d = null; + } + + return config; +} + +function configFromInput(config) { + var input = config._i; + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } +} + +export function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; + + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } + + if ((isObject(input) && isObjectEmpty(input)) || + (isArray(input) && input.length === 0)) { + input = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + + return createFromConfig(c); +} diff --git a/nodejs/node_modules/moment/src/lib/create/from-array.js b/nodejs/node_modules/moment/src/lib/create/from-array.js new file mode 100755 index 0000000..b5a0911 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/from-array.js @@ -0,0 +1,147 @@ +import { hooks } from '../utils/hooks'; +import { createDate, createUTCDate } from './date-from-array'; +import { daysInYear } from '../units/year'; +import { weekOfYear, weeksInYear, dayOfYearFromWeeks } from '../units/week-calendar-utils'; +import { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants'; +import { createLocal } from './local'; +import defaults from '../utils/defaults'; +import getParsingFlags from './parsing-flags'; + +function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; +} + +// convert an array to a date. +// the array should mirror the parameters below +// note: all values past the year are optional and will default to the lowest possible value. +// [year, month, day , hour, minute, second, millisecond] +export function configFromArray (config) { + var i, date, input = [], currentDate, expectedWeekday, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); + + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + + // check for mismatching day of week + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { + getParsingFlags(config).weekdayMismatch = true; + } +} + +function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + var curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to begining of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } +} diff --git a/nodejs/node_modules/moment/src/lib/create/from-object.js b/nodejs/node_modules/moment/src/lib/create/from-object.js new file mode 100755 index 0000000..c0bfe9f --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/from-object.js @@ -0,0 +1,16 @@ +import { normalizeObjectUnits } from '../units/aliases'; +import { configFromArray } from './from-array'; +import map from '../utils/map'; + +export function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + + configFromArray(config); +} diff --git a/nodejs/node_modules/moment/src/lib/create/from-string-and-array.js b/nodejs/node_modules/moment/src/lib/create/from-string-and-array.js new file mode 100755 index 0000000..1d8a7a8 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/from-string-and-array.js @@ -0,0 +1,50 @@ +import { copyConfig } from '../moment/constructor'; +import { configFromStringAndFormat } from './from-string-and-format'; +import getParsingFlags from './parsing-flags'; +import { isValid } from './valid'; +import extend from '../utils/extend'; + +// date from string and array of format strings +export function configFromStringAndArray(config) { + var tempConfig, + bestMoment, + + scoreToBeat, + i, + currentScore; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (!isValid(tempConfig)) { + continue; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; + + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); +} diff --git a/nodejs/node_modules/moment/src/lib/create/from-string-and-format.js b/nodejs/node_modules/moment/src/lib/create/from-string-and-format.js new file mode 100755 index 0000000..ed921d5 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/from-string-and-format.js @@ -0,0 +1,113 @@ +import { configFromISO, configFromRFC2822 } from './from-string'; +import { configFromArray } from './from-array'; +import { getParseRegexForToken } from '../parse/regex'; +import { addTimeToArrayFromToken } from '../parse/token'; +import { expandFormat, formatTokenFunctions, formattingTokens } from '../format/format'; +import checkOverflow from './check-overflow'; +import { HOUR } from '../units/constants'; +import { hooks } from '../utils/hooks'; +import getParsingFlags from './parsing-flags'; + +// constant that refers to the ISO standard +hooks.ISO_8601 = function () {}; + +// constant that refers to the RFC 2822 form +hooks.RFC_2822 = function () {}; + +// date from string and format string +export function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + config._a = []; + getParsingFlags(config).empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; + + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } + else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } + + // clear _12h flag if hour is <= 12 + if (config._a[HOUR] <= 12 && + getParsingFlags(config).bigHour === true && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; + } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + + configFromArray(config); + checkOverflow(config); +} + + +function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } +} diff --git a/nodejs/node_modules/moment/src/lib/create/from-string.js b/nodejs/node_modules/moment/src/lib/create/from-string.js new file mode 100755 index 0000000..c5ad56b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/from-string.js @@ -0,0 +1,230 @@ +import { configFromStringAndFormat } from './from-string-and-format'; +import { createUTCDate } from './date-from-array'; +import { configFromArray } from './from-array'; +import { hooks } from '../utils/hooks'; +import { deprecate } from '../utils/deprecate'; +import getParsingFlags from './parsing-flags'; +import {defaultLocaleMonthsShort} from '../units/month'; +import {defaultLocaleWeekdaysShort} from '../units/day-of-week'; + +// iso 8601 regex +// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) +var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; +var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + +var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + +var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] +]; + +// iso time formats and regexes +var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] +]; + +var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + +// date from iso format +export function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } +} + +// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 +var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; + +function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10) + ]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; +} + +function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; +} + +function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); +} + +function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; +} + +var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 +}; + +function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; + } +} + +// date and time from ref 2822 format +export function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } +} + +// date from iso format or fallback +export function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); +} + +hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged and will be removed in an upcoming major release. Please refer to ' + + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } +); diff --git a/nodejs/node_modules/moment/src/lib/create/local.js b/nodejs/node_modules/moment/src/lib/create/local.js new file mode 100755 index 0000000..88c1e26 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/local.js @@ -0,0 +1,5 @@ +import { createLocalOrUTC } from './from-anything'; + +export function createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); +} diff --git a/nodejs/node_modules/moment/src/lib/create/parsing-flags.js b/nodejs/node_modules/moment/src/lib/create/parsing-flags.js new file mode 100755 index 0000000..c47173f --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/parsing-flags.js @@ -0,0 +1,26 @@ +function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false, + parsedDateParts : [], + meridiem : null, + rfc2822 : false, + weekdayMismatch : false + }; +} + +export default function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; +} diff --git a/nodejs/node_modules/moment/src/lib/create/utc.js b/nodejs/node_modules/moment/src/lib/create/utc.js new file mode 100755 index 0000000..9613953 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/utc.js @@ -0,0 +1,5 @@ +import { createLocalOrUTC } from './from-anything'; + +export function createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); +} diff --git a/nodejs/node_modules/moment/src/lib/create/valid.js b/nodejs/node_modules/moment/src/lib/create/valid.js new file mode 100755 index 0000000..d13f12f --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/create/valid.js @@ -0,0 +1,50 @@ +import extend from '../utils/extend'; +import { createUTC } from './utc'; +import getParsingFlags from '../create/parsing-flags'; +import some from '../utils/some'; + +export function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); + var isNowValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.weekdayMismatch && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); + + if (m._strict) { + isNowValid = isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } + else { + return isNowValid; + } + } + return m._isValid; +} + +export function createInvalid (flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; +} diff --git a/nodejs/node_modules/moment/src/lib/duration/abs.js b/nodejs/node_modules/moment/src/lib/duration/abs.js new file mode 100755 index 0000000..103a4cf --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/abs.js @@ -0,0 +1,18 @@ +var mathAbs = Math.abs; + +export function abs () { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; +} diff --git a/nodejs/node_modules/moment/src/lib/duration/add-subtract.js b/nodejs/node_modules/moment/src/lib/duration/add-subtract.js new file mode 100755 index 0000000..3b44e18 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/add-subtract.js @@ -0,0 +1,21 @@ +import { createDuration } from './create'; + +function addSubtract (duration, input, value, direction) { + var other = createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); +} + +// supports only 2.0-style add(1, 's') or add(duration) +export function add (input, value) { + return addSubtract(this, input, value, 1); +} + +// supports only 2.0-style subtract(1, 's') or subtract(duration) +export function subtract (input, value) { + return addSubtract(this, input, value, -1); +} diff --git a/nodejs/node_modules/moment/src/lib/duration/as.js b/nodejs/node_modules/moment/src/lib/duration/as.js new file mode 100755 index 0000000..122204a --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/as.js @@ -0,0 +1,61 @@ +import { daysToMonths, monthsToDays } from './bubble'; +import { normalizeUnits } from '../units/aliases'; +import toInt from '../utils/to-int'; + +export function as (units) { + if (!this.isValid()) { + return NaN; + } + var days; + var months; + var milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } +} + +// TODO: Use this.as('ms')? +export function valueOf () { + if (!this.isValid()) { + return NaN; + } + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); +} + +function makeAs (alias) { + return function () { + return this.as(alias); + }; +} + +export var asMilliseconds = makeAs('ms'); +export var asSeconds = makeAs('s'); +export var asMinutes = makeAs('m'); +export var asHours = makeAs('h'); +export var asDays = makeAs('d'); +export var asWeeks = makeAs('w'); +export var asMonths = makeAs('M'); +export var asYears = makeAs('y'); diff --git a/nodejs/node_modules/moment/src/lib/duration/bubble.js b/nodejs/node_modules/moment/src/lib/duration/bubble.js new file mode 100755 index 0000000..0c4a336 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/bubble.js @@ -0,0 +1,61 @@ +import absFloor from '../utils/abs-floor'; +import absCeil from '../utils/abs-ceil'; +import { createUTCDate } from '../create/date-from-array'; + +export function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; + + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; +} + +export function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; +} + +export function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; +} diff --git a/nodejs/node_modules/moment/src/lib/duration/clone.js b/nodejs/node_modules/moment/src/lib/duration/clone.js new file mode 100755 index 0000000..56008d1 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/clone.js @@ -0,0 +1,6 @@ +import { createDuration } from './create'; + +export function clone () { + return createDuration(this); +} + diff --git a/nodejs/node_modules/moment/src/lib/duration/constructor.js b/nodejs/node_modules/moment/src/lib/duration/constructor.js new file mode 100755 index 0000000..2d86d5e --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/constructor.js @@ -0,0 +1,44 @@ +import { normalizeObjectUnits } from '../units/aliases'; +import { getLocale } from '../locale/locales'; +import isDurationValid from './valid.js'; + +export function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + this._isValid = isDurationValid(normalizedInput); + + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = getLocale(); + + this._bubble(); +} + +export function isDuration (obj) { + return obj instanceof Duration; +} diff --git a/nodejs/node_modules/moment/src/lib/duration/create.js b/nodejs/node_modules/moment/src/lib/duration/create.js new file mode 100755 index 0000000..3468148 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/create.js @@ -0,0 +1,122 @@ +import { Duration, isDuration } from './constructor'; +import isNumber from '../utils/is-number'; +import toInt from '../utils/to-int'; +import absRound from '../utils/abs-round'; +import hasOwnProp from '../utils/has-own-prop'; +import { DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants'; +import { cloneWithOffset } from '../units/offset'; +import { createLocal } from '../create/local'; +import { createInvalid as invalid } from './valid'; + +// ASP.NET json date format regex +var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; + +// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html +// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere +// and further modified to allow for strings containing both week and day +var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + +export function createDuration (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms : input._milliseconds, + d : input._days, + M : input._months + }; + } else if (isNumber(input)) { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; + duration = { + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) + }; + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + return ret; +} + +createDuration.fn = Duration.prototype; +createDuration.invalid = invalid; + +function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; +} + +function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; +} + +function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } + + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; +} diff --git a/nodejs/node_modules/moment/src/lib/duration/duration.js b/nodejs/node_modules/moment/src/lib/duration/duration.js new file mode 100755 index 0000000..528b568 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/duration.js @@ -0,0 +1,16 @@ +// Side effect imports +import './prototype'; + +import { createDuration } from './create'; +import { isDuration } from './constructor'; +import { + getSetRelativeTimeRounding, + getSetRelativeTimeThreshold +} from './humanize'; + +export { + createDuration, + isDuration, + getSetRelativeTimeRounding, + getSetRelativeTimeThreshold +}; diff --git a/nodejs/node_modules/moment/src/lib/duration/get.js b/nodejs/node_modules/moment/src/lib/duration/get.js new file mode 100755 index 0000000..8993e07 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/get.js @@ -0,0 +1,25 @@ +import { normalizeUnits } from '../units/aliases'; +import absFloor from '../utils/abs-floor'; + +export function get (units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; +} + +function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; +} + +export var milliseconds = makeGetter('milliseconds'); +export var seconds = makeGetter('seconds'); +export var minutes = makeGetter('minutes'); +export var hours = makeGetter('hours'); +export var days = makeGetter('days'); +export var months = makeGetter('months'); +export var years = makeGetter('years'); + +export function weeks () { + return absFloor(this.days() / 7); +} diff --git a/nodejs/node_modules/moment/src/lib/duration/humanize.js b/nodejs/node_modules/moment/src/lib/duration/humanize.js new file mode 100755 index 0000000..454b01a --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/humanize.js @@ -0,0 +1,85 @@ +import { createDuration } from './create'; + +var round = Math.round; +var thresholds = { + ss: 44, // a few seconds to seconds + s : 45, // seconds to minute + m : 45, // minutes to hour + h : 22, // hours to day + d : 26, // days to month + M : 11 // months to year +}; + +// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize +function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); +} + +function relativeTime (posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + + var a = seconds <= thresholds.ss && ['s', seconds] || + seconds < thresholds.s && ['ss', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); +} + +// This function allows you to set the rounding function for relative time strings +export function getSetRelativeTimeRounding (roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + if (typeof(roundingFunction) === 'function') { + round = roundingFunction; + return true; + } + return false; +} + +// This function allows you to set a threshold for relative time strings +export function getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } + return true; +} + +export function humanize (withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var locale = this.localeData(); + var output = relativeTime(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); +} diff --git a/nodejs/node_modules/moment/src/lib/duration/iso-string.js b/nodejs/node_modules/moment/src/lib/duration/iso-string.js new file mode 100755 index 0000000..419f363 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/iso-string.js @@ -0,0 +1,64 @@ +import absFloor from '../utils/abs-floor'; +var abs = Math.abs; + +function sign(x) { + return ((x > 0) - (x < 0)) || +x; +} + +export function toISOString() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs(this._milliseconds) / 1000; + var days = abs(this._days); + var months = abs(this._months); + var minutes, hours, years; + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + + return totalSign + 'P' + + (Y ? ymSign + Y + 'Y' : '') + + (M ? ymSign + M + 'M' : '') + + (D ? daysSign + D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? hmsSign + h + 'H' : '') + + (m ? hmsSign + m + 'M' : '') + + (s ? hmsSign + s + 'S' : ''); +} diff --git a/nodejs/node_modules/moment/src/lib/duration/prototype.js b/nodejs/node_modules/moment/src/lib/duration/prototype.js new file mode 100755 index 0000000..dd5470d --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/prototype.js @@ -0,0 +1,52 @@ +import { Duration } from './constructor'; + +var proto = Duration.prototype; + +import { abs } from './abs'; +import { add, subtract } from './add-subtract'; +import { as, asMilliseconds, asSeconds, asMinutes, asHours, asDays, asWeeks, asMonths, asYears, valueOf } from './as'; +import { bubble } from './bubble'; +import { clone } from './clone'; +import { get, milliseconds, seconds, minutes, hours, days, months, years, weeks } from './get'; +import { humanize } from './humanize'; +import { toISOString } from './iso-string'; +import { lang, locale, localeData } from '../moment/locale'; +import { isValid } from './valid'; + +proto.isValid = isValid; +proto.abs = abs; +proto.add = add; +proto.subtract = subtract; +proto.as = as; +proto.asMilliseconds = asMilliseconds; +proto.asSeconds = asSeconds; +proto.asMinutes = asMinutes; +proto.asHours = asHours; +proto.asDays = asDays; +proto.asWeeks = asWeeks; +proto.asMonths = asMonths; +proto.asYears = asYears; +proto.valueOf = valueOf; +proto._bubble = bubble; +proto.clone = clone; +proto.get = get; +proto.milliseconds = milliseconds; +proto.seconds = seconds; +proto.minutes = minutes; +proto.hours = hours; +proto.days = days; +proto.weeks = weeks; +proto.months = months; +proto.years = years; +proto.humanize = humanize; +proto.toISOString = toISOString; +proto.toString = toISOString; +proto.toJSON = toISOString; +proto.locale = locale; +proto.localeData = localeData; + +// Deprecations +import { deprecate } from '../utils/deprecate'; + +proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString); +proto.lang = lang; diff --git a/nodejs/node_modules/moment/src/lib/duration/valid.js b/nodejs/node_modules/moment/src/lib/duration/valid.js new file mode 100755 index 0000000..033fd5b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/duration/valid.js @@ -0,0 +1,36 @@ +import toInt from '../utils/to-int'; +import indexOf from '../utils/index-of'; +import {Duration} from './constructor'; +import {createDuration} from './create'; + +var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + +export default function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } + } + + var unitHasDecimal = false; + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; +} + +export function isValid() { + return this._isValid; +} + +export function createInvalid() { + return createDuration(NaN); +} diff --git a/nodejs/node_modules/moment/src/lib/format/format.js b/nodejs/node_modules/moment/src/lib/format/format.js new file mode 100755 index 0000000..03f5c58 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/format/format.js @@ -0,0 +1,92 @@ +import zeroFill from '../utils/zero-fill'; +import isFunction from '../utils/is-function'; + +export var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + +var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + +var formatFunctions = {}; + +export var formatTokenFunctions = {}; + +// token: 'M' +// padded: ['MM', 2] +// ordinal: 'Mo' +// callback: function () { this.month() + 1 } +export function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } +} + +function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); +} + +function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = '', i; + for (i = 0; i < length; i++) { + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; + } + return output; + }; +} + +// format date using native date object +export function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + + return formatFunctions[format](m); +} + +export function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; +} diff --git a/nodejs/node_modules/moment/src/lib/locale/base-config.js b/nodejs/node_modules/moment/src/lib/locale/base-config.js new file mode 100755 index 0000000..d7a7c66 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/base-config.js @@ -0,0 +1,44 @@ +import { defaultCalendar } from './calendar'; +import { defaultLongDateFormat } from './formats'; +import { defaultInvalidDate } from './invalid'; +import { defaultOrdinal, defaultDayOfMonthOrdinalParse } from './ordinal'; +import { defaultRelativeTime } from './relative'; + +// months +import { + defaultLocaleMonths, + defaultLocaleMonthsShort, +} from '../units/month'; + +// week +import { defaultLocaleWeek } from '../units/week'; + +// weekdays +import { + defaultLocaleWeekdays, + defaultLocaleWeekdaysMin, + defaultLocaleWeekdaysShort, +} from '../units/day-of-week'; + +// meridiem +import { defaultLocaleMeridiemParse } from '../units/hour'; + +export var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, + + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, + + week: defaultLocaleWeek, + + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, + + meridiemParse: defaultLocaleMeridiemParse +}; diff --git a/nodejs/node_modules/moment/src/lib/locale/calendar.js b/nodejs/node_modules/moment/src/lib/locale/calendar.js new file mode 100755 index 0000000..f12214b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/calendar.js @@ -0,0 +1,15 @@ +export var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' +}; + +import isFunction from '../utils/is-function'; + +export function calendar (key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; +} diff --git a/nodejs/node_modules/moment/src/lib/locale/constructor.js b/nodejs/node_modules/moment/src/lib/locale/constructor.js new file mode 100755 index 0000000..c32b73e --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/constructor.js @@ -0,0 +1,5 @@ +export function Locale(config) { + if (config != null) { + this.set(config); + } +} diff --git a/nodejs/node_modules/moment/src/lib/locale/en.js b/nodejs/node_modules/moment/src/lib/locale/en.js new file mode 100755 index 0000000..4a7d250 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/en.js @@ -0,0 +1,15 @@ +import './prototype'; +import { getSetGlobalLocale } from './locales'; +import toInt from '../utils/to-int'; + +getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } +}); diff --git a/nodejs/node_modules/moment/src/lib/locale/formats.js b/nodejs/node_modules/moment/src/lib/locale/formats.js new file mode 100755 index 0000000..6d83b03 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/formats.js @@ -0,0 +1,23 @@ +export var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' +}; + +export function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + + return this._longDateFormat[key]; +} diff --git a/nodejs/node_modules/moment/src/lib/locale/invalid.js b/nodejs/node_modules/moment/src/lib/locale/invalid.js new file mode 100755 index 0000000..e909633 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/invalid.js @@ -0,0 +1,5 @@ +export var defaultInvalidDate = 'Invalid date'; + +export function invalidDate () { + return this._invalidDate; +} diff --git a/nodejs/node_modules/moment/src/lib/locale/lists.js b/nodejs/node_modules/moment/src/lib/locale/lists.js new file mode 100755 index 0000000..42f7572 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/lists.js @@ -0,0 +1,93 @@ +import isNumber from '../utils/is-number'; +import { getLocale } from './locales'; +import { createUTC } from '../create/utc'; + +function get (format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); + return locale[field](utc, format); +} + +function listMonthsImpl (format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return get(format, index, field, 'month'); + } + + var i; + var out = []; + for (i = 0; i < 12; i++) { + out[i] = get(format, i, field, 'month'); + } + return out; +} + +// () +// (5) +// (fmt, 5) +// (fmt) +// (true) +// (true, 5) +// (true, fmt, 5) +// (true, fmt) +function listWeekdaysImpl (localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0; + + if (index != null) { + return get(format, (index + shift) % 7, field, 'day'); + } + + var i; + var out = []; + for (i = 0; i < 7; i++) { + out[i] = get(format, (i + shift) % 7, field, 'day'); + } + return out; +} + +export function listMonths (format, index) { + return listMonthsImpl(format, index, 'months'); +} + +export function listMonthsShort (format, index) { + return listMonthsImpl(format, index, 'monthsShort'); +} + +export function listWeekdays (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); +} + +export function listWeekdaysShort (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); +} + +export function listWeekdaysMin (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); +} diff --git a/nodejs/node_modules/moment/src/lib/locale/locale.js b/nodejs/node_modules/moment/src/lib/locale/locale.js new file mode 100755 index 0000000..ac9cebf --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/locale.js @@ -0,0 +1,39 @@ +// Side effect imports +import './prototype'; + +import { + getSetGlobalLocale, + defineLocale, + updateLocale, + getLocale, + listLocales +} from './locales'; + +import { + listMonths, + listMonthsShort, + listWeekdays, + listWeekdaysShort, + listWeekdaysMin +} from './lists'; + +export { + getSetGlobalLocale, + defineLocale, + updateLocale, + getLocale, + listLocales, + listMonths, + listMonthsShort, + listWeekdays, + listWeekdaysShort, + listWeekdaysMin +}; + +import { deprecate } from '../utils/deprecate'; +import { hooks } from '../utils/hooks'; + +hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); +hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); + +import './en'; diff --git a/nodejs/node_modules/moment/src/lib/locale/locales.js b/nodejs/node_modules/moment/src/lib/locale/locales.js new file mode 100755 index 0000000..af28bfe --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/locales.js @@ -0,0 +1,197 @@ +import isArray from '../utils/is-array'; +import hasOwnProp from '../utils/has-own-prop'; +import isUndefined from '../utils/is-undefined'; +import compareArrays from '../utils/compare-arrays'; +import { deprecateSimple } from '../utils/deprecate'; +import { mergeConfigs } from './set'; +import { Locale } from './constructor'; +import keys from '../utils/keys'; + +import { baseConfig } from './base-config'; + +// internal storage for locale config files +var locales = {}; +var localeFamilies = {}; +var globalLocale; + +function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; +} + +// pick the locale from the array +// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each +// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root +function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return globalLocale; +} + +function loadLocale(name) { + var oldLocale = null; + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { + try { + oldLocale = globalLocale._abbr; + var aliasedRequire = require; + aliasedRequire('./locale/' + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} + } + return locales[name]; +} + +// This function will load locale and then set the global locale. If +// no arguments are passed in, it will simply return the current global +// locale key. +export function getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } + else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + else { + if ((typeof console !== 'undefined') && console.warn) { + //warn user if arguments are passed but the locale could not be set + console.warn('Locale ' + key + ' not found. Did you forget to load it?'); + } + } + } + + return globalLocale._abbr; +} + +export function defineLocale (name, config) { + if (config !== null) { + var locale, parentConfig = baseConfig; + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale ' + + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + locale = loadLocale(config.parentLocale); + if (locale != null) { + parentConfig = locale._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } + } + } + locales[name] = new Locale(mergeConfigs(parentConfig, config)); + + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } + + // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); + + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } +} + +export function updateLocale(name, config) { + if (config != null) { + var locale, tmpLocale, parentConfig = baseConfig; + // MERGE + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + config = mergeConfigs(parentConfig, config); + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + + // backwards compat for now: also set the locale + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; +} + +// returns locale data +export function getLocale (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); +} + +export function listLocales() { + return keys(locales); +} diff --git a/nodejs/node_modules/moment/src/lib/locale/ordinal.js b/nodejs/node_modules/moment/src/lib/locale/ordinal.js new file mode 100755 index 0000000..e2efc05 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/ordinal.js @@ -0,0 +1,7 @@ +export var defaultOrdinal = '%d'; +export var defaultDayOfMonthOrdinalParse = /\d{1,2}/; + +export function ordinal (number) { + return this._ordinal.replace('%d', number); +} + diff --git a/nodejs/node_modules/moment/src/lib/locale/pre-post-format.js b/nodejs/node_modules/moment/src/lib/locale/pre-post-format.js new file mode 100755 index 0000000..10ed205 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/pre-post-format.js @@ -0,0 +1,3 @@ +export function preParsePostFormat (string) { + return string; +} diff --git a/nodejs/node_modules/moment/src/lib/locale/prototype.js b/nodejs/node_modules/moment/src/lib/locale/prototype.js new file mode 100755 index 0000000..24eef89 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/prototype.js @@ -0,0 +1,69 @@ +import { Locale } from './constructor'; + +var proto = Locale.prototype; + +import { calendar } from './calendar'; +import { longDateFormat } from './formats'; +import { invalidDate } from './invalid'; +import { ordinal } from './ordinal'; +import { preParsePostFormat } from './pre-post-format'; +import { relativeTime, pastFuture } from './relative'; +import { set } from './set'; + +proto.calendar = calendar; +proto.longDateFormat = longDateFormat; +proto.invalidDate = invalidDate; +proto.ordinal = ordinal; +proto.preparse = preParsePostFormat; +proto.postformat = preParsePostFormat; +proto.relativeTime = relativeTime; +proto.pastFuture = pastFuture; +proto.set = set; + +// Month +import { + localeMonthsParse, + localeMonths, + localeMonthsShort, + monthsRegex, + monthsShortRegex +} from '../units/month'; + +proto.months = localeMonths; +proto.monthsShort = localeMonthsShort; +proto.monthsParse = localeMonthsParse; +proto.monthsRegex = monthsRegex; +proto.monthsShortRegex = monthsShortRegex; + +// Week +import { localeWeek, localeFirstDayOfYear, localeFirstDayOfWeek } from '../units/week'; +proto.week = localeWeek; +proto.firstDayOfYear = localeFirstDayOfYear; +proto.firstDayOfWeek = localeFirstDayOfWeek; + +// Day of Week +import { + localeWeekdaysParse, + localeWeekdays, + localeWeekdaysMin, + localeWeekdaysShort, + + weekdaysRegex, + weekdaysShortRegex, + weekdaysMinRegex +} from '../units/day-of-week'; + +proto.weekdays = localeWeekdays; +proto.weekdaysMin = localeWeekdaysMin; +proto.weekdaysShort = localeWeekdaysShort; +proto.weekdaysParse = localeWeekdaysParse; + +proto.weekdaysRegex = weekdaysRegex; +proto.weekdaysShortRegex = weekdaysShortRegex; +proto.weekdaysMinRegex = weekdaysMinRegex; + +// Hours +import { localeIsPM, localeMeridiem } from '../units/hour'; + +proto.isPM = localeIsPM; +proto.meridiem = localeMeridiem; diff --git a/nodejs/node_modules/moment/src/lib/locale/relative.js b/nodejs/node_modules/moment/src/lib/locale/relative.js new file mode 100755 index 0000000..431466b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/relative.js @@ -0,0 +1,30 @@ +export var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' +}; + +import isFunction from '../utils/is-function'; + +export function relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); +} + +export function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); +} diff --git a/nodejs/node_modules/moment/src/lib/locale/set.js b/nodejs/node_modules/moment/src/lib/locale/set.js new file mode 100755 index 0000000..c63d5ad --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/locale/set.js @@ -0,0 +1,49 @@ +import isFunction from '../utils/is-function'; +import extend from '../utils/extend'; +import isObject from '../utils/is-object'; +import hasOwnProp from '../utils/has-own-prop'; + +export function set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + (/\d{1,2}/).source); +} + +export function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + for (prop in parentConfig) { + if (hasOwnProp(parentConfig, prop) && + !hasOwnProp(childConfig, prop) && + isObject(parentConfig[prop])) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + return res; +} diff --git a/nodejs/node_modules/moment/src/lib/moment/add-subtract.js b/nodejs/node_modules/moment/src/lib/moment/add-subtract.js new file mode 100755 index 0000000..e758b5d --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/add-subtract.js @@ -0,0 +1,55 @@ +import { get, set } from './get-set'; +import { setMonth } from '../units/month'; +import { createDuration } from '../duration/create'; +import { deprecateSimple } from '../utils/deprecate'; +import { hooks } from '../utils/hooks'; +import absRound from '../utils/abs-round'; + + +// TODO: remove 'name' arg after deprecation is removed +function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; +} + +export function addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } +} + +export var add = createAdder(1, 'add'); +export var subtract = createAdder(-1, 'subtract'); + diff --git a/nodejs/node_modules/moment/src/lib/moment/calendar.js b/nodejs/node_modules/moment/src/lib/moment/calendar.js new file mode 100755 index 0000000..4b5725c --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/calendar.js @@ -0,0 +1,26 @@ +import { createLocal } from '../create/local'; +import { cloneWithOffset } from '../units/offset'; +import isFunction from '../utils/is-function'; +import { hooks } from '../utils/hooks'; + +export function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; +} + +export function calendar (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; + + var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/clone.js b/nodejs/node_modules/moment/src/lib/moment/clone.js new file mode 100755 index 0000000..d96b328 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/clone.js @@ -0,0 +1,5 @@ +import { Moment } from './constructor'; + +export function clone () { + return new Moment(this); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/compare.js b/nodejs/node_modules/moment/src/lib/moment/compare.js new file mode 100755 index 0000000..b26bac6 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/compare.js @@ -0,0 +1,59 @@ +import { isMoment } from './constructor'; +import { normalizeUnits } from '../units/aliases'; +import { createLocal } from '../create/local'; +import isUndefined from '../utils/is-undefined'; + +export function isAfter (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } +} + +export function isBefore (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } +} + +export function isBetween (from, to, units, inclusivity) { + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && + (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); +} + +export function isSame (input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + } +} + +export function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input,units); +} + +export function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input,units); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/constructor.js b/nodejs/node_modules/moment/src/lib/moment/constructor.js new file mode 100755 index 0000000..bc53f81 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/constructor.js @@ -0,0 +1,77 @@ +import { hooks } from '../utils/hooks'; +import hasOwnProp from '../utils/has-own-prop'; +import isUndefined from '../utils/is-undefined'; +import getParsingFlags from '../create/parsing-flags'; + +// Plugins that add properties should also add the key here (null value), +// so we can properly clone ourselves. +var momentProperties = hooks.momentProperties = []; + +export function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; +} + +var updateInProgress = false; + +// Moment prototype object +export function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } +} + +export function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/creation-data.js b/nodejs/node_modules/moment/src/lib/moment/creation-data.js new file mode 100755 index 0000000..7e2d69a --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/creation-data.js @@ -0,0 +1,9 @@ +export function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; +} diff --git a/nodejs/node_modules/moment/src/lib/moment/diff.js b/nodejs/node_modules/moment/src/lib/moment/diff.js new file mode 100755 index 0000000..85254df --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/diff.js @@ -0,0 +1,58 @@ +import absFloor from '../utils/abs-floor'; +import { cloneWithOffset } from '../units/offset'; +import { normalizeUnits } from '../units/aliases'; + +export function diff (input, units, asFloat) { + var that, + zoneDelta, + delta, output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + switch (units) { + case 'year': output = monthDiff(this, that) / 12; break; + case 'month': output = monthDiff(this, that); break; + case 'quarter': output = monthDiff(this, that) / 3; break; + case 'second': output = (this - that) / 1e3; break; // 1000 + case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 + case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 + case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst + case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: output = this - that; + } + + return asFloat ? output : absFloor(output); +} + +function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; +} diff --git a/nodejs/node_modules/moment/src/lib/moment/format.js b/nodejs/node_modules/moment/src/lib/moment/format.js new file mode 100755 index 0000000..9544f51 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/format.js @@ -0,0 +1,62 @@ +import { formatMoment } from '../format/format'; +import { hooks } from '../utils/hooks'; +import isFunction from '../utils/is-function'; + +hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; +hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + +export function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); +} + +export function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + var utc = keepOffset !== true; + var m = utc ? this.clone().utc() : this; + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { + return this.toDate().toISOString(); + } else { + return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); + } + } + return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); +} + +/** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ +export function inspect () { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment'; + var zone = ''; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + var prefix = '[' + func + '("]'; + var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; + + return this.format(prefix + year + datetime + suffix); +} + +export function format (inputString) { + if (!inputString) { + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; + } + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/from.js b/nodejs/node_modules/moment/src/lib/moment/from.js new file mode 100755 index 0000000..4fbd03e --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/from.js @@ -0,0 +1,17 @@ +import { createDuration } from '../duration/create'; +import { createLocal } from '../create/local'; +import { isMoment } from '../moment/constructor'; + +export function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } +} + +export function fromNow (withoutSuffix) { + return this.from(createLocal(), withoutSuffix); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/get-set.js b/nodejs/node_modules/moment/src/lib/moment/get-set.js new file mode 100755 index 0000000..f5035f1 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/get-set.js @@ -0,0 +1,61 @@ +import { normalizeUnits, normalizeObjectUnits } from '../units/aliases'; +import { getPrioritizedUnits } from '../units/priorities'; +import { hooks } from '../utils/hooks'; +import isFunction from '../utils/is-function'; +import { daysInMonth } from '../units/month'; +import { isLeapYear } from '../units/year'; + +export function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; +} + +export function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; +} + +export function set (mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } + else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } +} + +// MOMENTS + +export function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; +} + + +export function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; +} diff --git a/nodejs/node_modules/moment/src/lib/moment/locale.js b/nodejs/node_modules/moment/src/lib/moment/locale.js new file mode 100755 index 0000000..fb46e65 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/locale.js @@ -0,0 +1,34 @@ +import { getLocale } from '../locale/locales'; +import { deprecate } from '../utils/deprecate'; + +// If passed a locale key, it will set the locale for this +// instance. Otherwise, it will return the locale configuration +// variables for this instance. +export function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } +} + +export var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } +); + +export function localeData () { + return this._locale; +} diff --git a/nodejs/node_modules/moment/src/lib/moment/min-max.js b/nodejs/node_modules/moment/src/lib/moment/min-max.js new file mode 100755 index 0000000..d76920a --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/min-max.js @@ -0,0 +1,63 @@ +import { deprecate } from '../utils/deprecate'; +import isArray from '../utils/is-array'; +import { createLocal } from '../create/local'; +import { createInvalid } from '../create/valid'; + +export var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + } +); + +export var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + } +); + +// Pick a moment m from moments so that m[fn](other) is true for all +// other. This relies on the function fn to be transitive. +// +// moments should either be an array of moment objects or an array, whose +// first element is an array of moment objects. +function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; +} + +// TODO: Use [].sort instead? +export function min () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); +} + +export function max () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/moment.js b/nodejs/node_modules/moment/src/lib/moment/moment.js new file mode 100755 index 0000000..12eb5f1 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/moment.js @@ -0,0 +1,28 @@ +import { createLocal } from '../create/local'; +import { createUTC } from '../create/utc'; +import { createInvalid } from '../create/valid'; +import { isMoment } from './constructor'; +import { min, max } from './min-max'; +import { now } from './now'; +import momentPrototype from './prototype'; + +function createUnix (input) { + return createLocal(input * 1000); +} + +function createInZone () { + return createLocal.apply(null, arguments).parseZone(); +} + +export { + now, + min, + max, + isMoment, + createUTC, + createUnix, + createLocal, + createInZone, + createInvalid, + momentPrototype +}; diff --git a/nodejs/node_modules/moment/src/lib/moment/now.js b/nodejs/node_modules/moment/src/lib/moment/now.js new file mode 100755 index 0000000..0f4d0ae --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/now.js @@ -0,0 +1,3 @@ +export var now = function () { + return Date.now ? Date.now() : +(new Date()); +}; diff --git a/nodejs/node_modules/moment/src/lib/moment/prototype.js b/nodejs/node_modules/moment/src/lib/moment/prototype.js new file mode 100755 index 0000000..bd8fff7 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/prototype.js @@ -0,0 +1,150 @@ +import { Moment } from './constructor'; + +var proto = Moment.prototype; + +import { add, subtract } from './add-subtract'; +import { calendar, getCalendarFormat } from './calendar'; +import { clone } from './clone'; +import { isBefore, isBetween, isSame, isAfter, isSameOrAfter, isSameOrBefore } from './compare'; +import { diff } from './diff'; +import { format, toString, toISOString, inspect } from './format'; +import { from, fromNow } from './from'; +import { to, toNow } from './to'; +import { stringGet, stringSet } from './get-set'; +import { locale, localeData, lang } from './locale'; +import { prototypeMin, prototypeMax } from './min-max'; +import { startOf, endOf } from './start-end-of'; +import { valueOf, toDate, toArray, toObject, toJSON, unix } from './to-type'; +import { isValid, parsingFlags, invalidAt } from './valid'; +import { creationData } from './creation-data'; + +proto.add = add; +proto.calendar = calendar; +proto.clone = clone; +proto.diff = diff; +proto.endOf = endOf; +proto.format = format; +proto.from = from; +proto.fromNow = fromNow; +proto.to = to; +proto.toNow = toNow; +proto.get = stringGet; +proto.invalidAt = invalidAt; +proto.isAfter = isAfter; +proto.isBefore = isBefore; +proto.isBetween = isBetween; +proto.isSame = isSame; +proto.isSameOrAfter = isSameOrAfter; +proto.isSameOrBefore = isSameOrBefore; +proto.isValid = isValid; +proto.lang = lang; +proto.locale = locale; +proto.localeData = localeData; +proto.max = prototypeMax; +proto.min = prototypeMin; +proto.parsingFlags = parsingFlags; +proto.set = stringSet; +proto.startOf = startOf; +proto.subtract = subtract; +proto.toArray = toArray; +proto.toObject = toObject; +proto.toDate = toDate; +proto.toISOString = toISOString; +proto.inspect = inspect; +proto.toJSON = toJSON; +proto.toString = toString; +proto.unix = unix; +proto.valueOf = valueOf; +proto.creationData = creationData; + +// Year +import { getSetYear, getIsLeapYear } from '../units/year'; +proto.year = getSetYear; +proto.isLeapYear = getIsLeapYear; + +// Week Year +import { getSetWeekYear, getSetISOWeekYear, getWeeksInYear, getISOWeeksInYear } from '../units/week-year'; +proto.weekYear = getSetWeekYear; +proto.isoWeekYear = getSetISOWeekYear; + +// Quarter +import { getSetQuarter } from '../units/quarter'; +proto.quarter = proto.quarters = getSetQuarter; + +// Month +import { getSetMonth, getDaysInMonth } from '../units/month'; +proto.month = getSetMonth; +proto.daysInMonth = getDaysInMonth; + +// Week +import { getSetWeek, getSetISOWeek } from '../units/week'; +proto.week = proto.weeks = getSetWeek; +proto.isoWeek = proto.isoWeeks = getSetISOWeek; +proto.weeksInYear = getWeeksInYear; +proto.isoWeeksInYear = getISOWeeksInYear; + +// Day +import { getSetDayOfMonth } from '../units/day-of-month'; +import { getSetDayOfWeek, getSetISODayOfWeek, getSetLocaleDayOfWeek } from '../units/day-of-week'; +import { getSetDayOfYear } from '../units/day-of-year'; +proto.date = getSetDayOfMonth; +proto.day = proto.days = getSetDayOfWeek; +proto.weekday = getSetLocaleDayOfWeek; +proto.isoWeekday = getSetISODayOfWeek; +proto.dayOfYear = getSetDayOfYear; + +// Hour +import { getSetHour } from '../units/hour'; +proto.hour = proto.hours = getSetHour; + +// Minute +import { getSetMinute } from '../units/minute'; +proto.minute = proto.minutes = getSetMinute; + +// Second +import { getSetSecond } from '../units/second'; +proto.second = proto.seconds = getSetSecond; + +// Millisecond +import { getSetMillisecond } from '../units/millisecond'; +proto.millisecond = proto.milliseconds = getSetMillisecond; + +// Offset +import { + getSetOffset, + setOffsetToUTC, + setOffsetToLocal, + setOffsetToParsedOffset, + hasAlignedHourOffset, + isDaylightSavingTime, + isDaylightSavingTimeShifted, + getSetZone, + isLocal, + isUtcOffset, + isUtc +} from '../units/offset'; +proto.utcOffset = getSetOffset; +proto.utc = setOffsetToUTC; +proto.local = setOffsetToLocal; +proto.parseZone = setOffsetToParsedOffset; +proto.hasAlignedHourOffset = hasAlignedHourOffset; +proto.isDST = isDaylightSavingTime; +proto.isLocal = isLocal; +proto.isUtcOffset = isUtcOffset; +proto.isUtc = isUtc; +proto.isUTC = isUtc; + +// Timezone +import { getZoneAbbr, getZoneName } from '../units/timezone'; +proto.zoneAbbr = getZoneAbbr; +proto.zoneName = getZoneName; + +// Deprecations +import { deprecate } from '../utils/deprecate'; +proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); +proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); +proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); +proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); +proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); + +export default proto; diff --git a/nodejs/node_modules/moment/src/lib/moment/start-end-of.js b/nodejs/node_modules/moment/src/lib/moment/start-end-of.js new file mode 100755 index 0000000..02f9824 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/start-end-of.js @@ -0,0 +1,59 @@ +import { normalizeUnits } from '../units/aliases'; + +export function startOf (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + case 'date': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } + if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; +} + +export function endOf (units) { + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond') { + return this; + } + + // 'date' is an alias for 'day', so it should be considered as such. + if (units === 'date') { + units = 'day'; + } + + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/to-type.js b/nodejs/node_modules/moment/src/lib/moment/to-type.js new file mode 100755 index 0000000..a990dd2 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/to-type.js @@ -0,0 +1,34 @@ +export function valueOf () { + return this._d.valueOf() - ((this._offset || 0) * 60000); +} + +export function unix () { + return Math.floor(this.valueOf() / 1000); +} + +export function toDate () { + return new Date(this.valueOf()); +} + +export function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; +} + +export function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; +} + +export function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; +} diff --git a/nodejs/node_modules/moment/src/lib/moment/to.js b/nodejs/node_modules/moment/src/lib/moment/to.js new file mode 100755 index 0000000..7ad667e --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/to.js @@ -0,0 +1,17 @@ +import { createDuration } from '../duration/create'; +import { createLocal } from '../create/local'; +import { isMoment } from '../moment/constructor'; + +export function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } +} + +export function toNow (withoutSuffix) { + return this.to(createLocal(), withoutSuffix); +} diff --git a/nodejs/node_modules/moment/src/lib/moment/valid.js b/nodejs/node_modules/moment/src/lib/moment/valid.js new file mode 100755 index 0000000..6c00742 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/moment/valid.js @@ -0,0 +1,15 @@ +import { isValid as _isValid } from '../create/valid'; +import extend from '../utils/extend'; +import getParsingFlags from '../create/parsing-flags'; + +export function isValid () { + return _isValid(this); +} + +export function parsingFlags () { + return extend({}, getParsingFlags(this)); +} + +export function invalidAt () { + return getParsingFlags(this).overflow; +} diff --git a/nodejs/node_modules/moment/src/lib/parse/regex.js b/nodejs/node_modules/moment/src/lib/parse/regex.js new file mode 100755 index 0000000..4b86f34 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/parse/regex.js @@ -0,0 +1,54 @@ +export var match1 = /\d/; // 0 - 9 +export var match2 = /\d\d/; // 00 - 99 +export var match3 = /\d{3}/; // 000 - 999 +export var match4 = /\d{4}/; // 0000 - 9999 +export var match6 = /[+-]?\d{6}/; // -999999 - 999999 +export var match1to2 = /\d\d?/; // 0 - 99 +export var match3to4 = /\d\d\d\d?/; // 999 - 9999 +export var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 +export var match1to3 = /\d{1,3}/; // 0 - 999 +export var match1to4 = /\d{1,4}/; // 0 - 9999 +export var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 + +export var matchUnsigned = /\d+/; // 0 - inf +export var matchSigned = /[+-]?\d+/; // -inf - inf + +export var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z +export var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + +export var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 + +// any word (or two) characters or numbers including two/three word month in arabic. +// includes scottish gaelic two word and hyphenated months +export var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; + + +import hasOwnProp from '../utils/has-own-prop'; +import isFunction from '../utils/is-function'; + +var regexes = {}; + +export function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; +} + +export function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); +} + +// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript +function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); +} + +export function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +} diff --git a/nodejs/node_modules/moment/src/lib/parse/token.js b/nodejs/node_modules/moment/src/lib/parse/token.js new file mode 100755 index 0000000..24b4474 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/parse/token.js @@ -0,0 +1,33 @@ +import hasOwnProp from '../utils/has-own-prop'; +import isNumber from '../utils/is-number'; +import toInt from '../utils/to-int'; + +var tokens = {}; + +export function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } +} + +export function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); +} + +export function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } +} diff --git a/nodejs/node_modules/moment/src/lib/units/aliases.js b/nodejs/node_modules/moment/src/lib/units/aliases.js new file mode 100755 index 0000000..0d8b88a --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/aliases.js @@ -0,0 +1,30 @@ +import hasOwnProp from '../utils/has-own-prop'; + +var aliases = {}; + +export function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; +} + +export function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; +} + +export function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; +} + diff --git a/nodejs/node_modules/moment/src/lib/units/constants.js b/nodejs/node_modules/moment/src/lib/units/constants.js new file mode 100755 index 0000000..70bf1b2 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/constants.js @@ -0,0 +1,9 @@ +export var YEAR = 0; +export var MONTH = 1; +export var DATE = 2; +export var HOUR = 3; +export var MINUTE = 4; +export var SECOND = 5; +export var MILLISECOND = 6; +export var WEEK = 7; +export var WEEKDAY = 8; diff --git a/nodejs/node_modules/moment/src/lib/units/day-of-month.js b/nodejs/node_modules/moment/src/lib/units/day-of-month.js new file mode 100755 index 0000000..cbd1e40 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/day-of-month.js @@ -0,0 +1,39 @@ +import { makeGetSet } from '../moment/get-set'; +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match2 } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { DATE } from './constants'; +import toInt from '../utils/to-int'; + +// FORMATTING + +addFormatToken('D', ['DD', 2], 'Do', 'date'); + +// ALIASES + +addUnitAlias('date', 'D'); + +// PRIORITY +addUnitPriority('date', 9); + +// PARSING + +addRegexToken('D', match1to2); +addRegexToken('DD', match1to2, match2); +addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? + (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : + locale._dayOfMonthOrdinalParseLenient; +}); + +addParseToken(['D', 'DD'], DATE); +addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0]); +}); + +// MOMENTS + +export var getSetDayOfMonth = makeGetSet('Date', true); diff --git a/nodejs/node_modules/moment/src/lib/units/day-of-week.js b/nodejs/node_modules/moment/src/lib/units/day-of-week.js new file mode 100755 index 0000000..438160b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/day-of-week.js @@ -0,0 +1,364 @@ +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, matchWord, regexEscape } from '../parse/regex'; +import { addWeekParseToken } from '../parse/token'; +import toInt from '../utils/to-int'; +import isArray from '../utils/is-array'; +import indexOf from '../utils/index-of'; +import hasOwnProp from '../utils/has-own-prop'; +import { createUTC } from '../create/utc'; +import getParsingFlags from '../create/parsing-flags'; + +// FORMATTING + +addFormatToken('d', 0, 'do', 'day'); + +addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); +}); + +addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); +}); + +addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); +}); + +addFormatToken('e', 0, 0, 'weekday'); +addFormatToken('E', 0, 0, 'isoWeekday'); + +// ALIASES + +addUnitAlias('day', 'd'); +addUnitAlias('weekday', 'e'); +addUnitAlias('isoWeekday', 'E'); + +// PRIORITY +addUnitPriority('day', 11); +addUnitPriority('weekday', 11); +addUnitPriority('isoWeekday', 11); + +// PARSING + +addRegexToken('d', match1to2); +addRegexToken('e', match1to2); +addRegexToken('E', match1to2); +addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); +}); +addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); +}); +addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); +}); + +addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } +}); + +addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); +}); + +// HELPERS + +function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; +} + +function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + return isNaN(input) ? null : input; +} + +// LOCALES + +export var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); +export function localeWeekdays (m, format) { + if (!m) { + return isArray(this._weekdays) ? this._weekdays : + this._weekdays['standalone']; + } + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; +} + +export var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); +export function localeWeekdaysShort (m) { + return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; +} + +export var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); +export function localeWeekdaysMin (m) { + return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; +} + +function handleStrictParse(weekdayName, format, strict) { + var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } +} + +export function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; + + if (this._weekdaysParseExact) { + return handleStrictParse.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } +} + +// MOMENTS + +export function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } +} + +export function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); +} + +export function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } +} + +var defaultWeekdaysRegex = matchWord; +export function weekdaysRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + return this._weekdaysStrictRegex && isStrict ? + this._weekdaysStrictRegex : this._weekdaysRegex; + } +} + +var defaultWeekdaysShortRegex = matchWord; +export function weekdaysShortRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + return this._weekdaysShortStrictRegex && isStrict ? + this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } +} + +var defaultWeekdaysMinRegex = matchWord; +export function weekdaysMinRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + return this._weekdaysMinStrictRegex && isStrict ? + this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } +} + + +function computeWeekdaysParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], + i, mom, minp, shortp, longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); +} diff --git a/nodejs/node_modules/moment/src/lib/units/day-of-year.js b/nodejs/node_modules/moment/src/lib/units/day-of-year.js new file mode 100755 index 0000000..6fe931c --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/day-of-year.js @@ -0,0 +1,36 @@ +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match3, match1to3 } from '../parse/regex'; +import { daysInYear } from './year'; +import { createUTCDate } from '../create/date-from-array'; +import { addParseToken } from '../parse/token'; +import toInt from '../utils/to-int'; + +// FORMATTING + +addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + +// ALIASES + +addUnitAlias('dayOfYear', 'DDD'); + +// PRIORITY +addUnitPriority('dayOfYear', 4); + +// PARSING + +addRegexToken('DDD', match1to3); +addRegexToken('DDDD', match3); +addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); +}); + +// HELPERS + +// MOMENTS + +export function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); +} diff --git a/nodejs/node_modules/moment/src/lib/units/hour.js b/nodejs/node_modules/moment/src/lib/units/hour.js new file mode 100755 index 0000000..d717a79 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/hour.js @@ -0,0 +1,144 @@ +import { makeGetSet } from '../moment/get-set'; +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match2, match3to4, match5to6 } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { HOUR, MINUTE, SECOND } from './constants'; +import toInt from '../utils/to-int'; +import zeroFill from '../utils/zero-fill'; +import getParsingFlags from '../create/parsing-flags'; + +// FORMATTING + +function hFormat() { + return this.hours() % 12 || 12; +} + +function kFormat() { + return this.hours() || 24; +} + +addFormatToken('H', ['HH', 2], 0, 'hour'); +addFormatToken('h', ['hh', 2], 0, hFormat); +addFormatToken('k', ['kk', 2], 0, kFormat); + +addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); +}); + +addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); +}); + +addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); +}); + +addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); +}); + +function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); +} + +meridiem('a', true); +meridiem('A', false); + +// ALIASES + +addUnitAlias('hour', 'h'); + +// PRIORITY +addUnitPriority('hour', 13); + +// PARSING + +function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; +} + +addRegexToken('a', matchMeridiem); +addRegexToken('A', matchMeridiem); +addRegexToken('H', match1to2); +addRegexToken('h', match1to2); +addRegexToken('k', match1to2); +addRegexToken('HH', match1to2, match2); +addRegexToken('hh', match1to2, match2); +addRegexToken('kk', match1to2, match2); + +addRegexToken('hmm', match3to4); +addRegexToken('hmmss', match5to6); +addRegexToken('Hmm', match3to4); +addRegexToken('Hmmss', match5to6); + +addParseToken(['H', 'HH'], HOUR); +addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; +}); +addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; +}); +addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; +}); +addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; +}); +addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; +}); +addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); +}); +addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); +}); + +// LOCALES + +export function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); +} + +export var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; +export function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } +} + + +// MOMENTS + +// Setting the hour should keep the time, because the user explicitly +// specified which hour they want. So trying to maintain the same hour (in +// a new timezone) makes sense. Adding/subtracting hours does not follow +// this rule. +export var getSetHour = makeGetSet('Hours', true); diff --git a/nodejs/node_modules/moment/src/lib/units/millisecond.js b/nodejs/node_modules/moment/src/lib/units/millisecond.js new file mode 100755 index 0000000..27c9512 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/millisecond.js @@ -0,0 +1,69 @@ +import { makeGetSet } from '../moment/get-set'; +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1, match2, match3, match1to3, matchUnsigned } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { MILLISECOND } from './constants'; +import toInt from '../utils/to-int'; + +// FORMATTING + +addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); +}); + +addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); +}); + +addFormatToken(0, ['SSS', 3], 0, 'millisecond'); +addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; +}); +addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; +}); +addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; +}); +addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; +}); +addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; +}); +addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; +}); + + +// ALIASES + +addUnitAlias('millisecond', 'ms'); + +// PRIORITY + +addUnitPriority('millisecond', 16); + +// PARSING + +addRegexToken('S', match1to3, match1); +addRegexToken('SS', match1to3, match2); +addRegexToken('SSS', match1to3, match3); + +var token; +for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); +} + +function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); +} + +for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); +} +// MOMENTS + +export var getSetMillisecond = makeGetSet('Milliseconds', false); diff --git a/nodejs/node_modules/moment/src/lib/units/minute.js b/nodejs/node_modules/moment/src/lib/units/minute.js new file mode 100755 index 0000000..9f76032 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/minute.js @@ -0,0 +1,29 @@ +import { makeGetSet } from '../moment/get-set'; +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match2 } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { MINUTE } from './constants'; + +// FORMATTING + +addFormatToken('m', ['mm', 2], 0, 'minute'); + +// ALIASES + +addUnitAlias('minute', 'm'); + +// PRIORITY + +addUnitPriority('minute', 14); + +// PARSING + +addRegexToken('m', match1to2); +addRegexToken('mm', match1to2, match2); +addParseToken(['m', 'mm'], MINUTE); + +// MOMENTS + +export var getSetMinute = makeGetSet('Minutes', false); diff --git a/nodejs/node_modules/moment/src/lib/units/month.js b/nodejs/node_modules/moment/src/lib/units/month.js new file mode 100755 index 0000000..f504ed3 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/month.js @@ -0,0 +1,290 @@ +import { get } from '../moment/get-set'; +import hasOwnProp from '../utils/has-own-prop'; +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match2, matchWord, regexEscape } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { hooks } from '../utils/hooks'; +import { MONTH } from './constants'; +import toInt from '../utils/to-int'; +import isArray from '../utils/is-array'; +import isNumber from '../utils/is-number'; +import mod from '../utils/mod'; +import indexOf from '../utils/index-of'; +import { createUTC } from '../create/utc'; +import getParsingFlags from '../create/parsing-flags'; +import { isLeapYear } from '../units/year'; + +export function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); +} + +// FORMATTING + +addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; +}); + +addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); +}); + +addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); +}); + +// ALIASES + +addUnitAlias('month', 'M'); + +// PRIORITY + +addUnitPriority('month', 8); + +// PARSING + +addRegexToken('M', match1to2); +addRegexToken('MM', match1to2, match2); +addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); +}); +addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); +}); + +addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; +}); + +addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } +}); + +// LOCALES + +var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; +export var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); +export function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } + return isArray(this._months) ? this._months[m.month()] : + this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; +} + +export var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); +export function localeMonthsShort (m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : + this._monthsShort['standalone']; + } + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; +} + +function handleStrictParse(monthName, format, strict) { + var i, ii, mom, llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } +} + +export function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; + + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } +} + +// MOMENTS + +export function setMonth (mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (!isNumber(value)) { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; +} + +export function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } +} + +export function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); +} + +var defaultMonthsShortRegex = matchWord; +export function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } +} + +var defaultMonthsRegex = matchWord; +export function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } +} + +function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); +} diff --git a/nodejs/node_modules/moment/src/lib/units/offset.js b/nodejs/node_modules/moment/src/lib/units/offset.js new file mode 100755 index 0000000..752358f --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/offset.js @@ -0,0 +1,235 @@ +import zeroFill from '../utils/zero-fill'; +import { createDuration } from '../duration/create'; +import { addSubtract } from '../moment/add-subtract'; +import { isMoment, copyConfig } from '../moment/constructor'; +import { addFormatToken } from '../format/format'; +import { addRegexToken, matchOffset, matchShortOffset } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { createLocal } from '../create/local'; +import { prepareConfig } from '../create/from-anything'; +import { createUTC } from '../create/utc'; +import isDate from '../utils/is-date'; +import toInt from '../utils/to-int'; +import isUndefined from '../utils/is-undefined'; +import compareArrays from '../utils/compare-arrays'; +import { hooks } from '../utils/hooks'; + +// FORMATTING + +function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); +} + +offset('Z', ':'); +offset('ZZ', ''); + +// PARSING + +addRegexToken('Z', matchShortOffset); +addRegexToken('ZZ', matchShortOffset); +addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); +}); + +// HELPERS + +// timezone chunker +// '+10:00' > ['10', '00'] +// '-1530' > ['-15', '30'] +var chunkOffset = /([\+\-]|\d\d)/gi; + +function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher); + + if (matches === null) { + return null; + } + + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + + return minutes === 0 ? + 0 : + parts[0] === '+' ? minutes : -minutes; +} + +// Return a moment from input, that is local/utc/zone equivalent to model. +export function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); + // Use low-level api, because this fn is low-level api. + res._d.setTime(res._d.valueOf() + diff); + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } +} + +function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; +} + +// HOOKS + +// This function will be called whenever a moment is mutated. +// It is intended to keep the offset in sync with the timezone. +hooks.updateOffset = function () {}; + +// MOMENTS + +// keepLocalTime = true means only change the timezone, without +// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> +// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset +// +0200, so we adjust the time as needed, to be valid. +// +// Keeping the time actually adds/subtracts (one hour) +// from the actual represented time. That is why we call updateOffset +// a second time. In case it wants us to change the offset again +// _changeInProgress == true case, then we have to adjust, because +// there is no such time in the given timezone. +export function getSetOffset (input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract(this, createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } +} + +export function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } +} + +export function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); +} + +export function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; +} + +export function setOffsetToParsedOffset () { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } + else { + this.utcOffset(0, true); + } + } + return this; +} + +export function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } + input = input ? createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; +} + +export function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); +} + +export function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; +} + +export function isLocal () { + return this.isValid() ? !this._isUTC : false; +} + +export function isUtcOffset () { + return this.isValid() ? this._isUTC : false; +} + +export function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; +} diff --git a/nodejs/node_modules/moment/src/lib/units/priorities.js b/nodejs/node_modules/moment/src/lib/units/priorities.js new file mode 100755 index 0000000..699017c --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/priorities.js @@ -0,0 +1,16 @@ +var priorities = {}; + +export function addUnitPriority(unit, priority) { + priorities[unit] = priority; +} + +export function getPrioritizedUnits(unitsObj) { + var units = []; + for (var u in unitsObj) { + units.push({unit: u, priority: priorities[u]}); + } + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; +} diff --git a/nodejs/node_modules/moment/src/lib/units/quarter.js b/nodejs/node_modules/moment/src/lib/units/quarter.js new file mode 100755 index 0000000..a6d409a --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/quarter.js @@ -0,0 +1,32 @@ +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1 } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { MONTH } from './constants'; +import toInt from '../utils/to-int'; + +// FORMATTING + +addFormatToken('Q', 0, 'Qo', 'quarter'); + +// ALIASES + +addUnitAlias('quarter', 'Q'); + +// PRIORITY + +addUnitPriority('quarter', 7); + +// PARSING + +addRegexToken('Q', match1); +addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; +}); + +// MOMENTS + +export function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); +} diff --git a/nodejs/node_modules/moment/src/lib/units/second.js b/nodejs/node_modules/moment/src/lib/units/second.js new file mode 100755 index 0000000..1793711 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/second.js @@ -0,0 +1,29 @@ +import { makeGetSet } from '../moment/get-set'; +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match2 } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { SECOND } from './constants'; + +// FORMATTING + +addFormatToken('s', ['ss', 2], 0, 'second'); + +// ALIASES + +addUnitAlias('second', 's'); + +// PRIORITY + +addUnitPriority('second', 15); + +// PARSING + +addRegexToken('s', match1to2); +addRegexToken('ss', match1to2, match2); +addParseToken(['s', 'ss'], SECOND); + +// MOMENTS + +export var getSetSecond = makeGetSet('Seconds', false); diff --git a/nodejs/node_modules/moment/src/lib/units/timestamp.js b/nodejs/node_modules/moment/src/lib/units/timestamp.js new file mode 100755 index 0000000..a49e1e4 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/timestamp.js @@ -0,0 +1,20 @@ +import { addFormatToken } from '../format/format'; +import { addRegexToken, matchTimestamp, matchSigned } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import toInt from '../utils/to-int'; + +// FORMATTING + +addFormatToken('X', 0, 0, 'unix'); +addFormatToken('x', 0, 0, 'valueOf'); + +// PARSING + +addRegexToken('x', matchSigned); +addRegexToken('X', matchTimestamp); +addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); +}); +addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); +}); diff --git a/nodejs/node_modules/moment/src/lib/units/timezone.js b/nodejs/node_modules/moment/src/lib/units/timezone.js new file mode 100755 index 0000000..20c81cd --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/timezone.js @@ -0,0 +1,16 @@ +import { addFormatToken } from '../format/format'; + +// FORMATTING + +addFormatToken('z', 0, 0, 'zoneAbbr'); +addFormatToken('zz', 0, 0, 'zoneName'); + +// MOMENTS + +export function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; +} + +export function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; +} diff --git a/nodejs/node_modules/moment/src/lib/units/units.js b/nodejs/node_modules/moment/src/lib/units/units.js new file mode 100755 index 0000000..6f45f1c --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/units.js @@ -0,0 +1,20 @@ +// Side effect imports +import './day-of-month'; +import './day-of-week'; +import './day-of-year'; +import './hour'; +import './millisecond'; +import './minute'; +import './month'; +import './offset'; +import './quarter'; +import './second'; +import './timestamp'; +import './timezone'; +import './week-year'; +import './week'; +import './year'; + +import { normalizeUnits } from './aliases'; + +export { normalizeUnits }; diff --git a/nodejs/node_modules/moment/src/lib/units/week-calendar-utils.js b/nodejs/node_modules/moment/src/lib/units/week-calendar-utils.js new file mode 100755 index 0000000..5be8a5f --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/week-calendar-utils.js @@ -0,0 +1,65 @@ +import { daysInYear } from './year'; +import { createLocal } from '../create/local'; +import { createUTCDate } from '../create/date-from-array'; + +// start-of-first-week - start-of-year +function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; +} + +// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday +export function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; +} + +export function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; +} + +export function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; +} diff --git a/nodejs/node_modules/moment/src/lib/units/week-year.js b/nodejs/node_modules/moment/src/lib/units/week-year.js new file mode 100755 index 0000000..7fa5425 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/week-year.js @@ -0,0 +1,107 @@ +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex'; +import { addWeekParseToken } from '../parse/token'; +import { weekOfYear, weeksInYear, dayOfYearFromWeeks } from './week-calendar-utils'; +import toInt from '../utils/to-int'; +import { hooks } from '../utils/hooks'; +import { createLocal } from '../create/local'; +import { createUTCDate } from '../create/date-from-array'; + +// FORMATTING + +addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; +}); + +addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; +}); + +function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); +} + +addWeekYearFormatToken('gggg', 'weekYear'); +addWeekYearFormatToken('ggggg', 'weekYear'); +addWeekYearFormatToken('GGGG', 'isoWeekYear'); +addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + +// ALIASES + +addUnitAlias('weekYear', 'gg'); +addUnitAlias('isoWeekYear', 'GG'); + +// PRIORITY + +addUnitPriority('weekYear', 1); +addUnitPriority('isoWeekYear', 1); + + +// PARSING + +addRegexToken('G', matchSigned); +addRegexToken('g', matchSigned); +addRegexToken('GG', match1to2, match2); +addRegexToken('gg', match1to2, match2); +addRegexToken('GGGG', match1to4, match4); +addRegexToken('gggg', match1to4, match4); +addRegexToken('GGGGG', match1to6, match6); +addRegexToken('ggggg', match1to6, match6); + +addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); +}); + +addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); +}); + +// MOMENTS + +export function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); +} + +export function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); +} + +export function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); +} + +export function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); +} + +function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } +} + +function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; +} diff --git a/nodejs/node_modules/moment/src/lib/units/week.js b/nodejs/node_modules/moment/src/lib/units/week.js new file mode 100755 index 0000000..da64ffe --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/week.js @@ -0,0 +1,67 @@ +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match2 } from '../parse/regex'; +import { addWeekParseToken } from '../parse/token'; +import toInt from '../utils/to-int'; +import { createLocal } from '../create/local'; +import { weekOfYear } from './week-calendar-utils'; + +// FORMATTING + +addFormatToken('w', ['ww', 2], 'wo', 'week'); +addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + +// ALIASES + +addUnitAlias('week', 'w'); +addUnitAlias('isoWeek', 'W'); + +// PRIORITIES + +addUnitPriority('week', 5); +addUnitPriority('isoWeek', 5); + +// PARSING + +addRegexToken('w', match1to2); +addRegexToken('ww', match1to2, match2); +addRegexToken('W', match1to2); +addRegexToken('WW', match1to2, match2); + +addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); +}); + +// HELPERS + +// LOCALES + +export function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; +} + +export var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. +}; + +export function localeFirstDayOfWeek () { + return this._week.dow; +} + +export function localeFirstDayOfYear () { + return this._week.doy; +} + +// MOMENTS + +export function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); +} + +export function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); +} diff --git a/nodejs/node_modules/moment/src/lib/units/year.js b/nodejs/node_modules/moment/src/lib/units/year.js new file mode 100755 index 0000000..8f3f94c --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/units/year.js @@ -0,0 +1,75 @@ +import { makeGetSet } from '../moment/get-set'; +import { addFormatToken } from '../format/format'; +import { addUnitAlias } from './aliases'; +import { addUnitPriority } from './priorities'; +import { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex'; +import { addParseToken } from '../parse/token'; +import { hooks } from '../utils/hooks'; +import { YEAR } from './constants'; +import toInt from '../utils/to-int'; + +// FORMATTING + +addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; +}); + +addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; +}); + +addFormatToken(0, ['YYYY', 4], 0, 'year'); +addFormatToken(0, ['YYYYY', 5], 0, 'year'); +addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + +// ALIASES + +addUnitAlias('year', 'y'); + +// PRIORITIES + +addUnitPriority('year', 1); + +// PARSING + +addRegexToken('Y', matchSigned); +addRegexToken('YY', match1to2, match2); +addRegexToken('YYYY', match1to4, match4); +addRegexToken('YYYYY', match1to6, match6); +addRegexToken('YYYYYY', match1to6, match6); + +addParseToken(['YYYYY', 'YYYYYY'], YEAR); +addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); +}); +addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); +}); +addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); +}); + +// HELPERS + +export function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; +} + +export function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; +} + +// HOOKS + +hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); +}; + +// MOMENTS + +export var getSetYear = makeGetSet('FullYear', true); + +export function getIsLeapYear () { + return isLeapYear(this.year()); +} diff --git a/nodejs/node_modules/moment/src/lib/utils/abs-ceil.js b/nodejs/node_modules/moment/src/lib/utils/abs-ceil.js new file mode 100755 index 0000000..7cf9329 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/abs-ceil.js @@ -0,0 +1,7 @@ +export default function absCeil (number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } +} diff --git a/nodejs/node_modules/moment/src/lib/utils/abs-floor.js b/nodejs/node_modules/moment/src/lib/utils/abs-floor.js new file mode 100755 index 0000000..401c7f0 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/abs-floor.js @@ -0,0 +1,8 @@ +export default function absFloor (number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } +} diff --git a/nodejs/node_modules/moment/src/lib/utils/abs-round.js b/nodejs/node_modules/moment/src/lib/utils/abs-round.js new file mode 100755 index 0000000..98f54bc --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/abs-round.js @@ -0,0 +1,7 @@ +export default function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } +} diff --git a/nodejs/node_modules/moment/src/lib/utils/compare-arrays.js b/nodejs/node_modules/moment/src/lib/utils/compare-arrays.js new file mode 100755 index 0000000..2eb274b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/compare-arrays.js @@ -0,0 +1,16 @@ +import toInt from './to-int'; + +// compare two arrays, return the number of differences +export default function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/defaults.js b/nodejs/node_modules/moment/src/lib/utils/defaults.js new file mode 100755 index 0000000..45c5e87 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/defaults.js @@ -0,0 +1,10 @@ +// Pick the first defined of two or three arguments. +export default function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/deprecate.js b/nodejs/node_modules/moment/src/lib/utils/deprecate.js new file mode 100755 index 0000000..8b4c87a --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/deprecate.js @@ -0,0 +1,55 @@ +import extend from './extend'; +import { hooks } from './hooks'; +import isUndefined from './is-undefined'; + +function warn(msg) { + if (hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } +} + +export function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + if (firstTime) { + var args = []; + var arg; + for (var i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); +} + +var deprecations = {}; + +export function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } +} + +hooks.suppressDeprecationWarnings = false; +hooks.deprecationHandler = null; diff --git a/nodejs/node_modules/moment/src/lib/utils/extend.js b/nodejs/node_modules/moment/src/lib/utils/extend.js new file mode 100755 index 0000000..ba74a0b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/extend.js @@ -0,0 +1,19 @@ +import hasOwnProp from './has-own-prop'; + +export default function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/has-own-prop.js b/nodejs/node_modules/moment/src/lib/utils/has-own-prop.js new file mode 100755 index 0000000..4d2403c --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/has-own-prop.js @@ -0,0 +1,3 @@ +export default function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); +} diff --git a/nodejs/node_modules/moment/src/lib/utils/hooks.js b/nodejs/node_modules/moment/src/lib/utils/hooks.js new file mode 100755 index 0000000..02a5bd3 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/hooks.js @@ -0,0 +1,13 @@ +export { hooks, setHookCallback }; + +var hookCallback; + +function hooks () { + return hookCallback.apply(null, arguments); +} + +// This is done to register the method called with moment() +// without creating circular dependencies. +function setHookCallback (callback) { + hookCallback = callback; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/index-of.js b/nodejs/node_modules/moment/src/lib/utils/index-of.js new file mode 100755 index 0000000..92298cf --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/index-of.js @@ -0,0 +1,18 @@ +var indexOf; + +if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; +} else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; +} + +export { indexOf as default }; diff --git a/nodejs/node_modules/moment/src/lib/utils/is-array.js b/nodejs/node_modules/moment/src/lib/utils/is-array.js new file mode 100755 index 0000000..2d0e0f3 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/is-array.js @@ -0,0 +1,3 @@ +export default function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/is-date.js b/nodejs/node_modules/moment/src/lib/utils/is-date.js new file mode 100755 index 0000000..69c4d0e --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/is-date.js @@ -0,0 +1,3 @@ +export default function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/is-function.js b/nodejs/node_modules/moment/src/lib/utils/is-function.js new file mode 100755 index 0000000..12304b1 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/is-function.js @@ -0,0 +1,3 @@ +export default function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/is-number.js b/nodejs/node_modules/moment/src/lib/utils/is-number.js new file mode 100755 index 0000000..74d6137 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/is-number.js @@ -0,0 +1,3 @@ +export default function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/is-object-empty.js b/nodejs/node_modules/moment/src/lib/utils/is-object-empty.js new file mode 100755 index 0000000..695c3d2 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/is-object-empty.js @@ -0,0 +1,13 @@ +export default function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return (Object.getOwnPropertyNames(obj).length === 0); + } else { + var k; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + return true; + } +} diff --git a/nodejs/node_modules/moment/src/lib/utils/is-object.js b/nodejs/node_modules/moment/src/lib/utils/is-object.js new file mode 100755 index 0000000..1113538 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/is-object.js @@ -0,0 +1,5 @@ +export default function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/is-undefined.js b/nodejs/node_modules/moment/src/lib/utils/is-undefined.js new file mode 100755 index 0000000..de57a8b --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/is-undefined.js @@ -0,0 +1,3 @@ +export default function isUndefined(input) { + return input === void 0; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/keys.js b/nodejs/node_modules/moment/src/lib/utils/keys.js new file mode 100755 index 0000000..2da4e32 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/keys.js @@ -0,0 +1,19 @@ +import hasOwnProp from './has-own-prop'; + +var keys; + +if (Object.keys) { + keys = Object.keys; +} else { + keys = function (obj) { + var i, res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; +} + +export { keys as default }; diff --git a/nodejs/node_modules/moment/src/lib/utils/map.js b/nodejs/node_modules/moment/src/lib/utils/map.js new file mode 100755 index 0000000..1cbc563 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/map.js @@ -0,0 +1,7 @@ +export default function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/mod.js b/nodejs/node_modules/moment/src/lib/utils/mod.js new file mode 100755 index 0000000..8046cda --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/mod.js @@ -0,0 +1,3 @@ +export default function mod(n, x) { + return ((n % x) + x) % x; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/some.js b/nodejs/node_modules/moment/src/lib/utils/some.js new file mode 100755 index 0000000..1bd3186 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/some.js @@ -0,0 +1,19 @@ +var some; +if (Array.prototype.some) { + some = Array.prototype.some; +} else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; +} + +export { some as default }; diff --git a/nodejs/node_modules/moment/src/lib/utils/to-int.js b/nodejs/node_modules/moment/src/lib/utils/to-int.js new file mode 100755 index 0000000..fb48941 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/to-int.js @@ -0,0 +1,12 @@ +import absFloor from './abs-floor'; + +export default function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; +} diff --git a/nodejs/node_modules/moment/src/lib/utils/zero-fill.js b/nodejs/node_modules/moment/src/lib/utils/zero-fill.js new file mode 100755 index 0000000..7009ec9 --- /dev/null +++ b/nodejs/node_modules/moment/src/lib/utils/zero-fill.js @@ -0,0 +1,7 @@ +export default function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; +} diff --git a/nodejs/node_modules/moment/src/locale/af.js b/nodejs/node_modules/moment/src/locale/af.js new file mode 100755 index 0000000..7af0324 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/af.js @@ -0,0 +1,64 @@ +//! moment.js locale configuration +//! locale : Afrikaans [af] +//! author : Werner Mollentze : https://github.com/wernerm + +import moment from '../moment'; + +export default moment.defineLocale('af', { + months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), + weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), + weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), + meridiemParse: /vm|nm/i, + isPM : function (input) { + return /^nm$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'vm' : 'VM'; + } else { + return isLower ? 'nm' : 'NM'; + } + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Vandag om] LT', + nextDay : '[Môre om] LT', + nextWeek : 'dddd [om] LT', + lastDay : '[Gister om] LT', + lastWeek : '[Laas] dddd [om] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'oor %s', + past : '%s gelede', + s : '\'n paar sekondes', + ss : '%d sekondes', + m : '\'n minuut', + mm : '%d minute', + h : '\'n uur', + hh : '%d ure', + d : '\'n dag', + dd : '%d dae', + M : '\'n maand', + MM : '%d maande', + y : '\'n jaar', + yy : '%d jaar' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter + }, + week : { + dow : 1, // Maandag is die eerste dag van die week. + doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/ar-dz.js b/nodejs/node_modules/moment/src/locale/ar-dz.js new file mode 100755 index 0000000..f01a30d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ar-dz.js @@ -0,0 +1,51 @@ +//! moment.js locale configuration +//! locale : Arabic (Algeria) [ar-dz] +//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme + +import moment from '../moment'; + +export default moment.defineLocale('ar-dz', { + months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 4 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ar-kw.js b/nodejs/node_modules/moment/src/locale/ar-kw.js new file mode 100755 index 0000000..684abb7 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ar-kw.js @@ -0,0 +1,50 @@ +//! moment.js locale configuration +//! locale : Arabic (Kuwait) [ar-kw] +//! author : Nusret Parlak: https://github.com/nusretparlak + +import moment from '../moment'; + +export default moment.defineLocale('ar-kw', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/ar-ly.js b/nodejs/node_modules/moment/src/locale/ar-ly.js new file mode 100755 index 0000000..b6b5002 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ar-ly.js @@ -0,0 +1,113 @@ +//! moment.js locale configuration +//! locale : Arabic (Lybia) [ar-ly] +//! author : Ali Hmer: https://github.com/kikoanis + +import moment from '../moment'; + +var symbolMap = { + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '0': '0' +}, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; +}, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] +}, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; +}, months = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر' +]; + +export default moment.defineLocale('ar-ly', { + months : months, + monthsShort : months, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'بعد %s', + past : 'منذ %s', + s : pluralize('s'), + ss : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/ar-ma.js b/nodejs/node_modules/moment/src/locale/ar-ma.js new file mode 100755 index 0000000..b1af907 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ar-ma.js @@ -0,0 +1,52 @@ +//! moment.js locale configuration +//! locale : Arabic (Morocco) [ar-ma] +//! author : ElFadili Yassine : https://github.com/ElFadiliY +//! author : Abdel Said : https://github.com/abdelsaid + +import moment from '../moment'; + +export default moment.defineLocale('ar-ma', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ar-sa.js b/nodejs/node_modules/moment/src/locale/ar-sa.js new file mode 100755 index 0000000..65ba6a1 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ar-sa.js @@ -0,0 +1,96 @@ +//! moment.js locale configuration +//! locale : Arabic (Saudi Arabia) [ar-sa] +//! author : Suhail Alkowaileet : https://github.com/xsoh + +import moment from '../moment'; + +var symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' +}, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' +}; + +export default moment.defineLocale('ar-sa', { + months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ar-tn.js b/nodejs/node_modules/moment/src/locale/ar-tn.js new file mode 100755 index 0000000..952f3bf --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ar-tn.js @@ -0,0 +1,51 @@ +//! moment.js locale configuration +//! locale : Arabic (Tunisia) [ar-tn] +//! author : Nader Toukabri : https://github.com/naderio + +import moment from '../moment'; + +export default moment.defineLocale('ar-tn', { + months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + ss : '%d ثانية', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات' + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ar.js b/nodejs/node_modules/moment/src/locale/ar.js new file mode 100755 index 0000000..92f368d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ar.js @@ -0,0 +1,128 @@ +//! moment.js locale configuration +//! locale : Arabic [ar] +//! author : Abdel Said: https://github.com/abdelsaid +//! author : Ahmed Elkhatib +//! author : forabi https://github.com/forabi + +import moment from '../moment'; + +var symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' +}, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' +}, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; +}, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] +}, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; +}, months = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر' +]; + +export default moment.defineLocale('ar', { + months : months, + monthsShort : months, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'بعد %s', + past : 'منذ %s', + s : pluralize('s'), + ss : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/az.js b/nodejs/node_modules/moment/src/locale/az.js new file mode 100755 index 0000000..4fea428 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/az.js @@ -0,0 +1,97 @@ +//! moment.js locale configuration +//! locale : Azerbaijani [az] +//! author : topchiyev : https://github.com/topchiyev + +import moment from '../moment'; + +var suffixes = { + 1: '-inci', + 5: '-inci', + 8: '-inci', + 70: '-inci', + 80: '-inci', + 2: '-nci', + 7: '-nci', + 20: '-nci', + 50: '-nci', + 3: '-üncü', + 4: '-üncü', + 100: '-üncü', + 6: '-ncı', + 9: '-uncu', + 10: '-uncu', + 30: '-uncu', + 60: '-ıncı', + 90: '-ıncı' +}; + +export default moment.defineLocale('az', { + months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), + monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), + weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), + weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), + weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[sabah saat] LT', + nextWeek : '[gələn həftə] dddd [saat] LT', + lastDay : '[dünən] LT', + lastWeek : '[keçən həftə] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s sonra', + past : '%s əvvəl', + s : 'birneçə saniyə', + ss : '%d saniyə', + m : 'bir dəqiqə', + mm : '%d dəqiqə', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir il', + yy : '%d il' + }, + meridiemParse: /gecə|səhər|gündüz|axşam/, + isPM : function (input) { + return /^(gündüz|axşam)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'gecə'; + } else if (hour < 12) { + return 'səhər'; + } else if (hour < 17) { + return 'gündüz'; + } else { + return 'axşam'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, + ordinal : function (number) { + if (number === 0) { // special case for zero + return number + '-ıncı'; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/be.js b/nodejs/node_modules/moment/src/locale/be.js new file mode 100755 index 0000000..e106f24 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/be.js @@ -0,0 +1,126 @@ +//! moment.js locale configuration +//! locale : Belarusian [be] +//! author : Dmitry Demidov : https://github.com/demidov91 +//! author: Praleska: http://praleska.pro/ +//! Author : Menelion Elensúle : https://github.com/Oire + +import moment from '../moment'; + +function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); +} +function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', + 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', + 'dd': 'дзень_дні_дзён', + 'MM': 'месяц_месяцы_месяцаў', + 'yy': 'год_гады_гадоў' + }; + if (key === 'm') { + return withoutSuffix ? 'хвіліна' : 'хвіліну'; + } + else if (key === 'h') { + return withoutSuffix ? 'гадзіна' : 'гадзіну'; + } + else { + return number + ' ' + plural(format[key], +number); + } +} + +export default moment.defineLocale('be', { + months : { + format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'), + standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_') + }, + monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), + weekdays : { + format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), + standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), + isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/ + }, + weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., HH:mm', + LLLL : 'dddd, D MMMM YYYY г., HH:mm' + }, + calendar : { + sameDay: '[Сёння ў] LT', + nextDay: '[Заўтра ў] LT', + lastDay: '[Учора ў] LT', + nextWeek: function () { + return '[У] dddd [ў] LT'; + }, + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return '[У мінулую] dddd [ў] LT'; + case 1: + case 2: + case 4: + return '[У мінулы] dddd [ў] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'праз %s', + past : '%s таму', + s : 'некалькі секунд', + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : relativeTimeWithPlural, + hh : relativeTimeWithPlural, + d : 'дзень', + dd : relativeTimeWithPlural, + M : 'месяц', + MM : relativeTimeWithPlural, + y : 'год', + yy : relativeTimeWithPlural + }, + meridiemParse: /ночы|раніцы|дня|вечара/, + isPM : function (input) { + return /^(дня|вечара)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночы'; + } else if (hour < 12) { + return 'раніцы'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечара'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; + case 'D': + return number + '-га'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/bg.js b/nodejs/node_modules/moment/src/locale/bg.js new file mode 100755 index 0000000..5ce4dca --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/bg.js @@ -0,0 +1,82 @@ +//! moment.js locale configuration +//! locale : Bulgarian [bg] +//! author : Krasen Borisov : https://github.com/kraz + +import moment from '../moment'; + +export default moment.defineLocale('bg', { + months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), + weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Днес в] LT', + nextDay : '[Утре в] LT', + nextWeek : 'dddd [в] LT', + lastDay : '[Вчера в] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[В изминалата] dddd [в] LT'; + case 1: + case 2: + case 4: + case 5: + return '[В изминалия] dddd [в] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'след %s', + past : 'преди %s', + s : 'няколко секунди', + ss : '%d секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дни', + M : 'месец', + MM : '%d месеца', + y : 'година', + yy : '%d години' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/bm.js b/nodejs/node_modules/moment/src/locale/bm.js new file mode 100755 index 0000000..887a750 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/bm.js @@ -0,0 +1,50 @@ +//! moment.js locale configuration +//! locale : Bambara [bm] +//! author : Estelle Comment : https://github.com/estellecomment +// Language contact person : Abdoufata Kane : https://github.com/abdoufata + +import moment from '../moment'; + +export default moment.defineLocale('bm', { + months : 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split('_'), + monthsShort : 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'), + weekdays : 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'), + weekdaysShort : 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'), + weekdaysMin : 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'MMMM [tile] D [san] YYYY', + LLL : 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm', + LLLL : 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm' + }, + calendar : { + sameDay : '[Bi lɛrɛ] LT', + nextDay : '[Sini lɛrɛ] LT', + nextWeek : 'dddd [don lɛrɛ] LT', + lastDay : '[Kunu lɛrɛ] LT', + lastWeek : 'dddd [tɛmɛnen lɛrɛ] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s kɔnɔ', + past : 'a bɛ %s bɔ', + s : 'sanga dama dama', + ss : 'sekondi %d', + m : 'miniti kelen', + mm : 'miniti %d', + h : 'lɛrɛ kelen', + hh : 'lɛrɛ %d', + d : 'tile kelen', + dd : 'tile %d', + M : 'kalo kelen', + MM : 'kalo %d', + y : 'san kelen', + yy : 'san %d' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/bn.js b/nodejs/node_modules/moment/src/locale/bn.js new file mode 100755 index 0000000..a859a23 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/bn.js @@ -0,0 +1,110 @@ +//! moment.js locale configuration +//! locale : Bengali [bn] +//! author : Kaushik Gandhi : https://github.com/kaushikgandhi + +import moment from '../moment'; + +var symbolMap = { + '1': '১', + '2': '২', + '3': '৩', + '4': '৪', + '5': '৫', + '6': '৬', + '7': '৭', + '8': '৮', + '9': '৯', + '0': '০' +}, +numberMap = { + '১': '1', + '২': '2', + '৩': '3', + '৪': '4', + '৫': '5', + '৬': '6', + '৭': '7', + '৮': '8', + '৯': '9', + '০': '0' +}; + +export default moment.defineLocale('bn', { + months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), + monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'), + weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'), + weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'), + weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'), + longDateFormat : { + LT : 'A h:mm সময়', + LTS : 'A h:mm:ss সময়', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm সময়', + LLLL : 'dddd, D MMMM YYYY, A h:mm সময়' + }, + calendar : { + sameDay : '[আজ] LT', + nextDay : '[আগামীকাল] LT', + nextWeek : 'dddd, LT', + lastDay : '[গতকাল] LT', + lastWeek : '[গত] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s পরে', + past : '%s আগে', + s : 'কয়েক সেকেন্ড', + ss : '%d সেকেন্ড', + m : 'এক মিনিট', + mm : '%d মিনিট', + h : 'এক ঘন্টা', + hh : '%d ঘন্টা', + d : 'এক দিন', + dd : '%d দিন', + M : 'এক মাস', + MM : '%d মাস', + y : 'এক বছর', + yy : '%d বছর' + }, + preparse: function (string) { + return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'রাত' && hour >= 4) || + (meridiem === 'দুপুর' && hour < 5) || + meridiem === 'বিকাল') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'রাত'; + } else if (hour < 10) { + return 'সকাল'; + } else if (hour < 17) { + return 'দুপুর'; + } else if (hour < 20) { + return 'বিকাল'; + } else { + return 'রাত'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/bo.js b/nodejs/node_modules/moment/src/locale/bo.js new file mode 100755 index 0000000..a536d48 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/bo.js @@ -0,0 +1,111 @@ +//! moment.js locale configuration +//! locale : Tibetan [bo] +//! author : Thupten N. Chakrishar : https://github.com/vajradog + +import moment from '../moment'; + +var symbolMap = { + '1': '༡', + '2': '༢', + '3': '༣', + '4': '༤', + '5': '༥', + '6': '༦', + '7': '༧', + '8': '༨', + '9': '༩', + '0': '༠' +}, +numberMap = { + '༡': '1', + '༢': '2', + '༣': '3', + '༤': '4', + '༥': '5', + '༦': '6', + '༧': '7', + '༨': '8', + '༩': '9', + '༠': '0' +}; + +export default moment.defineLocale('bo', { + months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), + weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[དི་རིང] LT', + nextDay : '[སང་ཉིན] LT', + nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', + lastDay : '[ཁ་སང] LT', + lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ལ་', + past : '%s སྔན་ལ', + s : 'ལམ་སང', + ss : '%d སྐར་ཆ།', + m : 'སྐར་མ་གཅིག', + mm : '%d སྐར་མ', + h : 'ཆུ་ཚོད་གཅིག', + hh : '%d ཆུ་ཚོད', + d : 'ཉིན་གཅིག', + dd : '%d ཉིན་', + M : 'ཟླ་བ་གཅིག', + MM : '%d ཟླ་བ', + y : 'ལོ་གཅིག', + yy : '%d ལོ' + }, + preparse: function (string) { + return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'མཚན་མོ' && hour >= 4) || + (meridiem === 'ཉིན་གུང' && hour < 5) || + meridiem === 'དགོང་དག') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'མཚན་མོ'; + } else if (hour < 10) { + return 'ཞོགས་ཀས'; + } else if (hour < 17) { + return 'ཉིན་གུང'; + } else if (hour < 20) { + return 'དགོང་དག'; + } else { + return 'མཚན་མོ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/br.js b/nodejs/node_modules/moment/src/locale/br.js new file mode 100755 index 0000000..7208f79 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/br.js @@ -0,0 +1,100 @@ +//! moment.js locale configuration +//! locale : Breton [br] +//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou + +import moment from '../moment'; + +function relativeTimeWithMutation(number, withoutSuffix, key) { + var format = { + 'mm': 'munutenn', + 'MM': 'miz', + 'dd': 'devezh' + }; + return number + ' ' + mutation(format[key], number); +} +function specialMutationForYears(number) { + switch (lastNumber(number)) { + case 1: + case 3: + case 4: + case 5: + case 9: + return number + ' bloaz'; + default: + return number + ' vloaz'; + } +} +function lastNumber(number) { + if (number > 9) { + return lastNumber(number % 10); + } + return number; +} +function mutation(text, number) { + if (number === 2) { + return softMutation(text); + } + return text; +} +function softMutation(text) { + var mutationTable = { + 'm': 'v', + 'b': 'v', + 'd': 'z' + }; + if (mutationTable[text.charAt(0)] === undefined) { + return text; + } + return mutationTable[text.charAt(0)] + text.substring(1); +} + +export default moment.defineLocale('br', { + months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), + monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), + weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), + weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), + weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h[e]mm A', + LTS : 'h[e]mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [a viz] MMMM YYYY', + LLL : 'D [a viz] MMMM YYYY h[e]mm A', + LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A' + }, + calendar : { + sameDay : '[Hiziv da] LT', + nextDay : '[Warc\'hoazh da] LT', + nextWeek : 'dddd [da] LT', + lastDay : '[Dec\'h da] LT', + lastWeek : 'dddd [paset da] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'a-benn %s', + past : '%s \'zo', + s : 'un nebeud segondennoù', + ss : '%d eilenn', + m : 'ur vunutenn', + mm : relativeTimeWithMutation, + h : 'un eur', + hh : '%d eur', + d : 'un devezh', + dd : relativeTimeWithMutation, + M : 'ur miz', + MM : relativeTimeWithMutation, + y : 'ur bloaz', + yy : specialMutationForYears + }, + dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/, + ordinal : function (number) { + var output = (number === 1) ? 'añ' : 'vet'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/bs.js b/nodejs/node_modules/moment/src/locale/bs.js new file mode 100755 index 0000000..f605c4d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/bs.js @@ -0,0 +1,143 @@ +//! moment.js locale configuration +//! locale : Bosnian [bs] +//! author : Nedim Cholich : https://github.com/frontyard +//! based on (hr) translation by Bojan Marković + +import moment from '../moment'; + +function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } +} + +export default moment.defineLocale('bs', { + months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : 'dan', + dd : translate, + M : 'mjesec', + MM : translate, + y : 'godinu', + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/ca.js b/nodejs/node_modules/moment/src/locale/ca.js new file mode 100755 index 0000000..8d1df57 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ca.js @@ -0,0 +1,80 @@ +//! moment.js locale configuration +//! locale : Catalan [ca] +//! author : Juan G. Hurtado : https://github.com/juanghurtado + +import moment from '../moment'; + +export default moment.defineLocale('ca', { + months : { + standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), + format: 'de gener_de febrer_de març_d\'abril_de maig_de juny_de juliol_d\'agost_de setembre_d\'octubre_de novembre_de desembre'.split('_'), + isFormat: /D[oD]?(\s)+MMMM/ + }, + monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'), + monthsParseExact : true, + weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), + weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), + weekdaysMin : 'dg_dl_dt_dc_dj_dv_ds'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [de] YYYY', + ll : 'D MMM YYYY', + LLL : 'D MMMM [de] YYYY [a les] H:mm', + lll : 'D MMM YYYY, H:mm', + LLLL : 'dddd D MMMM [de] YYYY [a les] H:mm', + llll : 'ddd D MMM YYYY, H:mm' + }, + calendar : { + sameDay : function () { + return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextDay : function () { + return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastDay : function () { + return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'd\'aquí %s', + past : 'fa %s', + s : 'uns segons', + ss : '%d segons', + m : 'un minut', + mm : '%d minuts', + h : 'una hora', + hh : '%d hores', + d : 'un dia', + dd : '%d dies', + M : 'un mes', + MM : '%d mesos', + y : 'un any', + yy : '%d anys' + }, + dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/, + ordinal : function (number, period) { + var output = (number === 1) ? 'r' : + (number === 2) ? 'n' : + (number === 3) ? 'r' : + (number === 4) ? 't' : 'è'; + if (period === 'w' || period === 'W') { + output = 'a'; + } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/cs.js b/nodejs/node_modules/moment/src/locale/cs.js new file mode 100755 index 0000000..6171ab1 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/cs.js @@ -0,0 +1,171 @@ +//! moment.js locale configuration +//! locale : Czech [cs] +//! author : petrbela : https://github.com/petrbela + +import moment from '../moment'; + +var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), + monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); +function plural(n) { + return (n > 1) && (n < 5) && (~~(n / 10) !== 1); +} +function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'sekundy' : 'sekund'); + } else { + return result + 'sekundami'; + } + break; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minuty' : 'minut'); + } else { + return result + 'minutami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodin'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'den' : 'dnem'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dny' : 'dní'); + } else { + return result + 'dny'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'měsíce' : 'měsíců'); + } else { + return result + 'měsíci'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'let'); + } else { + return result + 'lety'; + } + break; + } +} + +export default moment.defineLocale('cs', { + months : months, + monthsShort : monthsShort, + monthsParse : (function (months, monthsShort) { + var i, _monthsParse = []; + for (i = 0; i < 12; i++) { + // use custom parser to solve problem with July (červenec) + _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); + } + return _monthsParse; + }(months, monthsShort)), + shortMonthsParse : (function (monthsShort) { + var i, _shortMonthsParse = []; + for (i = 0; i < 12; i++) { + _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i'); + } + return _shortMonthsParse; + }(monthsShort)), + longMonthsParse : (function (months) { + var i, _longMonthsParse = []; + for (i = 0; i < 12; i++) { + _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i'); + } + return _longMonthsParse; + }(months)), + weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), + weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), + weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), + longDateFormat : { + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm', + l : 'D. M. YYYY' + }, + calendar : { + sameDay: '[dnes v] LT', + nextDay: '[zítra v] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v neděli v] LT'; + case 1: + case 2: + return '[v] dddd [v] LT'; + case 3: + return '[ve středu v] LT'; + case 4: + return '[ve čtvrtek v] LT'; + case 5: + return '[v pátek v] LT'; + case 6: + return '[v sobotu v] LT'; + } + }, + lastDay: '[včera v] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulou neděli v] LT'; + case 1: + case 2: + return '[minulé] dddd [v] LT'; + case 3: + return '[minulou středu v] LT'; + case 4: + case 5: + return '[minulý] dddd [v] LT'; + case 6: + return '[minulou sobotu v] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : 'před %s', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse : /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/cv.js b/nodejs/node_modules/moment/src/locale/cv.js new file mode 100755 index 0000000..d97d4d9 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/cv.js @@ -0,0 +1,54 @@ +//! moment.js locale configuration +//! locale : Chuvash [cv] +//! author : Anatoly Mironov : https://github.com/mirontoli + +import moment from '../moment'; + +export default moment.defineLocale('cv', { + months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'), + monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), + weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'), + weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), + weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', + LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', + LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm' + }, + calendar : { + sameDay: '[Паян] LT [сехетре]', + nextDay: '[Ыран] LT [сехетре]', + lastDay: '[Ӗнер] LT [сехетре]', + nextWeek: '[Ҫитес] dddd LT [сехетре]', + lastWeek: '[Иртнӗ] dddd LT [сехетре]', + sameElse: 'L' + }, + relativeTime : { + future : function (output) { + var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран'; + return output + affix; + }, + past : '%s каялла', + s : 'пӗр-ик ҫеккунт', + ss : '%d ҫеккунт', + m : 'пӗр минут', + mm : '%d минут', + h : 'пӗр сехет', + hh : '%d сехет', + d : 'пӗр кун', + dd : '%d кун', + M : 'пӗр уйӑх', + MM : '%d уйӑх', + y : 'пӗр ҫул', + yy : '%d ҫул' + }, + dayOfMonthOrdinalParse: /\d{1,2}-мӗш/, + ordinal : '%d-мӗш', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/cy.js b/nodejs/node_modules/moment/src/locale/cy.js new file mode 100755 index 0000000..eb2e54c --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/cy.js @@ -0,0 +1,73 @@ +//! moment.js locale configuration +//! locale : Welsh [cy] +//! author : Robert Allen : https://github.com/robgallen +//! author : https://github.com/ryangreaves + +import moment from '../moment'; + +export default moment.defineLocale('cy', { + months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), + monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), + weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), + weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), + weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), + weekdaysParseExact : true, + // time formats are the same as en-gb + longDateFormat: { + LT: 'HH:mm', + LTS : 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[Heddiw am] LT', + nextDay: '[Yfory am] LT', + nextWeek: 'dddd [am] LT', + lastDay: '[Ddoe am] LT', + lastWeek: 'dddd [diwethaf am] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'mewn %s', + past: '%s yn ôl', + s: 'ychydig eiliadau', + ss: '%d eiliad', + m: 'munud', + mm: '%d munud', + h: 'awr', + hh: '%d awr', + d: 'diwrnod', + dd: '%d diwrnod', + M: 'mis', + MM: '%d mis', + y: 'blwyddyn', + yy: '%d flynedd' + }, + dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, + // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh + ordinal: function (number) { + var b = number, + output = '', + lookup = [ + '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed + 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed + ]; + if (b > 20) { + if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { + output = 'fed'; // not 30ain, 70ain or 90ain + } else { + output = 'ain'; + } + } else if (b > 0) { + output = lookup[b]; + } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/da.js b/nodejs/node_modules/moment/src/locale/da.js new file mode 100755 index 0000000..a06c6e0 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/da.js @@ -0,0 +1,51 @@ +//! moment.js locale configuration +//! locale : Danish [da] +//! author : Ulrik Nielsen : https://github.com/mrbase + +import moment from '../moment'; + +export default moment.defineLocale('da', { + months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay : '[i dag kl.] LT', + nextDay : '[i morgen kl.] LT', + nextWeek : 'på dddd [kl.] LT', + lastDay : '[i går kl.] LT', + lastWeek : '[i] dddd[s kl.] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s siden', + s : 'få sekunder', + ss : '%d sekunder', + m : 'et minut', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dage', + M : 'en måned', + MM : '%d måneder', + y : 'et år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/de-at.js b/nodejs/node_modules/moment/src/locale/de-at.js new file mode 100755 index 0000000..4ed974c --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/de-at.js @@ -0,0 +1,70 @@ +//! moment.js locale configuration +//! locale : German (Austria) [de-at] +//! author : lluchs : https://github.com/lluchs +//! author: Menelion Elensúle: https://github.com/Oire +//! author : Martin Groller : https://github.com/MadMG +//! author : Mikolaj Dadela : https://github.com/mik01aj + +import moment from '../moment'; + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; +} + +export default moment.defineLocale('de-at', { + months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime, + mm : '%d Minuten', + h : processRelativeTime, + hh : '%d Stunden', + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/de-ch.js b/nodejs/node_modules/moment/src/locale/de-ch.js new file mode 100755 index 0000000..c448345 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/de-ch.js @@ -0,0 +1,69 @@ +//! moment.js locale configuration +//! locale : German (Switzerland) [de-ch] +//! author : sschueller : https://github.com/sschueller + +// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de# + +import moment from '../moment'; + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; +} + +export default moment.defineLocale('de-ch', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime, + mm : '%d Minuten', + h : processRelativeTime, + hh : '%d Stunden', + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/de.js b/nodejs/node_modules/moment/src/locale/de.js new file mode 100755 index 0000000..4574656 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/de.js @@ -0,0 +1,69 @@ +//! moment.js locale configuration +//! locale : German [de] +//! author : lluchs : https://github.com/lluchs +//! author: Menelion Elensúle: https://github.com/Oire +//! author : Mikolaj Dadela : https://github.com/mik01aj + +import moment from '../moment'; + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; +} + +export default moment.defineLocale('de', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime, + mm : '%d Minuten', + h : processRelativeTime, + hh : '%d Stunden', + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/dv.js b/nodejs/node_modules/moment/src/locale/dv.js new file mode 100755 index 0000000..3268843 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/dv.js @@ -0,0 +1,90 @@ +//! moment.js locale configuration +//! locale : Maldivian [dv] +//! author : Jawish Hameed : https://github.com/jawish + +import moment from '../moment'; + +var months = [ + 'ޖެނުއަރީ', + 'ފެބްރުއަރީ', + 'މާރިޗު', + 'އޭޕްރީލު', + 'މޭ', + 'ޖޫން', + 'ޖުލައި', + 'އޯގަސްޓު', + 'ސެޕްޓެމްބަރު', + 'އޮކްޓޯބަރު', + 'ނޮވެމްބަރު', + 'ޑިސެމްބަރު' +], weekdays = [ + 'އާދިއްތަ', + 'ހޯމަ', + 'އަންގާރަ', + 'ބުދަ', + 'ބުރާސްފަތި', + 'ހުކުރު', + 'ހޮނިހިރު' +]; + +export default moment.defineLocale('dv', { + months : months, + monthsShort : months, + weekdays : weekdays, + weekdaysShort : weekdays, + weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), + longDateFormat : { + + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/M/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /މކ|މފ/, + isPM : function (input) { + return 'މފ' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'މކ'; + } else { + return 'މފ'; + } + }, + calendar : { + sameDay : '[މިއަދު] LT', + nextDay : '[މާދަމާ] LT', + nextWeek : 'dddd LT', + lastDay : '[އިއްޔެ] LT', + lastWeek : '[ފާއިތުވި] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ތެރޭގައި %s', + past : 'ކުރިން %s', + s : 'ސިކުންތުކޮޅެއް', + ss : 'd% ސިކުންތު', + m : 'މިނިޓެއް', + mm : 'މިނިޓު %d', + h : 'ގަޑިއިރެއް', + hh : 'ގަޑިއިރު %d', + d : 'ދުވަހެއް', + dd : 'ދުވަސް %d', + M : 'މަހެއް', + MM : 'މަސް %d', + y : 'އަހަރެއް', + yy : 'އަހަރު %d' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 7, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/el.js b/nodejs/node_modules/moment/src/locale/el.js new file mode 100755 index 0000000..5e43ae3 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/el.js @@ -0,0 +1,89 @@ +//! moment.js locale configuration +//! locale : Greek [el] +//! author : Aggelos Karalias : https://github.com/mehiel + +import moment from '../moment'; +import isFunction from '../lib/utils/is-function'; + +export default moment.defineLocale('el', { + monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), + monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), + months : function (momentToFormat, format) { + if (!momentToFormat) { + return this._monthsNominativeEl; + } else if (typeof format === 'string' && /D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' + return this._monthsGenitiveEl[momentToFormat.month()]; + } else { + return this._monthsNominativeEl[momentToFormat.month()]; + } + }, + monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), + weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), + weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), + weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'μμ' : 'ΜΜ'; + } else { + return isLower ? 'πμ' : 'ΠΜ'; + } + }, + isPM : function (input) { + return ((input + '').toLowerCase()[0] === 'μ'); + }, + meridiemParse : /[ΠΜ]\.?Μ?\.?/i, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendarEl : { + sameDay : '[Σήμερα {}] LT', + nextDay : '[Αύριο {}] LT', + nextWeek : 'dddd [{}] LT', + lastDay : '[Χθες {}] LT', + lastWeek : function () { + switch (this.day()) { + case 6: + return '[το προηγούμενο] dddd [{}] LT'; + default: + return '[την προηγούμενη] dddd [{}] LT'; + } + }, + sameElse : 'L' + }, + calendar : function (key, mom) { + var output = this._calendarEl[key], + hours = mom && mom.hours(); + if (isFunction(output)) { + output = output.apply(mom); + } + return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); + }, + relativeTime : { + future : 'σε %s', + past : '%s πριν', + s : 'λίγα δευτερόλεπτα', + ss : '%d δευτερόλεπτα', + m : 'ένα λεπτό', + mm : '%d λεπτά', + h : 'μία ώρα', + hh : '%d ώρες', + d : 'μία μέρα', + dd : '%d μέρες', + M : 'ένας μήνας', + MM : '%d μήνες', + y : 'ένας χρόνος', + yy : '%d χρόνια' + }, + dayOfMonthOrdinalParse: /\d{1,2}η/, + ordinal: '%dη', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/en-au.js b/nodejs/node_modules/moment/src/locale/en-au.js new file mode 100755 index 0000000..04e61e4 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/en-au.js @@ -0,0 +1,59 @@ +//! moment.js locale configuration +//! locale : English (Australia) [en-au] +//! author : Jared Morse : https://github.com/jarcoal + +import moment from '../moment'; + +export default moment.defineLocale('en-au', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/en-ca.js b/nodejs/node_modules/moment/src/locale/en-ca.js new file mode 100755 index 0000000..008baed --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/en-ca.js @@ -0,0 +1,54 @@ +//! moment.js locale configuration +//! locale : English (Canada) [en-ca] +//! author : Jonathan Abourbih : https://github.com/jonbca + +import moment from '../moment'; + +export default moment.defineLocale('en-ca', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'YYYY-MM-DD', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } +}); diff --git a/nodejs/node_modules/moment/src/locale/en-gb.js b/nodejs/node_modules/moment/src/locale/en-gb.js new file mode 100755 index 0000000..da235be --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/en-gb.js @@ -0,0 +1,59 @@ +//! moment.js locale configuration +//! locale : English (United Kingdom) [en-gb] +//! author : Chris Gedrim : https://github.com/chrisgedrim + +import moment from '../moment'; + +export default moment.defineLocale('en-gb', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/en-ie.js b/nodejs/node_modules/moment/src/locale/en-ie.js new file mode 100755 index 0000000..725ff9e --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/en-ie.js @@ -0,0 +1,59 @@ +//! moment.js locale configuration +//! locale : English (Ireland) [en-ie] +//! author : Chris Cartlidge : https://github.com/chriscartlidge + +import moment from '../moment'; + +export default moment.defineLocale('en-ie', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/en-il.js b/nodejs/node_modules/moment/src/locale/en-il.js new file mode 100755 index 0000000..da293eb --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/en-il.js @@ -0,0 +1,54 @@ +//! moment.js locale configuration +//! locale : English (Israel) [en-il] +//! author : Chris Gedrim : https://github.com/chrisgedrim + +import moment from '../moment'; + +export default moment.defineLocale('en-il', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/en-nz.js b/nodejs/node_modules/moment/src/locale/en-nz.js new file mode 100755 index 0000000..ee7c468 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/en-nz.js @@ -0,0 +1,58 @@ +//! moment.js locale configuration +//! locale : English (New Zealand) [en-nz] +//! author : Luke McGregor : https://github.com/lukemcgregor + +import moment from '../moment'; + +export default moment.defineLocale('en-nz', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/eo.js b/nodejs/node_modules/moment/src/locale/eo.js new file mode 100755 index 0000000..66c1ac0 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/eo.js @@ -0,0 +1,65 @@ +//! moment.js locale configuration +//! locale : Esperanto [eo] +//! author : Colin Dean : https://github.com/colindean +//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia +//! comment : miestasmia corrected the translation by colindean + +import moment from '../moment'; + +export default moment.defineLocale('eo', { + months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), + weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'), + weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'), + weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D[-a de] MMMM, YYYY', + LLL : 'D[-a de] MMMM, YYYY HH:mm', + LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm' + }, + meridiemParse: /[ap]\.t\.m/i, + isPM: function (input) { + return input.charAt(0).toLowerCase() === 'p'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'p.t.m.' : 'P.T.M.'; + } else { + return isLower ? 'a.t.m.' : 'A.T.M.'; + } + }, + calendar : { + sameDay : '[Hodiaŭ je] LT', + nextDay : '[Morgaŭ je] LT', + nextWeek : 'dddd [je] LT', + lastDay : '[Hieraŭ je] LT', + lastWeek : '[pasinta] dddd [je] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'post %s', + past : 'antaŭ %s', + s : 'sekundoj', + ss : '%d sekundoj', + m : 'minuto', + mm : '%d minutoj', + h : 'horo', + hh : '%d horoj', + d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo + dd : '%d tagoj', + M : 'monato', + MM : '%d monatoj', + y : 'jaro', + yy : '%d jaroj' + }, + dayOfMonthOrdinalParse: /\d{1,2}a/, + ordinal : '%da', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/es-do.js b/nodejs/node_modules/moment/src/locale/es-do.js new file mode 100755 index 0000000..c839785 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/es-do.js @@ -0,0 +1,83 @@ +//! moment.js locale configuration +//! locale : Spanish (Dominican Republic) [es-do] + +import moment from '../moment'; + +var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + +var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; +var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + +export default moment.defineLocale('es-do', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY h:mm A', + LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/es-us.js b/nodejs/node_modules/moment/src/locale/es-us.js new file mode 100755 index 0000000..9fa1460 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/es-us.js @@ -0,0 +1,74 @@ +//! moment.js locale configuration +//! locale : Spanish (United States) [es-us] +//! author : bustta : https://github.com/bustta + +import moment from '../moment'; + +var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + +export default moment.defineLocale('es-us', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsParseExact : true, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'MM/DD/YYYY', + LL : 'MMMM [de] D [de] YYYY', + LLL : 'MMMM [de] D [de] YYYY h:mm A', + LLLL : 'dddd, MMMM [de] D [de] YYYY h:mm A' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/es.js b/nodejs/node_modules/moment/src/locale/es.js new file mode 100755 index 0000000..4dc588a --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/es.js @@ -0,0 +1,83 @@ +//! moment.js locale configuration +//! locale : Spanish [es] +//! author : Julio Napurí : https://github.com/julionc + +import moment from '../moment'; + +var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + +var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; +var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + +export default moment.defineLocale('es', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex : monthsRegex, + monthsShortRegex : monthsRegex, + monthsStrictRegex : /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex : /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/et.js b/nodejs/node_modules/moment/src/locale/et.js new file mode 100755 index 0000000..22415e7 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/et.js @@ -0,0 +1,73 @@ +//! moment.js locale configuration +//! locale : Estonian [et] +//! author : Henry Kehlmann : https://github.com/madhenry +//! improvements : Illimar Tambek : https://github.com/ragulka + +import moment from '../moment'; + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], + 'ss': [number + 'sekundi', number + 'sekundit'], + 'm' : ['ühe minuti', 'üks minut'], + 'mm': [number + ' minuti', number + ' minutit'], + 'h' : ['ühe tunni', 'tund aega', 'üks tund'], + 'hh': [number + ' tunni', number + ' tundi'], + 'd' : ['ühe päeva', 'üks päev'], + 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], + 'MM': [number + ' kuu', number + ' kuud'], + 'y' : ['ühe aasta', 'aasta', 'üks aasta'], + 'yy': [number + ' aasta', number + ' aastat'] + }; + if (withoutSuffix) { + return format[key][2] ? format[key][2] : format[key][1]; + } + return isFuture ? format[key][0] : format[key][1]; +} + +export default moment.defineLocale('et', { + months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), + monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), + weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), + weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), + weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Täna,] LT', + nextDay : '[Homme,] LT', + nextWeek : '[Järgmine] dddd LT', + lastDay : '[Eile,] LT', + lastWeek : '[Eelmine] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s pärast', + past : '%s tagasi', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : '%d päeva', + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/eu.js b/nodejs/node_modules/moment/src/locale/eu.js new file mode 100755 index 0000000..d544788 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/eu.js @@ -0,0 +1,58 @@ +//! moment.js locale configuration +//! locale : Basque [eu] +//! author : Eneko Illarramendi : https://github.com/eillarra + +import moment from '../moment'; + +export default moment.defineLocale('eu', { + months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), + monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), + monthsParseExact : true, + weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), + weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), + weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY[ko] MMMM[ren] D[a]', + LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', + LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', + l : 'YYYY-M-D', + ll : 'YYYY[ko] MMM D[a]', + lll : 'YYYY[ko] MMM D[a] HH:mm', + llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' + }, + calendar : { + sameDay : '[gaur] LT[etan]', + nextDay : '[bihar] LT[etan]', + nextWeek : 'dddd LT[etan]', + lastDay : '[atzo] LT[etan]', + lastWeek : '[aurreko] dddd LT[etan]', + sameElse : 'L' + }, + relativeTime : { + future : '%s barru', + past : 'duela %s', + s : 'segundo batzuk', + ss : '%d segundo', + m : 'minutu bat', + mm : '%d minutu', + h : 'ordu bat', + hh : '%d ordu', + d : 'egun bat', + dd : '%d egun', + M : 'hilabete bat', + MM : '%d hilabete', + y : 'urte bat', + yy : '%d urte' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/fa.js b/nodejs/node_modules/moment/src/locale/fa.js new file mode 100755 index 0000000..cf503c1 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/fa.js @@ -0,0 +1,98 @@ +//! moment.js locale configuration +//! locale : Persian [fa] +//! author : Ebrahim Byagowi : https://github.com/ebraminio + +import moment from '../moment'; + +var symbolMap = { + '1': '۱', + '2': '۲', + '3': '۳', + '4': '۴', + '5': '۵', + '6': '۶', + '7': '۷', + '8': '۸', + '9': '۹', + '0': '۰' +}, numberMap = { + '۱': '1', + '۲': '2', + '۳': '3', + '۴': '4', + '۵': '5', + '۶': '6', + '۷': '7', + '۸': '8', + '۹': '9', + '۰': '0' +}; + +export default moment.defineLocale('fa', { + months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /قبل از ظهر|بعد از ظهر/, + isPM: function (input) { + return /بعد از ظهر/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'قبل از ظهر'; + } else { + return 'بعد از ظهر'; + } + }, + calendar : { + sameDay : '[امروز ساعت] LT', + nextDay : '[فردا ساعت] LT', + nextWeek : 'dddd [ساعت] LT', + lastDay : '[دیروز ساعت] LT', + lastWeek : 'dddd [پیش] [ساعت] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'در %s', + past : '%s پیش', + s : 'چند ثانیه', + ss : 'ثانیه d%', + m : 'یک دقیقه', + mm : '%d دقیقه', + h : 'یک ساعت', + hh : '%d ساعت', + d : 'یک روز', + dd : '%d روز', + M : 'یک ماه', + MM : '%d ماه', + y : 'یک سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/[۰-۹]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + dayOfMonthOrdinalParse: /\d{1,2}م/, + ordinal : '%dم', + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/fi.js b/nodejs/node_modules/moment/src/locale/fi.js new file mode 100755 index 0000000..c505292 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/fi.js @@ -0,0 +1,101 @@ +//! moment.js locale configuration +//! locale : Finnish [fi] +//! author : Tarmo Aidantausta : https://github.com/bleadof + +import moment from '../moment'; + +var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), + numbersFuture = [ + 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', + numbersPast[7], numbersPast[8], numbersPast[9] + ]; +function translate(number, withoutSuffix, key, isFuture) { + var result = ''; + switch (key) { + case 's': + return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; + case 'ss': + return isFuture ? 'sekunnin' : 'sekuntia'; + case 'm': + return isFuture ? 'minuutin' : 'minuutti'; + case 'mm': + result = isFuture ? 'minuutin' : 'minuuttia'; + break; + case 'h': + return isFuture ? 'tunnin' : 'tunti'; + case 'hh': + result = isFuture ? 'tunnin' : 'tuntia'; + break; + case 'd': + return isFuture ? 'päivän' : 'päivä'; + case 'dd': + result = isFuture ? 'päivän' : 'päivää'; + break; + case 'M': + return isFuture ? 'kuukauden' : 'kuukausi'; + case 'MM': + result = isFuture ? 'kuukauden' : 'kuukautta'; + break; + case 'y': + return isFuture ? 'vuoden' : 'vuosi'; + case 'yy': + result = isFuture ? 'vuoden' : 'vuotta'; + break; + } + result = verbalNumber(number, isFuture) + ' ' + result; + return result; +} +function verbalNumber(number, isFuture) { + return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; +} + +export default moment.defineLocale('fi', { + months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), + monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), + weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), + weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), + weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'Do MMMM[ta] YYYY', + LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm', + LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', + l : 'D.M.YYYY', + ll : 'Do MMM YYYY', + lll : 'Do MMM YYYY, [klo] HH.mm', + llll : 'ddd, Do MMM YYYY, [klo] HH.mm' + }, + calendar : { + sameDay : '[tänään] [klo] LT', + nextDay : '[huomenna] [klo] LT', + nextWeek : 'dddd [klo] LT', + lastDay : '[eilen] [klo] LT', + lastWeek : '[viime] dddd[na] [klo] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s päästä', + past : '%s sitten', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/fo.js b/nodejs/node_modules/moment/src/locale/fo.js new file mode 100755 index 0000000..5efc4cc --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/fo.js @@ -0,0 +1,52 @@ +//! moment.js locale configuration +//! locale : Faroese [fo] +//! author : Ragnar Johannesen : https://github.com/ragnar123 + +import moment from '../moment'; + +export default moment.defineLocale('fo', { + months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), + weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), + weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D. MMMM, YYYY HH:mm' + }, + calendar : { + sameDay : '[Í dag kl.] LT', + nextDay : '[Í morgin kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[Í gjár kl.] LT', + lastWeek : '[síðstu] dddd [kl] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'um %s', + past : '%s síðani', + s : 'fá sekund', + ss : '%d sekundir', + m : 'ein minutt', + mm : '%d minuttir', + h : 'ein tími', + hh : '%d tímar', + d : 'ein dagur', + dd : '%d dagar', + M : 'ein mánaði', + MM : '%d mánaðir', + y : 'eitt ár', + yy : '%d ár' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/fr-ca.js b/nodejs/node_modules/moment/src/locale/fr-ca.js new file mode 100755 index 0000000..4825a6d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/fr-ca.js @@ -0,0 +1,66 @@ +//! moment.js locale configuration +//! locale : French (Canada) [fr-ca] +//! author : Jonathan Abourbih : https://github.com/jonbca + +import moment from '../moment'; + +export default moment.defineLocale('fr-ca', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal : function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/fr-ch.js b/nodejs/node_modules/moment/src/locale/fr-ch.js new file mode 100755 index 0000000..febd401 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/fr-ch.js @@ -0,0 +1,70 @@ +//! moment.js locale configuration +//! locale : French (Switzerland) [fr-ch] +//! author : Gaspard Bucher : https://github.com/gaspard + +import moment from '../moment'; + +export default moment.defineLocale('fr-ch', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal : function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/fr.js b/nodejs/node_modules/moment/src/locale/fr.js new file mode 100755 index 0000000..81399dc --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/fr.js @@ -0,0 +1,75 @@ +//! moment.js locale configuration +//! locale : French [fr] +//! author : John Fischer : https://github.com/jfroffice + +import moment from '../moment'; + +export default moment.defineLocale('fr', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|)/, + ordinal : function (number, period) { + switch (period) { + // TODO: Return 'e' when day of month > 1. Move this case inside + // block for masculine words below. + // See https://github.com/moment/moment/issues/3375 + case 'D': + return number + (number === 1 ? 'er' : ''); + + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/fy.js b/nodejs/node_modules/moment/src/locale/fy.js new file mode 100755 index 0000000..b4b2096 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/fy.js @@ -0,0 +1,67 @@ +//! moment.js locale configuration +//! locale : Frisian [fy] +//! author : Robin van der Vliet : https://github.com/robin0van0der0v + +import moment from '../moment'; + +var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'); + +export default moment.defineLocale('fy', { + months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + monthsParseExact : true, + weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'), + weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'), + weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[hjoed om] LT', + nextDay: '[moarn om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[juster om] LT', + lastWeek: '[ôfrûne] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'oer %s', + past : '%s lyn', + s : 'in pear sekonden', + ss : '%d sekonden', + m : 'ien minút', + mm : '%d minuten', + h : 'ien oere', + hh : '%d oeren', + d : 'ien dei', + dd : '%d dagen', + M : 'ien moanne', + MM : '%d moannen', + y : 'ien jier', + yy : '%d jierren' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/gd.js b/nodejs/node_modules/moment/src/locale/gd.js new file mode 100755 index 0000000..b3653d2 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/gd.js @@ -0,0 +1,68 @@ +//! moment.js locale configuration +//! locale : Scottish Gaelic [gd] +//! author : Jon Ashdown : https://github.com/jonashdown + +import moment from '../moment'; + +var months = [ + 'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd' +]; + +var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh']; + +var weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne']; + +var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis']; + +var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; + +export default moment.defineLocale('gd', { + months : months, + monthsShort : monthsShort, + monthsParseExact : true, + weekdays : weekdays, + weekdaysShort : weekdaysShort, + weekdaysMin : weekdaysMin, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[An-diugh aig] LT', + nextDay : '[A-màireach aig] LT', + nextWeek : 'dddd [aig] LT', + lastDay : '[An-dè aig] LT', + lastWeek : 'dddd [seo chaidh] [aig] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ann an %s', + past : 'bho chionn %s', + s : 'beagan diogan', + ss : '%d diogan', + m : 'mionaid', + mm : '%d mionaidean', + h : 'uair', + hh : '%d uairean', + d : 'latha', + dd : '%d latha', + M : 'mìos', + MM : '%d mìosan', + y : 'bliadhna', + yy : '%d bliadhna' + }, + dayOfMonthOrdinalParse : /\d{1,2}(d|na|mh)/, + ordinal : function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/gl.js b/nodejs/node_modules/moment/src/locale/gl.js new file mode 100755 index 0000000..206a8f6 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/gl.js @@ -0,0 +1,69 @@ +//! moment.js locale configuration +//! locale : Galician [gl] +//! author : Juan G. Hurtado : https://github.com/juanghurtado + +import moment from '../moment'; + +export default moment.defineLocale('gl', { + months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'), + monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextDay : function () { + return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextWeek : function () { + return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + lastDay : function () { + return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; + }, + lastWeek : function () { + return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : function (str) { + if (str.indexOf('un') === 0) { + return 'n' + str; + } + return 'en ' + str; + }, + past : 'hai %s', + s : 'uns segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'unha hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un ano', + yy : '%d anos' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/gom-latn.js b/nodejs/node_modules/moment/src/locale/gom-latn.js new file mode 100755 index 0000000..39ad91e --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/gom-latn.js @@ -0,0 +1,114 @@ +//! moment.js locale configuration +//! locale : Konkani Latin script [gom-latn] +//! author : The Discoverer : https://github.com/WikiDiscoverer + +import moment from '../moment'; + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['thodde secondanim', 'thodde second'], + 'ss': [number + ' secondanim', number + ' second'], + 'm': ['eka mintan', 'ek minute'], + 'mm': [number + ' mintanim', number + ' mintam'], + 'h': ['eka horan', 'ek hor'], + 'hh': [number + ' horanim', number + ' horam'], + 'd': ['eka disan', 'ek dis'], + 'dd': [number + ' disanim', number + ' dis'], + 'M': ['eka mhoinean', 'ek mhoino'], + 'MM': [number + ' mhoineanim', number + ' mhoine'], + 'y': ['eka vorsan', 'ek voros'], + 'yy': [number + ' vorsanim', number + ' vorsam'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; +} + +export default moment.defineLocale('gom-latn', { + months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'), + monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\'var'.split('_'), + weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'), + weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'A h:mm [vazta]', + LTS : 'A h:mm:ss [vazta]', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY A h:mm [vazta]', + LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]', + llll: 'ddd, D MMM YYYY, A h:mm [vazta]' + }, + calendar : { + sameDay: '[Aiz] LT', + nextDay: '[Faleam] LT', + nextWeek: '[Ieta to] dddd[,] LT', + lastDay: '[Kal] LT', + lastWeek: '[Fatlo] dddd[,] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s', + past : '%s adim', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse : /\d{1,2}(er)/, + ordinal : function (number, period) { + switch (period) { + // the ordinal 'er' only applies to day of the month + case 'D': + return number + 'er'; + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + case 'w': + case 'W': + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + }, + meridiemParse: /rati|sokalli|donparam|sanje/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'rati') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'sokalli') { + return hour; + } else if (meridiem === 'donparam') { + return hour > 12 ? hour : hour + 12; + } else if (meridiem === 'sanje') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'rati'; + } else if (hour < 12) { + return 'sokalli'; + } else if (hour < 16) { + return 'donparam'; + } else if (hour < 20) { + return 'sanje'; + } else { + return 'rati'; + } + } +}); diff --git a/nodejs/node_modules/moment/src/locale/gu.js b/nodejs/node_modules/moment/src/locale/gu.js new file mode 100755 index 0000000..ecde951 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/gu.js @@ -0,0 +1,115 @@ +//! moment.js locale configuration +//! locale : Gujarati [gu] +//! author : Kaushik Thanki : https://github.com/Kaushik1987 + +import moment from '../moment'; + +var symbolMap = { + '1': '૧', + '2': '૨', + '3': '૩', + '4': '૪', + '5': '૫', + '6': '૬', + '7': '૭', + '8': '૮', + '9': '૯', + '0': '૦' + }, + numberMap = { + '૧': '1', + '૨': '2', + '૩': '3', + '૪': '4', + '૫': '5', + '૬': '6', + '૭': '7', + '૮': '8', + '૯': '9', + '૦': '0' + }; + +export default moment.defineLocale('gu', { + months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split('_'), + monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.'.split('_'), + monthsParseExact: true, + weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split('_'), + weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'), + weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'), + longDateFormat: { + LT: 'A h:mm વાગ્યે', + LTS: 'A h:mm:ss વાગ્યે', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm વાગ્યે', + LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે' + }, + calendar: { + sameDay: '[આજ] LT', + nextDay: '[કાલે] LT', + nextWeek: 'dddd, LT', + lastDay: '[ગઇકાલે] LT', + lastWeek: '[પાછલા] dddd, LT', + sameElse: 'L' + }, + relativeTime: { + future: '%s મા', + past: '%s પેહલા', + s: 'અમુક પળો', + ss: '%d સેકંડ', + m: 'એક મિનિટ', + mm: '%d મિનિટ', + h: 'એક કલાક', + hh: '%d કલાક', + d: 'એક દિવસ', + dd: '%d દિવસ', + M: 'એક મહિનો', + MM: '%d મહિનો', + y: 'એક વર્ષ', + yy: '%d વર્ષ' + }, + preparse: function (string) { + return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Gujarati notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati. + meridiemParse: /રાત|બપોર|સવાર|સાંજ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'રાત') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'સવાર') { + return hour; + } else if (meridiem === 'બપોર') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'સાંજ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'રાત'; + } else if (hour < 10) { + return 'સવાર'; + } else if (hour < 17) { + return 'બપોર'; + } else if (hour < 20) { + return 'સાંજ'; + } else { + return 'રાત'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/he.js b/nodejs/node_modules/moment/src/locale/he.js new file mode 100755 index 0000000..02af634 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/he.js @@ -0,0 +1,91 @@ +//! moment.js locale configuration +//! locale : Hebrew [he] +//! author : Tomer Cohen : https://github.com/tomer +//! author : Moshe Simantov : https://github.com/DevelopmentIL +//! author : Tal Ater : https://github.com/TalAter + +import moment from '../moment'; + +export default moment.defineLocale('he', { + months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), + monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), + weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), + weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), + weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [ב]MMMM YYYY', + LLL : 'D [ב]MMMM YYYY HH:mm', + LLLL : 'dddd, D [ב]MMMM YYYY HH:mm', + l : 'D/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' + }, + calendar : { + sameDay : '[היום ב־]LT', + nextDay : '[מחר ב־]LT', + nextWeek : 'dddd [בשעה] LT', + lastDay : '[אתמול ב־]LT', + lastWeek : '[ביום] dddd [האחרון בשעה] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'בעוד %s', + past : 'לפני %s', + s : 'מספר שניות', + ss : '%d שניות', + m : 'דקה', + mm : '%d דקות', + h : 'שעה', + hh : function (number) { + if (number === 2) { + return 'שעתיים'; + } + return number + ' שעות'; + }, + d : 'יום', + dd : function (number) { + if (number === 2) { + return 'יומיים'; + } + return number + ' ימים'; + }, + M : 'חודש', + MM : function (number) { + if (number === 2) { + return 'חודשיים'; + } + return number + ' חודשים'; + }, + y : 'שנה', + yy : function (number) { + if (number === 2) { + return 'שנתיים'; + } else if (number % 10 === 0 && number !== 10) { + return number + ' שנה'; + } + return number + ' שנים'; + } + }, + meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i, + isPM : function (input) { + return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 5) { + return 'לפנות בוקר'; + } else if (hour < 10) { + return 'בבוקר'; + } else if (hour < 12) { + return isLower ? 'לפנה"צ' : 'לפני הצהריים'; + } else if (hour < 18) { + return isLower ? 'אחה"צ' : 'אחרי הצהריים'; + } else { + return 'בערב'; + } + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/hi.js b/nodejs/node_modules/moment/src/locale/hi.js new file mode 100755 index 0000000..f347160 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/hi.js @@ -0,0 +1,116 @@ +//! moment.js locale configuration +//! locale : Hindi [hi] +//! author : Mayank Singhal : https://github.com/mayanksinghal + +import moment from '../moment'; + +var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' +}, +numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' +}; + +export default moment.defineLocale('hi', { + months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), + monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), + monthsParseExact: true, + weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat : { + LT : 'A h:mm बजे', + LTS : 'A h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, A h:mm बजे' + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[कल] LT', + nextWeek : 'dddd, LT', + lastDay : '[कल] LT', + lastWeek : '[पिछले] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s में', + past : '%s पहले', + s : 'कुछ ही क्षण', + ss : '%d सेकंड', + m : 'एक मिनट', + mm : '%d मिनट', + h : 'एक घंटा', + hh : '%d घंटे', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महीने', + MM : '%d महीने', + y : 'एक वर्ष', + yy : '%d वर्ष' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Hindi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. + meridiemParse: /रात|सुबह|दोपहर|शाम/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सुबह') { + return hour; + } else if (meridiem === 'दोपहर') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'शाम') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'रात'; + } else if (hour < 10) { + return 'सुबह'; + } else if (hour < 17) { + return 'दोपहर'; + } else if (hour < 20) { + return 'शाम'; + } else { + return 'रात'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/hr.js b/nodejs/node_modules/moment/src/locale/hr.js new file mode 100755 index 0000000..aa3b853 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/hr.js @@ -0,0 +1,145 @@ +//! moment.js locale configuration +//! locale : Croatian [hr] +//! author : Bojan Marković : https://github.com/bmarkovic + +import moment from '../moment'; + +function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } +} + +export default moment.defineLocale('hr', { + months : { + format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'), + standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_') + }, + monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), + monthsParseExact: true, + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : 'dan', + dd : translate, + M : 'mjesec', + MM : translate, + y : 'godinu', + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/hu.js b/nodejs/node_modules/moment/src/locale/hu.js new file mode 100755 index 0000000..1e075de --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/hu.js @@ -0,0 +1,103 @@ +//! moment.js locale configuration +//! locale : Hungarian [hu] +//! author : Adam Brunner : https://github.com/adambrunner + +import moment from '../moment'; + +var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); +function translate(number, withoutSuffix, key, isFuture) { + var num = number, + suffix; + switch (key) { + case 's': + return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; + case 'ss': + return num + (isFuture || withoutSuffix) ? ' másodperc' : ' másodperce'; + case 'm': + return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'mm': + return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'h': + return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'hh': + return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'd': + return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'dd': + return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'M': + return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'MM': + return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'y': + return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); + case 'yy': + return num + (isFuture || withoutSuffix ? ' év' : ' éve'); + } + return ''; +} +function week(isFuture) { + return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; +} + +export default moment.defineLocale('hu', { + months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), + monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), + weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), + weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), + weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY. MMMM D.', + LLL : 'YYYY. MMMM D. H:mm', + LLLL : 'YYYY. MMMM D., dddd H:mm' + }, + meridiemParse: /de|du/i, + isPM: function (input) { + return input.charAt(1).toLowerCase() === 'u'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower === true ? 'de' : 'DE'; + } else { + return isLower === true ? 'du' : 'DU'; + } + }, + calendar : { + sameDay : '[ma] LT[-kor]', + nextDay : '[holnap] LT[-kor]', + nextWeek : function () { + return week.call(this, true); + }, + lastDay : '[tegnap] LT[-kor]', + lastWeek : function () { + return week.call(this, false); + }, + sameElse : 'L' + }, + relativeTime : { + future : '%s múlva', + past : '%s', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/hy-am.js b/nodejs/node_modules/moment/src/locale/hy-am.js new file mode 100755 index 0000000..1918a57 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/hy-am.js @@ -0,0 +1,87 @@ +//! moment.js locale configuration +//! locale : Armenian [hy-am] +//! author : Armendarabyan : https://github.com/armendarabyan + +import moment from '../moment'; + +export default moment.defineLocale('hy-am', { + months : { + format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'), + standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_') + }, + monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), + weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'), + weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY թ.', + LLL : 'D MMMM YYYY թ., HH:mm', + LLLL : 'dddd, D MMMM YYYY թ., HH:mm' + }, + calendar : { + sameDay: '[այսօր] LT', + nextDay: '[վաղը] LT', + lastDay: '[երեկ] LT', + nextWeek: function () { + return 'dddd [օրը ժամը] LT'; + }, + lastWeek: function () { + return '[անցած] dddd [օրը ժամը] LT'; + }, + sameElse: 'L' + }, + relativeTime : { + future : '%s հետո', + past : '%s առաջ', + s : 'մի քանի վայրկյան', + ss : '%d վայրկյան', + m : 'րոպե', + mm : '%d րոպե', + h : 'ժամ', + hh : '%d ժամ', + d : 'օր', + dd : '%d օր', + M : 'ամիս', + MM : '%d ամիս', + y : 'տարի', + yy : '%d տարի' + }, + meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, + isPM: function (input) { + return /^(ցերեկվա|երեկոյան)$/.test(input); + }, + meridiem : function (hour) { + if (hour < 4) { + return 'գիշերվա'; + } else if (hour < 12) { + return 'առավոտվա'; + } else if (hour < 17) { + return 'ցերեկվա'; + } else { + return 'երեկոյան'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, + ordinal: function (number, period) { + switch (period) { + case 'DDD': + case 'w': + case 'W': + case 'DDDo': + if (number === 1) { + return number + '-ին'; + } + return number + '-րդ'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/id.js b/nodejs/node_modules/moment/src/locale/id.js new file mode 100755 index 0000000..52b1ccc --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/id.js @@ -0,0 +1,74 @@ +//! moment.js locale configuration +//! locale : Indonesian [id] +//! author : Mohammad Satrio Utomo : https://github.com/tyok +//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan + +import moment from '../moment'; + +export default moment.defineLocale('id', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|siang|sore|malam/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'siang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sore' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'siang'; + } else if (hours < 19) { + return 'sore'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Besok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kemarin pukul] LT', + lastWeek : 'dddd [lalu pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lalu', + s : 'beberapa detik', + ss : '%d detik', + m : 'semenit', + mm : '%d menit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/is.js b/nodejs/node_modules/moment/src/locale/is.js new file mode 100755 index 0000000..51fb8e6 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/is.js @@ -0,0 +1,124 @@ +//! moment.js locale configuration +//! locale : Icelandic [is] +//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik + +import moment from '../moment'; + +function plural(n) { + if (n % 100 === 11) { + return true; + } else if (n % 10 === 1) { + return false; + } + return true; +} +function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; + case 'ss': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum'); + } + return result + 'sekúnda'; + case 'm': + return withoutSuffix ? 'mínúta' : 'mínútu'; + case 'mm': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); + } else if (withoutSuffix) { + return result + 'mínúta'; + } + return result + 'mínútu'; + case 'hh': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); + } + return result + 'klukkustund'; + case 'd': + if (withoutSuffix) { + return 'dagur'; + } + return isFuture ? 'dag' : 'degi'; + case 'dd': + if (plural(number)) { + if (withoutSuffix) { + return result + 'dagar'; + } + return result + (isFuture ? 'daga' : 'dögum'); + } else if (withoutSuffix) { + return result + 'dagur'; + } + return result + (isFuture ? 'dag' : 'degi'); + case 'M': + if (withoutSuffix) { + return 'mánuður'; + } + return isFuture ? 'mánuð' : 'mánuði'; + case 'MM': + if (plural(number)) { + if (withoutSuffix) { + return result + 'mánuðir'; + } + return result + (isFuture ? 'mánuði' : 'mánuðum'); + } else if (withoutSuffix) { + return result + 'mánuður'; + } + return result + (isFuture ? 'mánuð' : 'mánuði'); + case 'y': + return withoutSuffix || isFuture ? 'ár' : 'ári'; + case 'yy': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); + } + return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); + } +} + +export default moment.defineLocale('is', { + months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), + weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), + weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), + weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm' + }, + calendar : { + sameDay : '[í dag kl.] LT', + nextDay : '[á morgun kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[í gær kl.] LT', + lastWeek : '[síðasta] dddd [kl.] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'eftir %s', + past : 'fyrir %s síðan', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : 'klukkustund', + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/it.js b/nodejs/node_modules/moment/src/locale/it.js new file mode 100755 index 0000000..a7ce117 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/it.js @@ -0,0 +1,62 @@ +//! moment.js locale configuration +//! locale : Italian [it] +//! author : Lorenzo : https://github.com/aliem +//! author: Mattia Larentis: https://github.com/nostalgiaz + +import moment from '../moment'; + +export default moment.defineLocale('it', { + months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), + monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'), + weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'), + weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Oggi alle] LT', + nextDay: '[Domani alle] LT', + nextWeek: 'dddd [alle] LT', + lastDay: '[Ieri alle] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[la scorsa] dddd [alle] LT'; + default: + return '[lo scorso] dddd [alle] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : function (s) { + return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; + }, + past : '%s fa', + s : 'alcuni secondi', + ss : '%d secondi', + m : 'un minuto', + mm : '%d minuti', + h : 'un\'ora', + hh : '%d ore', + d : 'un giorno', + dd : '%d giorni', + M : 'un mese', + MM : '%d mesi', + y : 'un anno', + yy : '%d anni' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ja.js b/nodejs/node_modules/moment/src/locale/ja.js new file mode 100755 index 0000000..9812a73 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ja.js @@ -0,0 +1,84 @@ +//! moment.js locale configuration +//! locale : Japanese [ja] +//! author : LI Long : https://github.com/baryon + +import moment from '../moment'; + +export default moment.defineLocale('ja', { + months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), + weekdaysShort : '日_月_火_水_木_金_土'.split('_'), + weekdaysMin : '日_月_火_水_木_金_土'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日 dddd HH:mm', + l : 'YYYY/MM/DD', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日(ddd) HH:mm' + }, + meridiemParse: /午前|午後/i, + isPM : function (input) { + return input === '午後'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return '午前'; + } else { + return '午後'; + } + }, + calendar : { + sameDay : '[今日] LT', + nextDay : '[明日] LT', + nextWeek : function (now) { + if (now.week() < this.week()) { + return '[来週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + lastDay : '[昨日] LT', + lastWeek : function (now) { + if (this.week() < now.week()) { + return '[先週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + sameElse : 'L' + }, + dayOfMonthOrdinalParse : /\d{1,2}日/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + default: + return number; + } + }, + relativeTime : { + future : '%s後', + past : '%s前', + s : '数秒', + ss : '%d秒', + m : '1分', + mm : '%d分', + h : '1時間', + hh : '%d時間', + d : '1日', + dd : '%d日', + M : '1ヶ月', + MM : '%dヶ月', + y : '1年', + yy : '%d年' + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/jv.js b/nodejs/node_modules/moment/src/locale/jv.js new file mode 100755 index 0000000..31fc9ad --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/jv.js @@ -0,0 +1,74 @@ +//! moment.js locale configuration +//! locale : Javanese [jv] +//! author : Rony Lantip : https://github.com/lantip +//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa + +import moment from '../moment'; + +export default moment.defineLocale('jv', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), + weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /enjing|siyang|sonten|ndalu/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'enjing') { + return hour; + } else if (meridiem === 'siyang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sonten' || meridiem === 'ndalu') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'enjing'; + } else if (hours < 15) { + return 'siyang'; + } else if (hours < 19) { + return 'sonten'; + } else { + return 'ndalu'; + } + }, + calendar : { + sameDay : '[Dinten puniko pukul] LT', + nextDay : '[Mbenjang pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kala wingi pukul] LT', + lastWeek : 'dddd [kepengker pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'wonten ing %s', + past : '%s ingkang kepengker', + s : 'sawetawis detik', + ss : '%d detik', + m : 'setunggal menit', + mm : '%d menit', + h : 'setunggal jam', + hh : '%d jam', + d : 'sedinten', + dd : '%d dinten', + M : 'sewulan', + MM : '%d wulan', + y : 'setaun', + yy : '%d taun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/ka.js b/nodejs/node_modules/moment/src/locale/ka.js new file mode 100755 index 0000000..169734b --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ka.js @@ -0,0 +1,81 @@ +//! moment.js locale configuration +//! locale : Georgian [ka] +//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili + +import moment from '../moment'; + +export default moment.defineLocale('ka', { + months : { + standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), + format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') + }, + monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), + weekdays : { + standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), + format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'), + isFormat: /(წინა|შემდეგ)/ + }, + weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), + weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[დღეს] LT[-ზე]', + nextDay : '[ხვალ] LT[-ზე]', + lastDay : '[გუშინ] LT[-ზე]', + nextWeek : '[შემდეგ] dddd LT[-ზე]', + lastWeek : '[წინა] dddd LT-ზე', + sameElse : 'L' + }, + relativeTime : { + future : function (s) { + return (/(წამი|წუთი|საათი|წელი)/).test(s) ? + s.replace(/ი$/, 'ში') : + s + 'ში'; + }, + past : function (s) { + if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { + return s.replace(/(ი|ე)$/, 'ის წინ'); + } + if ((/წელი/).test(s)) { + return s.replace(/წელი$/, 'წლის წინ'); + } + }, + s : 'რამდენიმე წამი', + ss : '%d წამი', + m : 'წუთი', + mm : '%d წუთი', + h : 'საათი', + hh : '%d საათი', + d : 'დღე', + dd : '%d დღე', + M : 'თვე', + MM : '%d თვე', + y : 'წელი', + yy : '%d წელი' + }, + dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, + ordinal : function (number) { + if (number === 0) { + return number; + } + if (number === 1) { + return number + '-ლი'; + } + if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { + return 'მე-' + number; + } + return number + '-ე'; + }, + week : { + dow : 1, + doy : 7 + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/kk.js b/nodejs/node_modules/moment/src/locale/kk.js new file mode 100755 index 0000000..1917a9b --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/kk.js @@ -0,0 +1,78 @@ +//! moment.js locale configuration +//! locale : Kazakh [kk] +//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan + +import moment from '../moment'; + +var suffixes = { + 0: '-ші', + 1: '-ші', + 2: '-ші', + 3: '-ші', + 4: '-ші', + 5: '-ші', + 6: '-шы', + 7: '-ші', + 8: '-ші', + 9: '-шы', + 10: '-шы', + 20: '-шы', + 30: '-шы', + 40: '-шы', + 50: '-ші', + 60: '-шы', + 70: '-ші', + 80: '-ші', + 90: '-шы', + 100: '-ші' +}; + +export default moment.defineLocale('kk', { + months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'), + monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'), + weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'), + weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'), + weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Бүгін сағат] LT', + nextDay : '[Ертең сағат] LT', + nextWeek : 'dddd [сағат] LT', + lastDay : '[Кеше сағат] LT', + lastWeek : '[Өткен аптаның] dddd [сағат] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ішінде', + past : '%s бұрын', + s : 'бірнеше секунд', + ss : '%d секунд', + m : 'бір минут', + mm : '%d минут', + h : 'бір сағат', + hh : '%d сағат', + d : 'бір күн', + dd : '%d күн', + M : 'бір ай', + MM : '%d ай', + y : 'бір жыл', + yy : '%d жыл' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/km.js b/nodejs/node_modules/moment/src/locale/km.js new file mode 100755 index 0000000..b364ffe --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/km.js @@ -0,0 +1,101 @@ +//! moment.js locale configuration +//! locale : Cambodian [km] +//! author : Kruy Vanna : https://github.com/kruyvanna + +import moment from '../moment'; + +var symbolMap = { + '1': '១', + '2': '២', + '3': '៣', + '4': '៤', + '5': '៥', + '6': '៦', + '7': '៧', + '8': '៨', + '9': '៩', + '0': '០' +}, numberMap = { + '១': '1', + '២': '2', + '៣': '3', + '៤': '4', + '៥': '5', + '៦': '6', + '៧': '7', + '៨': '8', + '៩': '9', + '០': '0' +}; + +export default moment.defineLocale('km', { + months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysShort: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysMin: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /ព្រឹក|ល្ងាច/, + isPM: function (input) { + return input === 'ល្ងាច'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ព្រឹក'; + } else { + return 'ល្ងាច'; + } + }, + calendar: { + sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', + nextDay: '[ស្អែក ម៉ោង] LT', + nextWeek: 'dddd [ម៉ោង] LT', + lastDay: '[ម្សិលមិញ ម៉ោង] LT', + lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', + sameElse: 'L' + }, + relativeTime: { + future: '%sទៀត', + past: '%sមុន', + s: 'ប៉ុន្មានវិនាទី', + ss: '%d វិនាទី', + m: 'មួយនាទី', + mm: '%d នាទី', + h: 'មួយម៉ោង', + hh: '%d ម៉ោង', + d: 'មួយថ្ងៃ', + dd: '%d ថ្ងៃ', + M: 'មួយខែ', + MM: '%d ខែ', + y: 'មួយឆ្នាំ', + yy: '%d ឆ្នាំ' + }, + dayOfMonthOrdinalParse : /ទី\d{1,2}/, + ordinal : 'ទី%d', + preparse: function (string) { + return string.replace(/[១២៣៤៥៦៧៨៩០]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/kn.js b/nodejs/node_modules/moment/src/locale/kn.js new file mode 100755 index 0000000..d4b65e8 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/kn.js @@ -0,0 +1,117 @@ +//! moment.js locale configuration +//! locale : Kannada [kn] +//! author : Rajeev Naik : https://github.com/rajeevnaikte + +import moment from '../moment'; + +var symbolMap = { + '1': '೧', + '2': '೨', + '3': '೩', + '4': '೪', + '5': '೫', + '6': '೬', + '7': '೭', + '8': '೮', + '9': '೯', + '0': '೦' +}, +numberMap = { + '೧': '1', + '೨': '2', + '೩': '3', + '೪': '4', + '೫': '5', + '೬': '6', + '೭': '7', + '೮': '8', + '೯': '9', + '೦': '0' +}; + +export default moment.defineLocale('kn', { + months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'), + monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ'.split('_'), + monthsParseExact: true, + weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'), + weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'), + weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[ಇಂದು] LT', + nextDay : '[ನಾಳೆ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ನಿನ್ನೆ] LT', + lastWeek : '[ಕೊನೆಯ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ನಂತರ', + past : '%s ಹಿಂದೆ', + s : 'ಕೆಲವು ಕ್ಷಣಗಳು', + ss : '%d ಸೆಕೆಂಡುಗಳು', + m : 'ಒಂದು ನಿಮಿಷ', + mm : '%d ನಿಮಿಷ', + h : 'ಒಂದು ಗಂಟೆ', + hh : '%d ಗಂಟೆ', + d : 'ಒಂದು ದಿನ', + dd : '%d ದಿನ', + M : 'ಒಂದು ತಿಂಗಳು', + MM : '%d ತಿಂಗಳು', + y : 'ಒಂದು ವರ್ಷ', + yy : '%d ವರ್ಷ' + }, + preparse: function (string) { + return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ರಾತ್ರಿ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') { + return hour; + } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ಸಂಜೆ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ರಾತ್ರಿ'; + } else if (hour < 10) { + return 'ಬೆಳಿಗ್ಗೆ'; + } else if (hour < 17) { + return 'ಮಧ್ಯಾಹ್ನ'; + } else if (hour < 20) { + return 'ಸಂಜೆ'; + } else { + return 'ರಾತ್ರಿ'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/, + ordinal : function (number) { + return number + 'ನೇ'; + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/ko.js b/nodejs/node_modules/moment/src/locale/ko.js new file mode 100755 index 0000000..d2da13d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ko.js @@ -0,0 +1,74 @@ +//! moment.js locale configuration +//! locale : Korean [ko] +//! author : Kyungwook, Park : https://github.com/kyungw00k +//! author : Jeeeyul Lee + +import moment from '../moment'; + +export default moment.defineLocale('ko', { + months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), + weekdaysShort : '일_월_화_수_목_금_토'.split('_'), + weekdaysMin : '일_월_화_수_목_금_토'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY년 MMMM D일', + LLL : 'YYYY년 MMMM D일 A h:mm', + LLLL : 'YYYY년 MMMM D일 dddd A h:mm', + l : 'YYYY.MM.DD.', + ll : 'YYYY년 MMMM D일', + lll : 'YYYY년 MMMM D일 A h:mm', + llll : 'YYYY년 MMMM D일 dddd A h:mm' + }, + calendar : { + sameDay : '오늘 LT', + nextDay : '내일 LT', + nextWeek : 'dddd LT', + lastDay : '어제 LT', + lastWeek : '지난주 dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s 후', + past : '%s 전', + s : '몇 초', + ss : '%d초', + m : '1분', + mm : '%d분', + h : '한 시간', + hh : '%d시간', + d : '하루', + dd : '%d일', + M : '한 달', + MM : '%d달', + y : '일 년', + yy : '%d년' + }, + dayOfMonthOrdinalParse : /\d{1,2}(일|월|주)/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '일'; + case 'M': + return number + '월'; + case 'w': + case 'W': + return number + '주'; + default: + return number; + } + }, + meridiemParse : /오전|오후/, + isPM : function (token) { + return token === '오후'; + }, + meridiem : function (hour, minute, isUpper) { + return hour < 12 ? '오전' : '오후'; + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ky.js b/nodejs/node_modules/moment/src/locale/ky.js new file mode 100755 index 0000000..aa7f1b2 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ky.js @@ -0,0 +1,79 @@ +//! moment.js locale configuration +//! locale : Kyrgyz [ky] +//! author : Chyngyz Arystan uulu : https://github.com/chyngyz + + +import moment from '../moment'; + +var suffixes = { + 0: '-чү', + 1: '-чи', + 2: '-чи', + 3: '-чү', + 4: '-чү', + 5: '-чи', + 6: '-чы', + 7: '-чи', + 8: '-чи', + 9: '-чу', + 10: '-чу', + 20: '-чы', + 30: '-чу', + 40: '-чы', + 50: '-чү', + 60: '-чы', + 70: '-чи', + 80: '-чи', + 90: '-чу', + 100: '-чү' +}; + +export default moment.defineLocale('ky', { + months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), + monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'), + weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'), + weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Бүгүн саат] LT', + nextDay : '[Эртең саат] LT', + nextWeek : 'dddd [саат] LT', + lastDay : '[Кече саат] LT', + lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ичинде', + past : '%s мурун', + s : 'бирнече секунд', + ss : '%d секунд', + m : 'бир мүнөт', + mm : '%d мүнөт', + h : 'бир саат', + hh : '%d саат', + d : 'бир күн', + dd : '%d күн', + M : 'бир ай', + MM : '%d ай', + y : 'бир жыл', + yy : '%d жыл' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/lb.js b/nodejs/node_modules/moment/src/locale/lb.js new file mode 100755 index 0000000..8574277 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/lb.js @@ -0,0 +1,129 @@ +//! moment.js locale configuration +//! locale : Luxembourgish [lb] +//! author : mweimerskirch : https://github.com/mweimerskirch +//! author : David Raison : https://github.com/kwisatz + +import moment from '../moment'; + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eng Minutt', 'enger Minutt'], + 'h': ['eng Stonn', 'enger Stonn'], + 'd': ['een Dag', 'engem Dag'], + 'M': ['ee Mount', 'engem Mount'], + 'y': ['ee Joer', 'engem Joer'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; +} +function processFutureTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'a ' + string; + } + return 'an ' + string; +} +function processPastTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'viru ' + string; + } + return 'virun ' + string; +} +/** + * Returns true if the word before the given number loses the '-n' ending. + * e.g. 'an 10 Deeg' but 'a 5 Deeg' + * + * @param number {integer} + * @returns {boolean} + */ +function eifelerRegelAppliesToNumber(number) { + number = parseInt(number, 10); + if (isNaN(number)) { + return false; + } + if (number < 0) { + // Negative Number --> always true + return true; + } else if (number < 10) { + // Only 1 digit + if (4 <= number && number <= 7) { + return true; + } + return false; + } else if (number < 100) { + // 2 digits + var lastDigit = number % 10, firstDigit = number / 10; + if (lastDigit === 0) { + return eifelerRegelAppliesToNumber(firstDigit); + } + return eifelerRegelAppliesToNumber(lastDigit); + } else if (number < 10000) { + // 3 or 4 digits --> recursively check first digit + while (number >= 10) { + number = number / 10; + } + return eifelerRegelAppliesToNumber(number); + } else { + // Anything larger than 4 digits: recursively check first n-3 digits + number = number / 1000; + return eifelerRegelAppliesToNumber(number); + } +} + +export default moment.defineLocale('lb', { + months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), + weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm [Auer]', + LTS: 'H:mm:ss [Auer]', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm [Auer]', + LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]' + }, + calendar: { + sameDay: '[Haut um] LT', + sameElse: 'L', + nextDay: '[Muer um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gëschter um] LT', + lastWeek: function () { + // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule + switch (this.day()) { + case 2: + case 4: + return '[Leschten] dddd [um] LT'; + default: + return '[Leschte] dddd [um] LT'; + } + } + }, + relativeTime : { + future : processFutureTime, + past : processPastTime, + s : 'e puer Sekonnen', + ss : '%d Sekonnen', + m : processRelativeTime, + mm : '%d Minutten', + h : processRelativeTime, + hh : '%d Stonnen', + d : processRelativeTime, + dd : '%d Deeg', + M : processRelativeTime, + MM : '%d Méint', + y : processRelativeTime, + yy : '%d Joer' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/lo.js b/nodejs/node_modules/moment/src/locale/lo.js new file mode 100755 index 0000000..3226dd5 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/lo.js @@ -0,0 +1,62 @@ +//! moment.js locale configuration +//! locale : Lao [lo] +//! author : Ryan Hart : https://github.com/ryanhart2 + +import moment from '../moment'; + +export default moment.defineLocale('lo', { + months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'ວັນdddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, + isPM: function (input) { + return input === 'ຕອນແລງ'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ຕອນເຊົ້າ'; + } else { + return 'ຕອນແລງ'; + } + }, + calendar : { + sameDay : '[ມື້ນີ້ເວລາ] LT', + nextDay : '[ມື້ອື່ນເວລາ] LT', + nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT', + lastDay : '[ມື້ວານນີ້ເວລາ] LT', + lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ອີກ %s', + past : '%sຜ່ານມາ', + s : 'ບໍ່ເທົ່າໃດວິນາທີ', + ss : '%d ວິນາທີ' , + m : '1 ນາທີ', + mm : '%d ນາທີ', + h : '1 ຊົ່ວໂມງ', + hh : '%d ຊົ່ວໂມງ', + d : '1 ມື້', + dd : '%d ມື້', + M : '1 ເດືອນ', + MM : '%d ເດືອນ', + y : '1 ປີ', + yy : '%d ປີ' + }, + dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/, + ordinal : function (number) { + return 'ທີ່' + number; + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/lt.js b/nodejs/node_modules/moment/src/locale/lt.js new file mode 100755 index 0000000..d006e07 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/lt.js @@ -0,0 +1,110 @@ +//! moment.js locale configuration +//! locale : Lithuanian [lt] +//! author : Mindaugas Mozūras : https://github.com/mmozuras + +import moment from '../moment'; + +var units = { + 'ss' : 'sekundė_sekundžių_sekundes', + 'm' : 'minutė_minutės_minutę', + 'mm': 'minutės_minučių_minutes', + 'h' : 'valanda_valandos_valandą', + 'hh': 'valandos_valandų_valandas', + 'd' : 'diena_dienos_dieną', + 'dd': 'dienos_dienų_dienas', + 'M' : 'mėnuo_mėnesio_mėnesį', + 'MM': 'mėnesiai_mėnesių_mėnesius', + 'y' : 'metai_metų_metus', + 'yy': 'metai_metų_metus' +}; +function translateSeconds(number, withoutSuffix, key, isFuture) { + if (withoutSuffix) { + return 'kelios sekundės'; + } else { + return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; + } +} +function translateSingular(number, withoutSuffix, key, isFuture) { + return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); +} +function special(number) { + return number % 10 === 0 || (number > 10 && number < 20); +} +function forms(key) { + return units[key].split('_'); +} +function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + if (number === 1) { + return result + translateSingular(number, withoutSuffix, key[0], isFuture); + } else if (withoutSuffix) { + return result + (special(number) ? forms(key)[1] : forms(key)[0]); + } else { + if (isFuture) { + return result + forms(key)[1]; + } else { + return result + (special(number) ? forms(key)[1] : forms(key)[2]); + } + } +} +export default moment.defineLocale('lt', { + months : { + format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), + standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'), + isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/ + }, + monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), + weekdays : { + format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'), + standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'), + isFormat: /dddd HH:mm/ + }, + weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), + weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY [m.] MMMM D [d.]', + LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', + l : 'YYYY-MM-DD', + ll : 'YYYY [m.] MMMM D [d.]', + lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]' + }, + calendar : { + sameDay : '[Šiandien] LT', + nextDay : '[Rytoj] LT', + nextWeek : 'dddd LT', + lastDay : '[Vakar] LT', + lastWeek : '[Praėjusį] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'po %s', + past : 'prieš %s', + s : translateSeconds, + ss : translate, + m : translateSingular, + mm : translate, + h : translateSingular, + hh : translate, + d : translateSingular, + dd : translate, + M : translateSingular, + MM : translate, + y : translateSingular, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}-oji/, + ordinal : function (number) { + return number + '-oji'; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/lv.js b/nodejs/node_modules/moment/src/locale/lv.js new file mode 100755 index 0000000..d13b47b --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/lv.js @@ -0,0 +1,90 @@ +//! moment.js locale configuration +//! locale : Latvian [lv] +//! author : Kristaps Karlsons : https://github.com/skakri +//! author : Jānis Elmeris : https://github.com/JanisE + +import moment from '../moment'; + +var units = { + 'ss': 'sekundes_sekundēm_sekunde_sekundes'.split('_'), + 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'h': 'stundas_stundām_stunda_stundas'.split('_'), + 'hh': 'stundas_stundām_stunda_stundas'.split('_'), + 'd': 'dienas_dienām_diena_dienas'.split('_'), + 'dd': 'dienas_dienām_diena_dienas'.split('_'), + 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'y': 'gada_gadiem_gads_gadi'.split('_'), + 'yy': 'gada_gadiem_gads_gadi'.split('_') +}; +/** + * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. + */ +function format(forms, number, withoutSuffix) { + if (withoutSuffix) { + // E.g. "21 minūte", "3 minūtes". + return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3]; + } else { + // E.g. "21 minūtes" as in "pēc 21 minūtes". + // E.g. "3 minūtēm" as in "pēc 3 minūtēm". + return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1]; + } +} +function relativeTimeWithPlural(number, withoutSuffix, key) { + return number + ' ' + format(units[key], number, withoutSuffix); +} +function relativeTimeWithSingular(number, withoutSuffix, key) { + return format(units[key], number, withoutSuffix); +} +function relativeSeconds(number, withoutSuffix) { + return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; +} + +export default moment.defineLocale('lv', { + months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), + weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY.', + LL : 'YYYY. [gada] D. MMMM', + LLL : 'YYYY. [gada] D. MMMM, HH:mm', + LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm' + }, + calendar : { + sameDay : '[Šodien pulksten] LT', + nextDay : '[Rīt pulksten] LT', + nextWeek : 'dddd [pulksten] LT', + lastDay : '[Vakar pulksten] LT', + lastWeek : '[Pagājušā] dddd [pulksten] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'pēc %s', + past : 'pirms %s', + s : relativeSeconds, + ss : relativeTimeWithPlural, + m : relativeTimeWithSingular, + mm : relativeTimeWithPlural, + h : relativeTimeWithSingular, + hh : relativeTimeWithPlural, + d : relativeTimeWithSingular, + dd : relativeTimeWithPlural, + M : relativeTimeWithSingular, + MM : relativeTimeWithPlural, + y : relativeTimeWithSingular, + yy : relativeTimeWithPlural + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/me.js b/nodejs/node_modules/moment/src/locale/me.js new file mode 100755 index 0000000..120c997 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/me.js @@ -0,0 +1,103 @@ +//! moment.js locale configuration +//! locale : Montenegrin [me] +//! author : Miodrag Nikač : https://github.com/miodragnikac + +import moment from '../moment'; + +var translator = { + words: { //Different grammatical cases + ss: ['sekund', 'sekunda', 'sekundi'], + m: ['jedan minut', 'jednog minuta'], + mm: ['minut', 'minuta', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mjesec', 'mjeseca', 'mjeseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } +}; + +export default moment.defineLocale('me', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact : true, + weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sjutra u] LT', + + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedjelje] [u] LT', + '[prošlog] [ponedjeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srijede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'nekoliko sekundi', + ss : translator.translate, + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : 'dan', + dd : translator.translate, + M : 'mjesec', + MM : translator.translate, + y : 'godinu', + yy : translator.translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/mi.js b/nodejs/node_modules/moment/src/locale/mi.js new file mode 100755 index 0000000..0c105e5 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/mi.js @@ -0,0 +1,55 @@ +//! moment.js locale configuration +//! locale : Maori [mi] +//! author : John Corrigan : https://github.com/johnideal + +import moment from '../moment'; + +export default moment.defineLocale('mi', { + months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'), + monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'), + monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i, + weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'), + weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [i] HH:mm', + LLLL: 'dddd, D MMMM YYYY [i] HH:mm' + }, + calendar: { + sameDay: '[i teie mahana, i] LT', + nextDay: '[apopo i] LT', + nextWeek: 'dddd [i] LT', + lastDay: '[inanahi i] LT', + lastWeek: 'dddd [whakamutunga i] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'i roto i %s', + past: '%s i mua', + s: 'te hēkona ruarua', + ss: '%d hēkona', + m: 'he meneti', + mm: '%d meneti', + h: 'te haora', + hh: '%d haora', + d: 'he ra', + dd: '%d ra', + M: 'he marama', + MM: '%d marama', + y: 'he tau', + yy: '%d tau' + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/mk.js b/nodejs/node_modules/moment/src/locale/mk.js new file mode 100755 index 0000000..6d6e0b4 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/mk.js @@ -0,0 +1,82 @@ +//! moment.js locale configuration +//! locale : Macedonian [mk] +//! author : Borislav Mickov : https://github.com/B0k0 + +import moment from '../moment'; + +export default moment.defineLocale('mk', { + months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), + weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), + weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Денес во] LT', + nextDay : '[Утре во] LT', + nextWeek : '[Во] dddd [во] LT', + lastDay : '[Вчера во] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[Изминатата] dddd [во] LT'; + case 1: + case 2: + case 4: + case 5: + return '[Изминатиот] dddd [во] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'после %s', + past : 'пред %s', + s : 'неколку секунди', + ss : '%d секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дена', + M : 'месец', + MM : '%d месеци', + y : 'година', + yy : '%d години' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ml.js b/nodejs/node_modules/moment/src/locale/ml.js new file mode 100755 index 0000000..306566d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ml.js @@ -0,0 +1,73 @@ +//! moment.js locale configuration +//! locale : Malayalam [ml] +//! author : Floyd Pink : https://github.com/floydpink + +import moment from '../moment'; + +export default moment.defineLocale('ml', { + months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), + monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), + monthsParseExact : true, + weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), + weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), + weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), + longDateFormat : { + LT : 'A h:mm -നു', + LTS : 'A h:mm:ss -നു', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm -നു', + LLLL : 'dddd, D MMMM YYYY, A h:mm -നു' + }, + calendar : { + sameDay : '[ഇന്ന്] LT', + nextDay : '[നാളെ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ഇന്നലെ] LT', + lastWeek : '[കഴിഞ്ഞ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s കഴിഞ്ഞ്', + past : '%s മുൻപ്', + s : 'അൽപ നിമിഷങ്ങൾ', + ss : '%d സെക്കൻഡ്', + m : 'ഒരു മിനിറ്റ്', + mm : '%d മിനിറ്റ്', + h : 'ഒരു മണിക്കൂർ', + hh : '%d മണിക്കൂർ', + d : 'ഒരു ദിവസം', + dd : '%d ദിവസം', + M : 'ഒരു മാസം', + MM : '%d മാസം', + y : 'ഒരു വർഷം', + yy : '%d വർഷം' + }, + meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'രാത്രി' && hour >= 4) || + meridiem === 'ഉച്ച കഴിഞ്ഞ്' || + meridiem === 'വൈകുന്നേരം') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'രാത്രി'; + } else if (hour < 12) { + return 'രാവിലെ'; + } else if (hour < 17) { + return 'ഉച്ച കഴിഞ്ഞ്'; + } else if (hour < 20) { + return 'വൈകുന്നേരം'; + } else { + return 'രാത്രി'; + } + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/mn.js b/nodejs/node_modules/moment/src/locale/mn.js new file mode 100755 index 0000000..80a3c2f --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/mn.js @@ -0,0 +1,96 @@ +//! moment.js locale configuration +//! locale : Mongolian [mn] +//! author : Javkhlantugs Nyamdorj : https://github.com/javkhaanj7 + +import moment from '../moment'; + +function translate(number, withoutSuffix, key, isFuture) { + switch (key) { + case 's': + return withoutSuffix ? 'хэдхэн секунд' : 'хэдхэн секундын'; + case 'ss': + return number + (withoutSuffix ? ' секунд' : ' секундын'); + case 'm': + case 'mm': + return number + (withoutSuffix ? ' минут' : ' минутын'); + case 'h': + case 'hh': + return number + (withoutSuffix ? ' цаг' : ' цагийн'); + case 'd': + case 'dd': + return number + (withoutSuffix ? ' өдөр' : ' өдрийн'); + case 'M': + case 'MM': + return number + (withoutSuffix ? ' сар' : ' сарын'); + case 'y': + case 'yy': + return number + (withoutSuffix ? ' жил' : ' жилийн'); + default: + return number; + } +} + +export default moment.defineLocale('mn', { + months : 'Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар'.split('_'), + monthsShort : '1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар'.split('_'), + monthsParseExact : true, + weekdays : 'Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба'.split('_'), + weekdaysShort : 'Ням_Дав_Мяг_Лха_Пүр_Баа_Бям'.split('_'), + weekdaysMin : 'Ня_Да_Мя_Лх_Пү_Ба_Бя'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY оны MMMMын D', + LLL : 'YYYY оны MMMMын D HH:mm', + LLLL : 'dddd, YYYY оны MMMMын D HH:mm' + }, + meridiemParse: /ҮӨ|ҮХ/i, + isPM : function (input) { + return input === 'ҮХ'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ҮӨ'; + } else { + return 'ҮХ'; + } + }, + calendar : { + sameDay : '[Өнөөдөр] LT', + nextDay : '[Маргааш] LT', + nextWeek : '[Ирэх] dddd LT', + lastDay : '[Өчигдөр] LT', + lastWeek : '[Өнгөрсөн] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s дараа', + past : '%s өмнө', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2} өдөр/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + ' өдөр'; + default: + return number; + } + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/mr.js b/nodejs/node_modules/moment/src/locale/mr.js new file mode 100755 index 0000000..415644a --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/mr.js @@ -0,0 +1,153 @@ +//! moment.js locale configuration +//! locale : Marathi [mr] +//! author : Harshad Kale : https://github.com/kalehv +//! author : Vivek Athalye : https://github.com/vnathalye + +import moment from '../moment'; + +var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' +}, +numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' +}; + +function relativeTimeMr(number, withoutSuffix, string, isFuture) +{ + var output = ''; + if (withoutSuffix) { + switch (string) { + case 's': output = 'काही सेकंद'; break; + case 'ss': output = '%d सेकंद'; break; + case 'm': output = 'एक मिनिट'; break; + case 'mm': output = '%d मिनिटे'; break; + case 'h': output = 'एक तास'; break; + case 'hh': output = '%d तास'; break; + case 'd': output = 'एक दिवस'; break; + case 'dd': output = '%d दिवस'; break; + case 'M': output = 'एक महिना'; break; + case 'MM': output = '%d महिने'; break; + case 'y': output = 'एक वर्ष'; break; + case 'yy': output = '%d वर्षे'; break; + } + } + else { + switch (string) { + case 's': output = 'काही सेकंदां'; break; + case 'ss': output = '%d सेकंदां'; break; + case 'm': output = 'एका मिनिटा'; break; + case 'mm': output = '%d मिनिटां'; break; + case 'h': output = 'एका तासा'; break; + case 'hh': output = '%d तासां'; break; + case 'd': output = 'एका दिवसा'; break; + case 'dd': output = '%d दिवसां'; break; + case 'M': output = 'एका महिन्या'; break; + case 'MM': output = '%d महिन्यां'; break; + case 'y': output = 'एका वर्षा'; break; + case 'yy': output = '%d वर्षां'; break; + } + } + return output.replace(/%d/i, number); +} + +export default moment.defineLocale('mr', { + months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), + monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), + monthsParseExact : true, + weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat : { + LT : 'A h:mm वाजता', + LTS : 'A h:mm:ss वाजता', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm वाजता', + LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता' + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[उद्या] LT', + nextWeek : 'dddd, LT', + lastDay : '[काल] LT', + lastWeek: '[मागील] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future: '%sमध्ये', + past: '%sपूर्वी', + s: relativeTimeMr, + ss: relativeTimeMr, + m: relativeTimeMr, + mm: relativeTimeMr, + h: relativeTimeMr, + hh: relativeTimeMr, + d: relativeTimeMr, + dd: relativeTimeMr, + M: relativeTimeMr, + MM: relativeTimeMr, + y: relativeTimeMr, + yy: relativeTimeMr + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात्री') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सकाळी') { + return hour; + } else if (meridiem === 'दुपारी') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'सायंकाळी') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'रात्री'; + } else if (hour < 10) { + return 'सकाळी'; + } else if (hour < 17) { + return 'दुपारी'; + } else if (hour < 20) { + return 'सायंकाळी'; + } else { + return 'रात्री'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ms-my.js b/nodejs/node_modules/moment/src/locale/ms-my.js new file mode 100755 index 0000000..03fcaa9 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ms-my.js @@ -0,0 +1,75 @@ +//! moment.js locale configuration +//! locale : Malay [ms-my] +//! note : DEPRECATED, the correct one is [ms] +//! author : Weldan Jamili : https://github.com/weldan + +import moment from '../moment'; + +export default moment.defineLocale('ms-my', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + ss : '%d saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ms.js b/nodejs/node_modules/moment/src/locale/ms.js new file mode 100755 index 0000000..9f69147 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ms.js @@ -0,0 +1,74 @@ +//! moment.js locale configuration +//! locale : Malay [ms] +//! author : Weldan Jamili : https://github.com/weldan + +import moment from '../moment'; + +export default moment.defineLocale('ms', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + ss : '%d saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/mt.js b/nodejs/node_modules/moment/src/locale/mt.js new file mode 100755 index 0000000..4953fa2 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/mt.js @@ -0,0 +1,51 @@ +//! moment.js locale configuration +//! locale : Maltese (Malta) [mt] +//! author : Alessandro Maruccia : https://github.com/alesma + +import moment from '../moment'; + +export default moment.defineLocale('mt', { + months : 'Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru'.split('_'), + monthsShort : 'Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ'.split('_'), + weekdays : 'Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt'.split('_'), + weekdaysShort : 'Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib'.split('_'), + weekdaysMin : 'Ħa_Tn_Tl_Er_Ħa_Ġi_Si'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Illum fil-]LT', + nextDay : '[Għada fil-]LT', + nextWeek : 'dddd [fil-]LT', + lastDay : '[Il-bieraħ fil-]LT', + lastWeek : 'dddd [li għadda] [fil-]LT', + sameElse : 'L' + }, + relativeTime : { + future : 'f’ %s', + past : '%s ilu', + s : 'ftit sekondi', + ss : '%d sekondi', + m : 'minuta', + mm : '%d minuti', + h : 'siegħa', + hh : '%d siegħat', + d : 'ġurnata', + dd : '%d ġranet', + M : 'xahar', + MM : '%d xhur', + y : 'sena', + yy : '%d sni' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/my.js b/nodejs/node_modules/moment/src/locale/my.js new file mode 100755 index 0000000..7e98f7f --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/my.js @@ -0,0 +1,87 @@ +//! moment.js locale configuration +//! locale : Burmese [my] +//! author : Squar team, mysquar.com +//! author : David Rossellat : https://github.com/gholadr +//! author : Tin Aung Lin : https://github.com/thanyawzinmin + +import moment from '../moment'; + +var symbolMap = { + '1': '၁', + '2': '၂', + '3': '၃', + '4': '၄', + '5': '၅', + '6': '၆', + '7': '၇', + '8': '၈', + '9': '၉', + '0': '၀' +}, numberMap = { + '၁': '1', + '၂': '2', + '၃': '3', + '၄': '4', + '၅': '5', + '၆': '6', + '၇': '7', + '၈': '8', + '၉': '9', + '၀': '0' +}; + +export default moment.defineLocale('my', { + months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), + monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), + weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), + weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[ယနေ.] LT [မှာ]', + nextDay: '[မနက်ဖြန်] LT [မှာ]', + nextWeek: 'dddd LT [မှာ]', + lastDay: '[မနေ.က] LT [မှာ]', + lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', + sameElse: 'L' + }, + relativeTime: { + future: 'လာမည့် %s မှာ', + past: 'လွန်ခဲ့သော %s က', + s: 'စက္ကန်.အနည်းငယ်', + ss : '%d စက္ကန့်', + m: 'တစ်မိနစ်', + mm: '%d မိနစ်', + h: 'တစ်နာရီ', + hh: '%d နာရီ', + d: 'တစ်ရက်', + dd: '%d ရက်', + M: 'တစ်လ', + MM: '%d လ', + y: 'တစ်နှစ်', + yy: '%d နှစ်' + }, + preparse: function (string) { + return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/nb.js b/nodejs/node_modules/moment/src/locale/nb.js new file mode 100755 index 0000000..27bb88e --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/nb.js @@ -0,0 +1,55 @@ +//! moment.js locale configuration +//! locale : Norwegian Bokmål [nb] +//! authors : Espen Hovlandsdal : https://github.com/rexxars +//! Sigurd Gartmann : https://github.com/sigurdga + +import moment from '../moment'; + +export default moment.defineLocale('nb', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), + monthsParseExact : true, + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay: '[i dag kl.] LT', + nextDay: '[i morgen kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[i går kl.] LT', + lastWeek: '[forrige] dddd [kl.] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s siden', + s : 'noen sekunder', + ss : '%d sekunder', + m : 'ett minutt', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dager', + M : 'en måned', + MM : '%d måneder', + y : 'ett år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ne.js b/nodejs/node_modules/moment/src/locale/ne.js new file mode 100755 index 0000000..841198d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ne.js @@ -0,0 +1,115 @@ +//! moment.js locale configuration +//! locale : Nepalese [ne] +//! author : suvash : https://github.com/suvash + +import moment from '../moment'; + +var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' +}, +numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' +}; + +export default moment.defineLocale('ne', { + months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), + monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), + monthsParseExact : true, + weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), + weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), + weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'Aको h:mm बजे', + LTS : 'Aको h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, Aको h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /राति|बिहान|दिउँसो|साँझ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'राति') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'बिहान') { + return hour; + } else if (meridiem === 'दिउँसो') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'साँझ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 3) { + return 'राति'; + } else if (hour < 12) { + return 'बिहान'; + } else if (hour < 16) { + return 'दिउँसो'; + } else if (hour < 20) { + return 'साँझ'; + } else { + return 'राति'; + } + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[भोलि] LT', + nextWeek : '[आउँदो] dddd[,] LT', + lastDay : '[हिजो] LT', + lastWeek : '[गएको] dddd[,] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%sमा', + past : '%s अगाडि', + s : 'केही क्षण', + ss : '%d सेकेण्ड', + m : 'एक मिनेट', + mm : '%d मिनेट', + h : 'एक घण्टा', + hh : '%d घण्टा', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महिना', + MM : '%d महिना', + y : 'एक बर्ष', + yy : '%d बर्ष' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/nl-be.js b/nodejs/node_modules/moment/src/locale/nl-be.js new file mode 100755 index 0000000..d7a8d54 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/nl-be.js @@ -0,0 +1,80 @@ +//! moment.js locale configuration +//! locale : Dutch (Belgium) [nl-be] +//! author : Joris Röling : https://github.com/jorisroling +//! author : Jacob Middag : https://github.com/middagj + +import moment from '../moment'; + +var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); + +var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; +var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; + +export default moment.defineLocale('nl-be', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + ss : '%d seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/nl.js b/nodejs/node_modules/moment/src/locale/nl.js new file mode 100755 index 0000000..70c9837 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/nl.js @@ -0,0 +1,80 @@ +//! moment.js locale configuration +//! locale : Dutch [nl] +//! author : Joris Röling : https://github.com/jorisroling +//! author : Jacob Middag : https://github.com/middagj + +import moment from '../moment'; + +var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); + +var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; +var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; + +export default moment.defineLocale('nl', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + ss : '%d seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/nn.js b/nodejs/node_modules/moment/src/locale/nn.js new file mode 100755 index 0000000..ea8ca7b --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/nn.js @@ -0,0 +1,52 @@ +//! moment.js locale configuration +//! locale : Nynorsk [nn] +//! author : https://github.com/mechuwind + +import moment from '../moment'; + +export default moment.defineLocale('nn', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), + weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), + weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay: '[I dag klokka] LT', + nextDay: '[I morgon klokka] LT', + nextWeek: 'dddd [klokka] LT', + lastDay: '[I går klokka] LT', + lastWeek: '[Føregåande] dddd [klokka] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s sidan', + s : 'nokre sekund', + ss : '%d sekund', + m : 'eit minutt', + mm : '%d minutt', + h : 'ein time', + hh : '%d timar', + d : 'ein dag', + dd : '%d dagar', + M : 'ein månad', + MM : '%d månader', + y : 'eit år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/pa-in.js b/nodejs/node_modules/moment/src/locale/pa-in.js new file mode 100755 index 0000000..6b85350 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/pa-in.js @@ -0,0 +1,116 @@ +//! moment.js locale configuration +//! locale : Punjabi (India) [pa-in] +//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit + +import moment from '../moment'; + +var symbolMap = { + '1': '੧', + '2': '੨', + '3': '੩', + '4': '੪', + '5': '੫', + '6': '੬', + '7': '੭', + '8': '੮', + '9': '੯', + '0': '੦' +}, +numberMap = { + '੧': '1', + '੨': '2', + '੩': '3', + '੪': '4', + '੫': '5', + '੬': '6', + '੭': '7', + '੮': '8', + '੯': '9', + '੦': '0' +}; + +export default moment.defineLocale('pa-in', { + // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi. + months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'), + weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + longDateFormat : { + LT : 'A h:mm ਵਜੇ', + LTS : 'A h:mm:ss ਵਜੇ', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm ਵਜੇ', + LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ' + }, + calendar : { + sameDay : '[ਅਜ] LT', + nextDay : '[ਕਲ] LT', + nextWeek : '[ਅਗਲਾ] dddd, LT', + lastDay : '[ਕਲ] LT', + lastWeek : '[ਪਿਛਲੇ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ਵਿੱਚ', + past : '%s ਪਿਛਲੇ', + s : 'ਕੁਝ ਸਕਿੰਟ', + ss : '%d ਸਕਿੰਟ', + m : 'ਇਕ ਮਿੰਟ', + mm : '%d ਮਿੰਟ', + h : 'ਇੱਕ ਘੰਟਾ', + hh : '%d ਘੰਟੇ', + d : 'ਇੱਕ ਦਿਨ', + dd : '%d ਦਿਨ', + M : 'ਇੱਕ ਮਹੀਨਾ', + MM : '%d ਮਹੀਨੇ', + y : 'ਇੱਕ ਸਾਲ', + yy : '%d ਸਾਲ' + }, + preparse: function (string) { + return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Punjabi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi. + meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ਰਾਤ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ਸਵੇਰ') { + return hour; + } else if (meridiem === 'ਦੁਪਹਿਰ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ਸ਼ਾਮ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ਰਾਤ'; + } else if (hour < 10) { + return 'ਸਵੇਰ'; + } else if (hour < 17) { + return 'ਦੁਪਹਿਰ'; + } else if (hour < 20) { + return 'ਸ਼ਾਮ'; + } else { + return 'ਰਾਤ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/pl.js b/nodejs/node_modules/moment/src/locale/pl.js new file mode 100755 index 0000000..4a46277 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/pl.js @@ -0,0 +1,117 @@ +//! moment.js locale configuration +//! locale : Polish [pl] +//! author : Rafal Hirsz : https://github.com/evoL + +import moment from '../moment'; + +var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), + monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); +function plural(n) { + return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); +} +function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + return result + (plural(number) ? 'sekundy' : 'sekund'); + case 'm': + return withoutSuffix ? 'minuta' : 'minutę'; + case 'mm': + return result + (plural(number) ? 'minuty' : 'minut'); + case 'h': + return withoutSuffix ? 'godzina' : 'godzinę'; + case 'hh': + return result + (plural(number) ? 'godziny' : 'godzin'); + case 'MM': + return result + (plural(number) ? 'miesiące' : 'miesięcy'); + case 'yy': + return result + (plural(number) ? 'lata' : 'lat'); + } +} + +export default moment.defineLocale('pl', { + months : function (momentToFormat, format) { + if (!momentToFormat) { + return monthsNominative; + } else if (format === '') { + // Hack: if format empty we know this is used to generate + // RegExp by moment. Give then back both valid forms of months + // in RegExp ready format. + return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')'; + } else if (/D MMMM/.test(format)) { + return monthsSubjective[momentToFormat.month()]; + } else { + return monthsNominative[momentToFormat.month()]; + } + }, + monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), + weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), + weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'), + weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Dziś o] LT', + nextDay: '[Jutro o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[W niedzielę o] LT'; + + case 2: + return '[We wtorek o] LT'; + + case 3: + return '[W środę o] LT'; + + case 6: + return '[W sobotę o] LT'; + + default: + return '[W] dddd [o] LT'; + } + }, + lastDay: '[Wczoraj o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[W zeszłą niedzielę o] LT'; + case 3: + return '[W zeszłą środę o] LT'; + case 6: + return '[W zeszłą sobotę o] LT'; + default: + return '[W zeszły] dddd [o] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : '%s temu', + s : 'kilka sekund', + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : '1 dzień', + dd : '%d dni', + M : 'miesiąc', + MM : translate, + y : 'rok', + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/pt-br.js b/nodejs/node_modules/moment/src/locale/pt-br.js new file mode 100755 index 0000000..bcfe245 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/pt-br.js @@ -0,0 +1,53 @@ +//! moment.js locale configuration +//! locale : Portuguese (Brazil) [pt-br] +//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira + +import moment from '../moment'; + +export default moment.defineLocale('pt-br', { + months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), + monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), + weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY [às] HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm' + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : 'em %s', + past : 'há %s', + s : 'poucos segundos', + ss : '%d segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal : '%dº' +}); + diff --git a/nodejs/node_modules/moment/src/locale/pt.js b/nodejs/node_modules/moment/src/locale/pt.js new file mode 100755 index 0000000..9a63a49 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/pt.js @@ -0,0 +1,57 @@ +//! moment.js locale configuration +//! locale : Portuguese [pt] +//! author : Jefferson : https://github.com/jalex79 + +import moment from '../moment'; + +export default moment.defineLocale('pt', { + months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), + monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), + weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : 'em %s', + past : 'há %s', + s : 'segundos', + ss : '%d segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ro.js b/nodejs/node_modules/moment/src/locale/ro.js new file mode 100755 index 0000000..af621d5 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ro.js @@ -0,0 +1,68 @@ +//! moment.js locale configuration +//! locale : Romanian [ro] +//! author : Vlad Gurdiga : https://github.com/gurdiga +//! author : Valentin Agachi : https://github.com/avaly + +import moment from '../moment'; + +function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': 'secunde', + 'mm': 'minute', + 'hh': 'ore', + 'dd': 'zile', + 'MM': 'luni', + 'yy': 'ani' + }, + separator = ' '; + if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { + separator = ' de '; + } + return number + separator + format[key]; +} + +export default moment.defineLocale('ro', { + months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), + monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), + weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), + weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay: '[azi la] LT', + nextDay: '[mâine la] LT', + nextWeek: 'dddd [la] LT', + lastDay: '[ieri la] LT', + lastWeek: '[fosta] dddd [la] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'peste %s', + past : '%s în urmă', + s : 'câteva secunde', + ss : relativeTimeWithPlural, + m : 'un minut', + mm : relativeTimeWithPlural, + h : 'o oră', + hh : relativeTimeWithPlural, + d : 'o zi', + dd : relativeTimeWithPlural, + M : 'o lună', + MM : relativeTimeWithPlural, + y : 'un an', + yy : relativeTimeWithPlural + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ru.js b/nodejs/node_modules/moment/src/locale/ru.js new file mode 100755 index 0000000..29046af --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ru.js @@ -0,0 +1,175 @@ +//! moment.js locale configuration +//! locale : Russian [ru] +//! author : Viktorminator : https://github.com/Viktorminator +//! Author : Menelion Elensúle : https://github.com/Oire +//! author : Коренберг Марк : https://github.com/socketpair + +import moment from '../moment'; + +function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); +} +function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', + 'hh': 'час_часа_часов', + 'dd': 'день_дня_дней', + 'MM': 'месяц_месяца_месяцев', + 'yy': 'год_года_лет' + }; + if (key === 'm') { + return withoutSuffix ? 'минута' : 'минуту'; + } + else { + return number + ' ' + plural(format[key], +number); + } +} +var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; + +// http://new.gramota.ru/spravka/rules/139-prop : § 103 +// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637 +// CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753 +export default moment.defineLocale('ru', { + months : { + format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'), + standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_') + }, + monthsShort : { + // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ? + format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'), + standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_') + }, + weekdays : { + standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), + format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'), + isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/ + }, + weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + + // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки + monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, + + // копия предыдущего + monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, + + // полные названия с падежами + monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i, + + // Выражение, которое соотвествует только сокращённым формам + monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., H:mm', + LLLL : 'dddd, D MMMM YYYY г., H:mm' + }, + calendar : { + sameDay: '[Сегодня, в] LT', + nextDay: '[Завтра, в] LT', + lastDay: '[Вчера, в] LT', + nextWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В следующее] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В следующий] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В следующую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + lastWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В прошлое] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В прошлый] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В прошлую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'через %s', + past : '%s назад', + s : 'несколько секунд', + ss : relativeTimeWithPlural, + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : 'час', + hh : relativeTimeWithPlural, + d : 'день', + dd : relativeTimeWithPlural, + M : 'месяц', + MM : relativeTimeWithPlural, + y : 'год', + yy : relativeTimeWithPlural + }, + meridiemParse: /ночи|утра|дня|вечера/i, + isPM : function (input) { + return /^(дня|вечера)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночи'; + } else if (hour < 12) { + return 'утра'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечера'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + return number + '-й'; + case 'D': + return number + '-го'; + case 'w': + case 'W': + return number + '-я'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/sd.js b/nodejs/node_modules/moment/src/locale/sd.js new file mode 100755 index 0000000..9747ad4 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sd.js @@ -0,0 +1,89 @@ +//! moment.js locale configuration +//! locale : Sindhi [sd] +//! author : Narain Sagar : https://github.com/narainsagar + +import moment from '../moment'; + +var months = [ + 'جنوري', + 'فيبروري', + 'مارچ', + 'اپريل', + 'مئي', + 'جون', + 'جولاءِ', + 'آگسٽ', + 'سيپٽمبر', + 'آڪٽوبر', + 'نومبر', + 'ڊسمبر' +]; +var days = [ + 'آچر', + 'سومر', + 'اڱارو', + 'اربع', + 'خميس', + 'جمع', + 'ڇنڇر' +]; + +export default moment.defineLocale('sd', { + months : months, + monthsShort : months, + weekdays : days, + weekdaysShort : days, + weekdaysMin : days, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd، D MMMM YYYY HH:mm' + }, + meridiemParse: /صبح|شام/, + isPM : function (input) { + return 'شام' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'صبح'; + } + return 'شام'; + }, + calendar : { + sameDay : '[اڄ] LT', + nextDay : '[سڀاڻي] LT', + nextWeek : 'dddd [اڳين هفتي تي] LT', + lastDay : '[ڪالهه] LT', + lastWeek : '[گزريل هفتي] dddd [تي] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s پوء', + past : '%s اڳ', + s : 'چند سيڪنڊ', + ss : '%d سيڪنڊ', + m : 'هڪ منٽ', + mm : '%d منٽ', + h : 'هڪ ڪلاڪ', + hh : '%d ڪلاڪ', + d : 'هڪ ڏينهن', + dd : '%d ڏينهن', + M : 'هڪ مهينو', + MM : '%d مهينا', + y : 'هڪ سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/se.js b/nodejs/node_modules/moment/src/locale/se.js new file mode 100755 index 0000000..dd10cda --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/se.js @@ -0,0 +1,52 @@ +//! moment.js locale configuration +//! locale : Northern Sami [se] +//! authors : Bård Rolstad Henriksen : https://github.com/karamell + + +import moment from '../moment'; + +export default moment.defineLocale('se', { + months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'), + monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'), + weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'), + weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), + weekdaysMin : 's_v_m_g_d_b_L'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'MMMM D. [b.] YYYY', + LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm', + LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm' + }, + calendar : { + sameDay: '[otne ti] LT', + nextDay: '[ihttin ti] LT', + nextWeek: 'dddd [ti] LT', + lastDay: '[ikte ti] LT', + lastWeek: '[ovddit] dddd [ti] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s geažes', + past : 'maŋit %s', + s : 'moadde sekunddat', + ss: '%d sekunddat', + m : 'okta minuhta', + mm : '%d minuhtat', + h : 'okta diimmu', + hh : '%d diimmut', + d : 'okta beaivi', + dd : '%d beaivvit', + M : 'okta mánnu', + MM : '%d mánut', + y : 'okta jahki', + yy : '%d jagit' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/si.js b/nodejs/node_modules/moment/src/locale/si.js new file mode 100755 index 0000000..ed3caf3 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/si.js @@ -0,0 +1,62 @@ +//! moment.js locale configuration +//! locale : Sinhalese [si] +//! author : Sampath Sitinamaluwa : https://github.com/sampathsris + +import moment from '../moment'; + +/*jshint -W100*/ +export default moment.defineLocale('si', { + months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'), + monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'), + weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'), + weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), + weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'a h:mm', + LTS : 'a h:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY MMMM D', + LLL : 'YYYY MMMM D, a h:mm', + LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss' + }, + calendar : { + sameDay : '[අද] LT[ට]', + nextDay : '[හෙට] LT[ට]', + nextWeek : 'dddd LT[ට]', + lastDay : '[ඊයේ] LT[ට]', + lastWeek : '[පසුගිය] dddd LT[ට]', + sameElse : 'L' + }, + relativeTime : { + future : '%sකින්', + past : '%sකට පෙර', + s : 'තත්පර කිහිපය', + ss : 'තත්පර %d', + m : 'මිනිත්තුව', + mm : 'මිනිත්තු %d', + h : 'පැය', + hh : 'පැය %d', + d : 'දිනය', + dd : 'දින %d', + M : 'මාසය', + MM : 'මාස %d', + y : 'වසර', + yy : 'වසර %d' + }, + dayOfMonthOrdinalParse: /\d{1,2} වැනි/, + ordinal : function (number) { + return number + ' වැනි'; + }, + meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./, + isPM : function (input) { + return input === 'ප.ව.' || input === 'පස් වරු'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'ප.ව.' : 'පස් වරු'; + } else { + return isLower ? 'පෙ.ව.' : 'පෙර වරු'; + } + } +}); diff --git a/nodejs/node_modules/moment/src/locale/sk.js b/nodejs/node_modules/moment/src/locale/sk.js new file mode 100755 index 0000000..3cd3ee1 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sk.js @@ -0,0 +1,149 @@ +//! moment.js locale configuration +//! locale : Slovak [sk] +//! author : Martin Minka : https://github.com/k2s +//! based on work of petrbela : https://github.com/petrbela + +import moment from '../moment'; + +var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), + monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); +function plural(n) { + return (n > 1) && (n < 5); +} +function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'sekundy' : 'sekúnd'); + } else { + return result + 'sekundami'; + } + break; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minúty' : 'minút'); + } else { + return result + 'minútami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodín'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dni' : 'dní'); + } else { + return result + 'dňami'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'mesiace' : 'mesiacov'); + } else { + return result + 'mesiacmi'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'rokov'); + } else { + return result + 'rokmi'; + } + break; + } +} + +export default moment.defineLocale('sk', { + months : months, + monthsShort : monthsShort, + weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), + weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), + weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), + longDateFormat : { + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm' + }, + calendar : { + sameDay: '[dnes o] LT', + nextDay: '[zajtra o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v nedeľu o] LT'; + case 1: + case 2: + return '[v] dddd [o] LT'; + case 3: + return '[v stredu o] LT'; + case 4: + return '[vo štvrtok o] LT'; + case 5: + return '[v piatok o] LT'; + case 6: + return '[v sobotu o] LT'; + } + }, + lastDay: '[včera o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulú nedeľu o] LT'; + case 1: + case 2: + return '[minulý] dddd [o] LT'; + case 3: + return '[minulú stredu o] LT'; + case 4: + case 5: + return '[minulý] dddd [o] LT'; + case 6: + return '[minulú sobotu o] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : 'pred %s', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/sl.js b/nodejs/node_modules/moment/src/locale/sl.js new file mode 100755 index 0000000..b37b7ed --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sl.js @@ -0,0 +1,164 @@ +//! moment.js locale configuration +//! locale : Slovenian [sl] +//! author : Robert Sedovšek : https://github.com/sedovsek + +import moment from '../moment'; + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami'; + case 'ss': + if (number === 1) { + result += withoutSuffix ? 'sekundo' : 'sekundi'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'sekundi' : 'sekundah'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'sekunde' : 'sekundah'; + } else { + result += withoutSuffix || isFuture ? 'sekund' : 'sekund'; + } + return result; + case 'm': + return withoutSuffix ? 'ena minuta' : 'eno minuto'; + case 'mm': + if (number === 1) { + result += withoutSuffix ? 'minuta' : 'minuto'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'minute' : 'minutami'; + } else { + result += withoutSuffix || isFuture ? 'minut' : 'minutami'; + } + return result; + case 'h': + return withoutSuffix ? 'ena ura' : 'eno uro'; + case 'hh': + if (number === 1) { + result += withoutSuffix ? 'ura' : 'uro'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'uri' : 'urama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'ure' : 'urami'; + } else { + result += withoutSuffix || isFuture ? 'ur' : 'urami'; + } + return result; + case 'd': + return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; + case 'dd': + if (number === 1) { + result += withoutSuffix || isFuture ? 'dan' : 'dnem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; + } else { + result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; + } + return result; + case 'M': + return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; + case 'MM': + if (number === 1) { + result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; + } else { + result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; + } + return result; + case 'y': + return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; + case 'yy': + if (number === 1) { + result += withoutSuffix || isFuture ? 'leto' : 'letom'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'leti' : 'letoma'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'leta' : 'leti'; + } else { + result += withoutSuffix || isFuture ? 'let' : 'leti'; + } + return result; + } +} + +export default moment.defineLocale('sl', { + months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), + weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), + weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danes ob] LT', + nextDay : '[jutri ob] LT', + + nextWeek : function () { + switch (this.day()) { + case 0: + return '[v] [nedeljo] [ob] LT'; + case 3: + return '[v] [sredo] [ob] LT'; + case 6: + return '[v] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[v] dddd [ob] LT'; + } + }, + lastDay : '[včeraj ob] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + return '[prejšnjo] [nedeljo] [ob] LT'; + case 3: + return '[prejšnjo] [sredo] [ob] LT'; + case 6: + return '[prejšnjo] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prejšnji] dddd [ob] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'čez %s', + past : 'pred %s', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/sq.js b/nodejs/node_modules/moment/src/locale/sq.js new file mode 100755 index 0000000..1280db7 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sq.js @@ -0,0 +1,62 @@ +//! moment.js locale configuration +//! locale : Albanian [sq] +//! author : Flakërim Ismani : https://github.com/flakerimi +//! author : Menelion Elensúle : https://github.com/Oire +//! author : Oerd Cukalla : https://github.com/oerd + +import moment from '../moment'; + +export default moment.defineLocale('sq', { + months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), + monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), + weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), + weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), + weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), + weekdaysParseExact : true, + meridiemParse: /PD|MD/, + isPM: function (input) { + return input.charAt(0) === 'M'; + }, + meridiem : function (hours, minutes, isLower) { + return hours < 12 ? 'PD' : 'MD'; + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Sot në] LT', + nextDay : '[Nesër në] LT', + nextWeek : 'dddd [në] LT', + lastDay : '[Dje në] LT', + lastWeek : 'dddd [e kaluar në] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'në %s', + past : '%s më parë', + s : 'disa sekonda', + ss : '%d sekonda', + m : 'një minutë', + mm : '%d minuta', + h : 'një orë', + hh : '%d orë', + d : 'një ditë', + dd : '%d ditë', + M : 'një muaj', + MM : '%d muaj', + y : 'një vit', + yy : '%d vite' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/sr-cyrl.js b/nodejs/node_modules/moment/src/locale/sr-cyrl.js new file mode 100755 index 0000000..fc10aee --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sr-cyrl.js @@ -0,0 +1,102 @@ +//! moment.js locale configuration +//! locale : Serbian Cyrillic [sr-cyrl] +//! author : Milan Janačković : https://github.com/milan-j + +import moment from '../moment'; + +var translator = { + words: { //Different grammatical cases + ss: ['секунда', 'секунде', 'секунди'], + m: ['један минут', 'једне минуте'], + mm: ['минут', 'минуте', 'минута'], + h: ['један сат', 'једног сата'], + hh: ['сат', 'сата', 'сати'], + dd: ['дан', 'дана', 'дана'], + MM: ['месец', 'месеца', 'месеци'], + yy: ['година', 'године', 'година'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } +}; + +export default moment.defineLocale('sr-cyrl', { + months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'), + monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'), + monthsParseExact: true, + weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'), + weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'), + weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[данас у] LT', + nextDay: '[сутра у] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[у] [недељу] [у] LT'; + case 3: + return '[у] [среду] [у] LT'; + case 6: + return '[у] [суботу] [у] LT'; + case 1: + case 2: + case 4: + case 5: + return '[у] dddd [у] LT'; + } + }, + lastDay : '[јуче у] LT', + lastWeek : function () { + var lastWeekDays = [ + '[прошле] [недеље] [у] LT', + '[прошлог] [понедељка] [у] LT', + '[прошлог] [уторка] [у] LT', + '[прошле] [среде] [у] LT', + '[прошлог] [четвртка] [у] LT', + '[прошлог] [петка] [у] LT', + '[прошле] [суботе] [у] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'за %s', + past : 'пре %s', + s : 'неколико секунди', + ss : translator.translate, + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : 'дан', + dd : translator.translate, + M : 'месец', + MM : translator.translate, + y : 'годину', + yy : translator.translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/sr.js b/nodejs/node_modules/moment/src/locale/sr.js new file mode 100755 index 0000000..2118262 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sr.js @@ -0,0 +1,102 @@ +//! moment.js locale configuration +//! locale : Serbian [sr] +//! author : Milan Janačković : https://github.com/milan-j + +import moment from '../moment'; + +var translator = { + words: { //Different grammatical cases + ss: ['sekunda', 'sekunde', 'sekundi'], + m: ['jedan minut', 'jedne minute'], + mm: ['minut', 'minute', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mesec', 'meseca', 'meseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } +}; + +export default moment.defineLocale('sr', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'), + weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedelju] [u] LT'; + case 3: + return '[u] [sredu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedelje] [u] LT', + '[prošlog] [ponedeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'pre %s', + s : 'nekoliko sekundi', + ss : translator.translate, + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : 'dan', + dd : translator.translate, + M : 'mesec', + MM : translator.translate, + y : 'godinu', + yy : translator.translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/ss.js b/nodejs/node_modules/moment/src/locale/ss.js new file mode 100755 index 0000000..7cc5f24 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ss.js @@ -0,0 +1,81 @@ +//! moment.js locale configuration +//! locale : siSwati [ss] +//! author : Nicolai Davies : https://github.com/nicolaidavies + + +import moment from '../moment'; + +export default moment.defineLocale('ss', { + months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'), + monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'), + weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'), + weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'), + weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Namuhla nga] LT', + nextDay : '[Kusasa nga] LT', + nextWeek : 'dddd [nga] LT', + lastDay : '[Itolo nga] LT', + lastWeek : 'dddd [leliphelile] [nga] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'nga %s', + past : 'wenteka nga %s', + s : 'emizuzwana lomcane', + ss : '%d mzuzwana', + m : 'umzuzu', + mm : '%d emizuzu', + h : 'lihora', + hh : '%d emahora', + d : 'lilanga', + dd : '%d emalanga', + M : 'inyanga', + MM : '%d tinyanga', + y : 'umnyaka', + yy : '%d iminyaka' + }, + meridiemParse: /ekuseni|emini|entsambama|ebusuku/, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'ekuseni'; + } else if (hours < 15) { + return 'emini'; + } else if (hours < 19) { + return 'entsambama'; + } else { + return 'ebusuku'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ekuseni') { + return hour; + } else if (meridiem === 'emini') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') { + if (hour === 0) { + return 0; + } + return hour + 12; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : '%d', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/sv.js b/nodejs/node_modules/moment/src/locale/sv.js new file mode 100755 index 0000000..8afce35 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sv.js @@ -0,0 +1,61 @@ +//! moment.js locale configuration +//! locale : Swedish [sv] +//! author : Jens Alm : https://github.com/ulmus + +import moment from '../moment'; + +export default moment.defineLocale('sv', { + months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), + weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), + weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D MMMM YYYY [kl.] HH:mm', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd D MMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Idag] LT', + nextDay: '[Imorgon] LT', + lastDay: '[Igår] LT', + nextWeek: '[På] dddd LT', + lastWeek: '[I] dddd[s] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : 'för %s sedan', + s : 'några sekunder', + ss : '%d sekunder', + m : 'en minut', + mm : '%d minuter', + h : 'en timme', + hh : '%d timmar', + d : 'en dag', + dd : '%d dagar', + M : 'en månad', + MM : '%d månader', + y : 'ett år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}(e|a)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'e' : + (b === 1) ? 'a' : + (b === 2) ? 'a' : + (b === 3) ? 'e' : 'e'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/sw.js b/nodejs/node_modules/moment/src/locale/sw.js new file mode 100755 index 0000000..833de80 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/sw.js @@ -0,0 +1,51 @@ +//! moment.js locale configuration +//! locale : Swahili [sw] +//! author : Fahad Kassim : https://github.com/fadsel + +import moment from '../moment'; + +export default moment.defineLocale('sw', { + months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'), + weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), + weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[leo saa] LT', + nextDay : '[kesho saa] LT', + nextWeek : '[wiki ijayo] dddd [saat] LT', + lastDay : '[jana] LT', + lastWeek : '[wiki iliyopita] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s baadaye', + past : 'tokea %s', + s : 'hivi punde', + ss : 'sekunde %d', + m : 'dakika moja', + mm : 'dakika %d', + h : 'saa limoja', + hh : 'masaa %d', + d : 'siku moja', + dd : 'masiku %d', + M : 'mwezi mmoja', + MM : 'miezi %d', + y : 'mwaka mmoja', + yy : 'miaka %d' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ta.js b/nodejs/node_modules/moment/src/locale/ta.js new file mode 100755 index 0000000..9969cb5 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ta.js @@ -0,0 +1,121 @@ +//! moment.js locale configuration +//! locale : Tamil [ta] +//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404 + +import moment from '../moment'; + +var symbolMap = { + '1': '௧', + '2': '௨', + '3': '௩', + '4': '௪', + '5': '௫', + '6': '௬', + '7': '௭', + '8': '௮', + '9': '௯', + '0': '௦' +}, numberMap = { + '௧': '1', + '௨': '2', + '௩': '3', + '௪': '4', + '௫': '5', + '௬': '6', + '௭': '7', + '௮': '8', + '௯': '9', + '௦': '0' +}; + +export default moment.defineLocale('ta', { + months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), + weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), + weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, HH:mm', + LLLL : 'dddd, D MMMM YYYY, HH:mm' + }, + calendar : { + sameDay : '[இன்று] LT', + nextDay : '[நாளை] LT', + nextWeek : 'dddd, LT', + lastDay : '[நேற்று] LT', + lastWeek : '[கடந்த வாரம்] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s இல்', + past : '%s முன்', + s : 'ஒரு சில விநாடிகள்', + ss : '%d விநாடிகள்', + m : 'ஒரு நிமிடம்', + mm : '%d நிமிடங்கள்', + h : 'ஒரு மணி நேரம்', + hh : '%d மணி நேரம்', + d : 'ஒரு நாள்', + dd : '%d நாட்கள்', + M : 'ஒரு மாதம்', + MM : '%d மாதங்கள்', + y : 'ஒரு வருடம்', + yy : '%d ஆண்டுகள்' + }, + dayOfMonthOrdinalParse: /\d{1,2}வது/, + ordinal : function (number) { + return number + 'வது'; + }, + preparse: function (string) { + return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // refer http://ta.wikipedia.org/s/1er1 + meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, + meridiem : function (hour, minute, isLower) { + if (hour < 2) { + return ' யாமம்'; + } else if (hour < 6) { + return ' வைகறை'; // வைகறை + } else if (hour < 10) { + return ' காலை'; // காலை + } else if (hour < 14) { + return ' நண்பகல்'; // நண்பகல் + } else if (hour < 18) { + return ' எற்பாடு'; // எற்பாடு + } else if (hour < 22) { + return ' மாலை'; // மாலை + } else { + return ' யாமம்'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'யாமம்') { + return hour < 2 ? hour : hour + 12; + } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { + return hour; + } else if (meridiem === 'நண்பகல்') { + return hour >= 10 ? hour : hour + 12; + } else { + return hour + 12; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/te.js b/nodejs/node_modules/moment/src/locale/te.js new file mode 100755 index 0000000..8fd2767 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/te.js @@ -0,0 +1,80 @@ +//! moment.js locale configuration +//! locale : Telugu [te] +//! author : Krishna Chaitanya Thota : https://github.com/kcthota + +import moment from '../moment'; + +export default moment.defineLocale('te', { + months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'), + monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'), + monthsParseExact : true, + weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'), + weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), + weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[నేడు] LT', + nextDay : '[రేపు] LT', + nextWeek : 'dddd, LT', + lastDay : '[నిన్న] LT', + lastWeek : '[గత] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s లో', + past : '%s క్రితం', + s : 'కొన్ని క్షణాలు', + ss : '%d సెకన్లు', + m : 'ఒక నిమిషం', + mm : '%d నిమిషాలు', + h : 'ఒక గంట', + hh : '%d గంటలు', + d : 'ఒక రోజు', + dd : '%d రోజులు', + M : 'ఒక నెల', + MM : '%d నెలలు', + y : 'ఒక సంవత్సరం', + yy : '%d సంవత్సరాలు' + }, + dayOfMonthOrdinalParse : /\d{1,2}వ/, + ordinal : '%dవ', + meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'రాత్రి') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ఉదయం') { + return hour; + } else if (meridiem === 'మధ్యాహ్నం') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'సాయంత్రం') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'రాత్రి'; + } else if (hour < 10) { + return 'ఉదయం'; + } else if (hour < 17) { + return 'మధ్యాహ్నం'; + } else if (hour < 20) { + return 'సాయంత్రం'; + } else { + return 'రాత్రి'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/tet.js b/nodejs/node_modules/moment/src/locale/tet.js new file mode 100755 index 0000000..a4e9e19 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tet.js @@ -0,0 +1,60 @@ +//! moment.js locale configuration +//! locale : Tetun Dili (East Timor) [tet] +//! author : Joshua Brooks : https://github.com/joshbrooks +//! author : Onorio De J. Afonso : https://github.com/marobo +//! author : Sonia Simoes : https://github.com/soniasimoes + +import moment from '../moment'; + +export default moment.defineLocale('tet', { + months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'), + weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'), + weekdaysMin : 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Ohin iha] LT', + nextDay: '[Aban iha] LT', + nextWeek: 'dddd [iha] LT', + lastDay: '[Horiseik iha] LT', + lastWeek: 'dddd [semana kotuk] [iha] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'iha %s', + past : '%s liuba', + s : 'minutu balun', + ss : 'minutu %d', + m : 'minutu ida', + mm : 'minutu %d', + h : 'oras ida', + hh : 'oras %d', + d : 'loron ida', + dd : 'loron %d', + M : 'fulan ida', + MM : 'fulan %d', + y : 'tinan ida', + yy : 'tinan %d' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/tg.js b/nodejs/node_modules/moment/src/locale/tg.js new file mode 100755 index 0000000..9f15e1a --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tg.js @@ -0,0 +1,107 @@ +//! moment.js locale configuration +//! locale : Tajik [tg] +//! author : Orif N. Jr. : https://github.com/orif-jr + +import moment from '../moment'; + +var suffixes = { + 0: '-ум', + 1: '-ум', + 2: '-юм', + 3: '-юм', + 4: '-ум', + 5: '-ум', + 6: '-ум', + 7: '-ум', + 8: '-ум', + 9: '-ум', + 10: '-ум', + 12: '-ум', + 13: '-ум', + 20: '-ум', + 30: '-юм', + 40: '-ум', + 50: '-ум', + 60: '-ум', + 70: '-ум', + 80: '-ум', + 90: '-ум', + 100: '-ум' +}; + +export default moment.defineLocale('tg', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split('_'), + weekdaysShort : 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'), + weekdaysMin : 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Имрӯз соати] LT', + nextDay : '[Пагоҳ соати] LT', + lastDay : '[Дирӯз соати] LT', + nextWeek : 'dddd[и] [ҳафтаи оянда соати] LT', + lastWeek : 'dddd[и] [ҳафтаи гузашта соати] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'баъди %s', + past : '%s пеш', + s : 'якчанд сония', + m : 'як дақиқа', + mm : '%d дақиқа', + h : 'як соат', + hh : '%d соат', + d : 'як рӯз', + dd : '%d рӯз', + M : 'як моҳ', + MM : '%d моҳ', + y : 'як сол', + yy : '%d сол' + }, + meridiemParse: /шаб|субҳ|рӯз|бегоҳ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'шаб') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'субҳ') { + return hour; + } else if (meridiem === 'рӯз') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'бегоҳ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'шаб'; + } else if (hour < 11) { + return 'субҳ'; + } else if (hour < 16) { + return 'рӯз'; + } else if (hour < 19) { + return 'бегоҳ'; + } else { + return 'шаб'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ум|юм)/, + ordinal: function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/th.js b/nodejs/node_modules/moment/src/locale/th.js new file mode 100755 index 0000000..9f8771f --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/th.js @@ -0,0 +1,58 @@ +//! moment.js locale configuration +//! locale : Thai [th] +//! author : Kridsada Thanabulpong : https://github.com/sirn + +import moment from '../moment'; + +export default moment.defineLocale('th', { + months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), + monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'), + monthsParseExact: true, + weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), + weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference + weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY เวลา H:mm', + LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm' + }, + meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, + isPM: function (input) { + return input === 'หลังเที่ยง'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ก่อนเที่ยง'; + } else { + return 'หลังเที่ยง'; + } + }, + calendar : { + sameDay : '[วันนี้ เวลา] LT', + nextDay : '[พรุ่งนี้ เวลา] LT', + nextWeek : 'dddd[หน้า เวลา] LT', + lastDay : '[เมื่อวานนี้ เวลา] LT', + lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'อีก %s', + past : '%sที่แล้ว', + s : 'ไม่กี่วินาที', + ss : '%d วินาที', + m : '1 นาที', + mm : '%d นาที', + h : '1 ชั่วโมง', + hh : '%d ชั่วโมง', + d : '1 วัน', + dd : '%d วัน', + M : '1 เดือน', + MM : '%d เดือน', + y : '1 ปี', + yy : '%d ปี' + } +}); diff --git a/nodejs/node_modules/moment/src/locale/tl-ph.js b/nodejs/node_modules/moment/src/locale/tl-ph.js new file mode 100755 index 0000000..26c4824 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tl-ph.js @@ -0,0 +1,54 @@ +//! moment.js locale configuration +//! locale : Tagalog (Philippines) [tl-ph] +//! author : Dan Hagman : https://github.com/hagmandan + +import moment from '../moment'; + +export default moment.defineLocale('tl-ph', { + months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), + monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), + weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), + weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), + weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'MM/D/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY HH:mm', + LLLL : 'dddd, MMMM DD, YYYY HH:mm' + }, + calendar : { + sameDay: 'LT [ngayong araw]', + nextDay: '[Bukas ng] LT', + nextWeek: 'LT [sa susunod na] dddd', + lastDay: 'LT [kahapon]', + lastWeek: 'LT [noong nakaraang] dddd', + sameElse: 'L' + }, + relativeTime : { + future : 'sa loob ng %s', + past : '%s ang nakalipas', + s : 'ilang segundo', + ss : '%d segundo', + m : 'isang minuto', + mm : '%d minuto', + h : 'isang oras', + hh : '%d oras', + d : 'isang araw', + dd : '%d araw', + M : 'isang buwan', + MM : '%d buwan', + y : 'isang taon', + yy : '%d taon' + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/tlh.js b/nodejs/node_modules/moment/src/locale/tlh.js new file mode 100755 index 0000000..324edc6 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tlh.js @@ -0,0 +1,113 @@ +//! moment.js locale configuration +//! locale : Klingon [tlh] +//! author : Dominika Kruk : https://github.com/amaranthrose + +import moment from '../moment'; + +var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); + +function translateFuture(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'leS' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'waQ' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'nem' : + time + ' pIq'; + return time; +} + +function translatePast(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'Hu’' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'wen' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'ben' : + time + ' ret'; + return time; +} + +function translate(number, withoutSuffix, string, isFuture) { + var numberNoun = numberAsNoun(number); + switch (string) { + case 'ss': + return numberNoun + ' lup'; + case 'mm': + return numberNoun + ' tup'; + case 'hh': + return numberNoun + ' rep'; + case 'dd': + return numberNoun + ' jaj'; + case 'MM': + return numberNoun + ' jar'; + case 'yy': + return numberNoun + ' DIS'; + } +} + +function numberAsNoun(number) { + var hundred = Math.floor((number % 1000) / 100), + ten = Math.floor((number % 100) / 10), + one = number % 10, + word = ''; + if (hundred > 0) { + word += numbersNouns[hundred] + 'vatlh'; + } + if (ten > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH'; + } + if (one > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[one]; + } + return (word === '') ? 'pagh' : word; +} + +export default moment.defineLocale('tlh', { + months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'), + monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'), + monthsParseExact : true, + weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[DaHjaj] LT', + nextDay: '[wa’leS] LT', + nextWeek: 'LLL', + lastDay: '[wa’Hu’] LT', + lastWeek: 'LLL', + sameElse: 'L' + }, + relativeTime : { + future : translateFuture, + past : translatePast, + s : 'puS lup', + ss : translate, + m : 'wa’ tup', + mm : translate, + h : 'wa’ rep', + hh : translate, + d : 'wa’ jaj', + dd : translate, + M : 'wa’ jar', + MM : translate, + y : 'wa’ DIS', + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/tr.js b/nodejs/node_modules/moment/src/locale/tr.js new file mode 100755 index 0000000..b5e8ad7 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tr.js @@ -0,0 +1,90 @@ + +//! moment.js locale configuration +//! locale : Turkish [tr] +//! authors : Erhan Gundogan : https://github.com/erhangundogan, +//! Burak Yiğit Kaya: https://github.com/BYK + +import moment from '../moment'; + +var suffixes = { + 1: '\'inci', + 5: '\'inci', + 8: '\'inci', + 70: '\'inci', + 80: '\'inci', + 2: '\'nci', + 7: '\'nci', + 20: '\'nci', + 50: '\'nci', + 3: '\'üncü', + 4: '\'üncü', + 100: '\'üncü', + 6: '\'ncı', + 9: '\'uncu', + 10: '\'uncu', + 30: '\'uncu', + 60: '\'ıncı', + 90: '\'ıncı' +}; + +export default moment.defineLocale('tr', { + months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), + monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), + weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), + weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), + weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[yarın saat] LT', + nextWeek : '[gelecek] dddd [saat] LT', + lastDay : '[dün] LT', + lastWeek : '[geçen] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s sonra', + past : '%s önce', + s : 'birkaç saniye', + ss : '%d saniye', + m : 'bir dakika', + mm : '%d dakika', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir yıl', + yy : '%d yıl' + }, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'Do': + case 'DD': + return number; + default: + if (number === 0) { // special case for zero + return number + '\'ıncı'; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/tzl.js b/nodejs/node_modules/moment/src/locale/tzl.js new file mode 100755 index 0000000..2a59458 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tzl.js @@ -0,0 +1,84 @@ +//! moment.js locale configuration +//! locale : Talossan [tzl] +//! author : Robin van der Vliet : https://github.com/robin0van0der0v +//! author : Iustì Canun + +import moment from '../moment'; + +// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. +// This is currently too difficult (maybe even impossible) to add. +export default moment.defineLocale('tzl', { + months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'), + monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), + weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), + weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), + weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM [dallas] YYYY', + LLL : 'D. MMMM [dallas] YYYY HH.mm', + LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm' + }, + meridiemParse: /d\'o|d\'a/i, + isPM : function (input) { + return 'd\'o' === input.toLowerCase(); + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'd\'o' : 'D\'O'; + } else { + return isLower ? 'd\'a' : 'D\'A'; + } + }, + calendar : { + sameDay : '[oxhi à] LT', + nextDay : '[demà à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[ieiri à] LT', + lastWeek : '[sür el] dddd [lasteu à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'osprei %s', + past : 'ja%s', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + +function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['viensas secunds', '\'iensas secunds'], + 'ss': [number + ' secunds', '' + number + ' secunds'], + 'm': ['\'n míut', '\'iens míut'], + 'mm': [number + ' míuts', '' + number + ' míuts'], + 'h': ['\'n þora', '\'iensa þora'], + 'hh': [number + ' þoras', '' + number + ' þoras'], + 'd': ['\'n ziua', '\'iensa ziua'], + 'dd': [number + ' ziuas', '' + number + ' ziuas'], + 'M': ['\'n mes', '\'iens mes'], + 'MM': [number + ' mesen', '' + number + ' mesen'], + 'y': ['\'n ar', '\'iens ar'], + 'yy': [number + ' ars', '' + number + ' ars'] + }; + return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]); +} + diff --git a/nodejs/node_modules/moment/src/locale/tzm-latn.js b/nodejs/node_modules/moment/src/locale/tzm-latn.js new file mode 100755 index 0000000..23d2efa --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tzm-latn.js @@ -0,0 +1,50 @@ +//! moment.js locale configuration +//! locale : Central Atlas Tamazight Latin [tzm-latn] +//! author : Abdel Said : https://github.com/abdelsaid + +import moment from '../moment'; + +export default moment.defineLocale('tzm-latn', { + months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[asdkh g] LT', + nextDay: '[aska g] LT', + nextWeek: 'dddd [g] LT', + lastDay: '[assant g] LT', + lastWeek: 'dddd [g] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'dadkh s yan %s', + past : 'yan %s', + s : 'imik', + ss : '%d imik', + m : 'minuḍ', + mm : '%d minuḍ', + h : 'saɛa', + hh : '%d tassaɛin', + d : 'ass', + dd : '%d ossan', + M : 'ayowr', + MM : '%d iyyirn', + y : 'asgas', + yy : '%d isgasn' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/tzm.js b/nodejs/node_modules/moment/src/locale/tzm.js new file mode 100755 index 0000000..04c1954 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/tzm.js @@ -0,0 +1,50 @@ +//! moment.js locale configuration +//! locale : Central Atlas Tamazight [tzm] +//! author : Abdel Said : https://github.com/abdelsaid + +import moment from '../moment'; + +export default moment.defineLocale('tzm', { + months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', + nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', + nextWeek: 'dddd [ⴴ] LT', + lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', + lastWeek: 'dddd [ⴴ] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', + past : 'ⵢⴰⵏ %s', + s : 'ⵉⵎⵉⴽ', + ss : '%d ⵉⵎⵉⴽ', + m : 'ⵎⵉⵏⵓⴺ', + mm : '%d ⵎⵉⵏⵓⴺ', + h : 'ⵙⴰⵄⴰ', + hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', + d : 'ⴰⵙⵙ', + dd : '%d oⵙⵙⴰⵏ', + M : 'ⴰⵢoⵓⵔ', + MM : '%d ⵉⵢⵢⵉⵔⵏ', + y : 'ⴰⵙⴳⴰⵙ', + yy : '%d ⵉⵙⴳⴰⵙⵏ' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ug-cn.js b/nodejs/node_modules/moment/src/locale/ug-cn.js new file mode 100755 index 0000000..5a9a9fc --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ug-cn.js @@ -0,0 +1,110 @@ +//! moment.js language configuration +//! locale : Uyghur (China) [ug-cn] +//! author: boyaq : https://github.com/boyaq + +import moment from '../moment'; + +export default moment.defineLocale('ug-cn', { + months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split( + '_' + ), + weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى', + LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm', + LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm' + }, + meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ( + meridiem === 'يېرىم كېچە' || + meridiem === 'سەھەر' || + meridiem === 'چۈشتىن بۇرۇن' + ) { + return hour; + } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') { + return hour + 12; + } else { + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return 'يېرىم كېچە'; + } else if (hm < 900) { + return 'سەھەر'; + } else if (hm < 1130) { + return 'چۈشتىن بۇرۇن'; + } else if (hm < 1230) { + return 'چۈش'; + } else if (hm < 1800) { + return 'چۈشتىن كېيىن'; + } else { + return 'كەچ'; + } + }, + calendar: { + sameDay: '[بۈگۈن سائەت] LT', + nextDay: '[ئەتە سائەت] LT', + nextWeek: '[كېلەركى] dddd [سائەت] LT', + lastDay: '[تۆنۈگۈن] LT', + lastWeek: '[ئالدىنقى] dddd [سائەت] LT', + sameElse: 'L' + }, + relativeTime: { + future: '%s كېيىن', + past: '%s بۇرۇن', + s: 'نەچچە سېكونت', + ss: '%d سېكونت', + m: 'بىر مىنۇت', + mm: '%d مىنۇت', + h: 'بىر سائەت', + hh: '%d سائەت', + d: 'بىر كۈن', + dd: '%d كۈن', + M: 'بىر ئاي', + MM: '%d ئاي', + y: 'بىر يىل', + yy: '%d يىل' + }, + + dayOfMonthOrdinalParse: /\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '-كۈنى'; + case 'w': + case 'W': + return number + '-ھەپتە'; + default: + return number; + } + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow: 1, // Monday is the first day of the week. + doy: 7 // The week that contains Jan 1st is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/uk.js b/nodejs/node_modules/moment/src/locale/uk.js new file mode 100755 index 0000000..889e017 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/uk.js @@ -0,0 +1,144 @@ +//! moment.js locale configuration +//! locale : Ukrainian [uk] +//! author : zemlanin : https://github.com/zemlanin +//! Author : Menelion Elensúle : https://github.com/Oire + +import moment from '../moment'; + +function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); +} +function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд', + 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', + 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин', + 'dd': 'день_дні_днів', + 'MM': 'місяць_місяці_місяців', + 'yy': 'рік_роки_років' + }; + if (key === 'm') { + return withoutSuffix ? 'хвилина' : 'хвилину'; + } + else if (key === 'h') { + return withoutSuffix ? 'година' : 'годину'; + } + else { + return number + ' ' + plural(format[key], +number); + } +} +function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), + 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), + 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') + }; + + if (!m) { + return weekdays['nominative']; + } + + var nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? + 'accusative' : + ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? + 'genitive' : + 'nominative'); + return weekdays[nounCase][m.day()]; +} +function processHoursFunction(str) { + return function () { + return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; + }; +} + +export default moment.defineLocale('uk', { + months : { + 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'), + 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_') + }, + monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), + weekdays : weekdaysCaseReplace, + weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY р.', + LLL : 'D MMMM YYYY р., HH:mm', + LLLL : 'dddd, D MMMM YYYY р., HH:mm' + }, + calendar : { + sameDay: processHoursFunction('[Сьогодні '), + nextDay: processHoursFunction('[Завтра '), + lastDay: processHoursFunction('[Вчора '), + nextWeek: processHoursFunction('[У] dddd ['), + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return processHoursFunction('[Минулої] dddd [').call(this); + case 1: + case 2: + case 4: + return processHoursFunction('[Минулого] dddd [').call(this); + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'за %s', + past : '%s тому', + s : 'декілька секунд', + ss : relativeTimeWithPlural, + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : 'годину', + hh : relativeTimeWithPlural, + d : 'день', + dd : relativeTimeWithPlural, + M : 'місяць', + MM : relativeTimeWithPlural, + y : 'рік', + yy : relativeTimeWithPlural + }, + // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason + meridiemParse: /ночі|ранку|дня|вечора/, + isPM: function (input) { + return /^(дня|вечора)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночі'; + } else if (hour < 12) { + return 'ранку'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечора'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return number + '-й'; + case 'D': + return number + '-го'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/ur.js b/nodejs/node_modules/moment/src/locale/ur.js new file mode 100755 index 0000000..56f1818 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/ur.js @@ -0,0 +1,90 @@ +//! moment.js locale configuration +//! locale : Urdu [ur] +//! author : Sawood Alam : https://github.com/ibnesayeed +//! author : Zack : https://github.com/ZackVision + +import moment from '../moment'; + +var months = [ + 'جنوری', + 'فروری', + 'مارچ', + 'اپریل', + 'مئی', + 'جون', + 'جولائی', + 'اگست', + 'ستمبر', + 'اکتوبر', + 'نومبر', + 'دسمبر' +]; +var days = [ + 'اتوار', + 'پیر', + 'منگل', + 'بدھ', + 'جمعرات', + 'جمعہ', + 'ہفتہ' +]; + +export default moment.defineLocale('ur', { + months : months, + monthsShort : months, + weekdays : days, + weekdaysShort : days, + weekdaysMin : days, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd، D MMMM YYYY HH:mm' + }, + meridiemParse: /صبح|شام/, + isPM : function (input) { + return 'شام' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'صبح'; + } + return 'شام'; + }, + calendar : { + sameDay : '[آج بوقت] LT', + nextDay : '[کل بوقت] LT', + nextWeek : 'dddd [بوقت] LT', + lastDay : '[گذشتہ روز بوقت] LT', + lastWeek : '[گذشتہ] dddd [بوقت] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s بعد', + past : '%s قبل', + s : 'چند سیکنڈ', + ss : '%d سیکنڈ', + m : 'ایک منٹ', + mm : '%d منٹ', + h : 'ایک گھنٹہ', + hh : '%d گھنٹے', + d : 'ایک دن', + dd : '%d دن', + M : 'ایک ماہ', + MM : '%d ماہ', + y : 'ایک سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/uz-latn.js b/nodejs/node_modules/moment/src/locale/uz-latn.js new file mode 100755 index 0000000..2ba7ea6 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/uz-latn.js @@ -0,0 +1,50 @@ +//! moment.js locale configuration +//! locale : Uzbek Latin [uz-latn] +//! author : Rasulbek Mirzayev : github.com/Rasulbeeek + +import moment from '../moment'; + +export default moment.defineLocale('uz-latn', { + months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'), + monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'), + weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'), + weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'), + weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' + }, + calendar : { + sameDay : '[Bugun soat] LT [da]', + nextDay : '[Ertaga] LT [da]', + nextWeek : 'dddd [kuni soat] LT [da]', + lastDay : '[Kecha soat] LT [da]', + lastWeek : '[O\'tgan] dddd [kuni soat] LT [da]', + sameElse : 'L' + }, + relativeTime : { + future : 'Yaqin %s ichida', + past : 'Bir necha %s oldin', + s : 'soniya', + ss : '%d soniya', + m : 'bir daqiqa', + mm : '%d daqiqa', + h : 'bir soat', + hh : '%d soat', + d : 'bir kun', + dd : '%d kun', + M : 'bir oy', + MM : '%d oy', + y : 'bir yil', + yy : '%d yil' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/uz.js b/nodejs/node_modules/moment/src/locale/uz.js new file mode 100755 index 0000000..ff0f7ca --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/uz.js @@ -0,0 +1,50 @@ +//! moment.js locale configuration +//! locale : Uzbek [uz] +//! author : Sardor Muminov : https://github.com/muminoff + +import moment from '../moment'; + +export default moment.defineLocale('uz', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), + weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), + weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' + }, + calendar : { + sameDay : '[Бугун соат] LT [да]', + nextDay : '[Эртага] LT [да]', + nextWeek : 'dddd [куни соат] LT [да]', + lastDay : '[Кеча соат] LT [да]', + lastWeek : '[Утган] dddd [куни соат] LT [да]', + sameElse : 'L' + }, + relativeTime : { + future : 'Якин %s ичида', + past : 'Бир неча %s олдин', + s : 'фурсат', + ss : '%d фурсат', + m : 'бир дакика', + mm : '%d дакика', + h : 'бир соат', + hh : '%d соат', + d : 'бир кун', + dd : '%d кун', + M : 'бир ой', + MM : '%d ой', + y : 'бир йил', + yy : '%d йил' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/vi.js b/nodejs/node_modules/moment/src/locale/vi.js new file mode 100755 index 0000000..ad7f4b0 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/vi.js @@ -0,0 +1,71 @@ +//! moment.js locale configuration +//! locale : Vietnamese [vi] +//! author : Bang Nguyen : https://github.com/bangnk + +import moment from '../moment'; + +export default moment.defineLocale('vi', { + months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), + monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), + monthsParseExact : true, + weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), + weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysParseExact : true, + meridiemParse: /sa|ch/i, + isPM : function (input) { + return /^ch$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'sa' : 'SA'; + } else { + return isLower ? 'ch' : 'CH'; + } + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [năm] YYYY', + LLL : 'D MMMM [năm] YYYY HH:mm', + LLLL : 'dddd, D MMMM [năm] YYYY HH:mm', + l : 'DD/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Hôm nay lúc] LT', + nextDay: '[Ngày mai lúc] LT', + nextWeek: 'dddd [tuần tới lúc] LT', + lastDay: '[Hôm qua lúc] LT', + lastWeek: 'dddd [tuần rồi lúc] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s tới', + past : '%s trước', + s : 'vài giây', + ss : '%d giây' , + m : 'một phút', + mm : '%d phút', + h : 'một giờ', + hh : '%d giờ', + d : 'một ngày', + dd : '%d ngày', + M : 'một tháng', + MM : '%d tháng', + y : 'một năm', + yy : '%d năm' + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); + diff --git a/nodejs/node_modules/moment/src/locale/x-pseudo.js b/nodejs/node_modules/moment/src/locale/x-pseudo.js new file mode 100755 index 0000000..c50320d --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/x-pseudo.js @@ -0,0 +1,59 @@ +//! moment.js locale configuration +//! locale : Pseudo [x-pseudo] +//! author : Andrew Hood : https://github.com/andrewhood125 + +import moment from '../moment'; + +export default moment.defineLocale('x-pseudo', { + months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'), + monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'), + monthsParseExact : true, + weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'), + weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'), + weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[T~ódá~ý át] LT', + nextDay : '[T~ómó~rró~w át] LT', + nextWeek : 'dddd [át] LT', + lastDay : '[Ý~ést~érdá~ý át] LT', + lastWeek : '[L~ást] dddd [át] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'í~ñ %s', + past : '%s á~gó', + s : 'á ~féw ~sécó~ñds', + ss : '%d s~écóñ~ds', + m : 'á ~míñ~úté', + mm : '%d m~íñú~tés', + h : 'á~ñ hó~úr', + hh : '%d h~óúrs', + d : 'á ~dáý', + dd : '%d d~áýs', + M : 'á ~móñ~th', + MM : '%d m~óñt~hs', + y : 'á ~ýéár', + yy : '%d ý~éárs' + }, + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/yo.js b/nodejs/node_modules/moment/src/locale/yo.js new file mode 100755 index 0000000..dcd6cd2 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/yo.js @@ -0,0 +1,51 @@ +//! moment.js locale configuration +//! locale : Yoruba Nigeria [yo] +//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe + +import moment from '../moment'; + +export default moment.defineLocale('yo', { + months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'), + monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'), + weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'), + weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'), + weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Ònì ni] LT', + nextDay : '[Ọ̀la ni] LT', + nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT', + lastDay : '[Àna ni] LT', + lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ní %s', + past : '%s kọjá', + s : 'ìsẹjú aayá die', + ss :'aayá %d', + m : 'ìsẹjú kan', + mm : 'ìsẹjú %d', + h : 'wákati kan', + hh : 'wákati %d', + d : 'ọjọ́ kan', + dd : 'ọjọ́ %d', + M : 'osù kan', + MM : 'osù %d', + y : 'ọdún kan', + yy : 'ọdún %d' + }, + dayOfMonthOrdinalParse : /ọjọ́\s\d{1,2}/, + ordinal : 'ọjọ́ %d', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/zh-cn.js b/nodejs/node_modules/moment/src/locale/zh-cn.js new file mode 100755 index 0000000..d9e6e7e --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/zh-cn.js @@ -0,0 +1,102 @@ +//! moment.js locale configuration +//! locale : Chinese (China) [zh-cn] +//! author : suupic : https://github.com/suupic +//! author : Zeno Zeng : https://github.com/zenozeng + +import moment from '../moment'; + +export default moment.defineLocale('zh-cn', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日Ah点mm分', + LLLL : 'YYYY年M月D日ddddAh点mm分', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || + meridiem === '上午') { + return hour; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } else { + // '中午' + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', + sameElse : 'L' + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '周'; + default: + return number; + } + }, + relativeTime : { + future : '%s内', + past : '%s前', + s : '几秒', + ss : '%d 秒', + m : '1 分钟', + mm : '%d 分钟', + h : '1 小时', + hh : '%d 小时', + d : '1 天', + dd : '%d 天', + M : '1 个月', + MM : '%d 个月', + y : '1 年', + yy : '%d 年' + }, + week : { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } +}); diff --git a/nodejs/node_modules/moment/src/locale/zh-hk.js b/nodejs/node_modules/moment/src/locale/zh-hk.js new file mode 100755 index 0000000..9943541 --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/zh-hk.js @@ -0,0 +1,96 @@ +//! moment.js locale configuration +//! locale : Chinese (Hong Kong) [zh-hk] +//! author : Ben : https://github.com/ben-lin +//! author : Chris Lam : https://github.com/hehachris +//! author : Konstantin : https://github.com/skfd + +import moment from '../moment'; + +export default moment.defineLocale('zh-hk', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日dddd HH:mm', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', + sameElse : 'L' + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal : function (number, period) { + switch (period) { + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; + default : + return number; + } + }, + relativeTime : { + future : '%s內', + past : '%s前', + s : '幾秒', + ss : '%d 秒', + m : '1 分鐘', + mm : '%d 分鐘', + h : '1 小時', + hh : '%d 小時', + d : '1 天', + dd : '%d 天', + M : '1 個月', + MM : '%d 個月', + y : '1 年', + yy : '%d 年' + } +}); diff --git a/nodejs/node_modules/moment/src/locale/zh-tw.js b/nodejs/node_modules/moment/src/locale/zh-tw.js new file mode 100755 index 0000000..5ad0d9c --- /dev/null +++ b/nodejs/node_modules/moment/src/locale/zh-tw.js @@ -0,0 +1,95 @@ +//! moment.js locale configuration +//! locale : Chinese (Taiwan) [zh-tw] +//! author : Ben : https://github.com/ben-lin +//! author : Chris Lam : https://github.com/hehachris + +import moment from '../moment'; + +export default moment.defineLocale('zh-tw', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日dddd HH:mm', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : '[今天] LT', + nextDay : '[明天] LT', + nextWeek : '[下]dddd LT', + lastDay : '[昨天] LT', + lastWeek : '[上]dddd LT', + sameElse : 'L' + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal : function (number, period) { + switch (period) { + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; + default : + return number; + } + }, + relativeTime : { + future : '%s內', + past : '%s前', + s : '幾秒', + ss : '%d 秒', + m : '1 分鐘', + mm : '%d 分鐘', + h : '1 小時', + hh : '%d 小時', + d : '1 天', + dd : '%d 天', + M : '1 個月', + MM : '%d 個月', + y : '1 年', + yy : '%d 年' + } +}); diff --git a/nodejs/node_modules/moment/src/moment.js b/nodejs/node_modules/moment/src/moment.js new file mode 100755 index 0000000..9516d28 --- /dev/null +++ b/nodejs/node_modules/moment/src/moment.js @@ -0,0 +1,95 @@ +//! moment.js +//! version : 2.22.2 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com + +import { hooks as moment, setHookCallback } from './lib/utils/hooks'; + +moment.version = '2.22.2'; + +import { + min, + max, + now, + isMoment, + momentPrototype as fn, + createUTC as utc, + createUnix as unix, + createLocal as local, + createInvalid as invalid, + createInZone as parseZone +} from './lib/moment/moment'; + +import { + getCalendarFormat +} from './lib/moment/calendar'; + +import { + defineLocale, + updateLocale, + getSetGlobalLocale as locale, + getLocale as localeData, + listLocales as locales, + listMonths as months, + listMonthsShort as monthsShort, + listWeekdays as weekdays, + listWeekdaysMin as weekdaysMin, + listWeekdaysShort as weekdaysShort +} from './lib/locale/locale'; + +import { + isDuration, + createDuration as duration, + getSetRelativeTimeRounding as relativeTimeRounding, + getSetRelativeTimeThreshold as relativeTimeThreshold +} from './lib/duration/duration'; + +import { normalizeUnits } from './lib/units/units'; + +import isDate from './lib/utils/is-date'; + +setHookCallback(local); + +moment.fn = fn; +moment.min = min; +moment.max = max; +moment.now = now; +moment.utc = utc; +moment.unix = unix; +moment.months = months; +moment.isDate = isDate; +moment.locale = locale; +moment.invalid = invalid; +moment.duration = duration; +moment.isMoment = isMoment; +moment.weekdays = weekdays; +moment.parseZone = parseZone; +moment.localeData = localeData; +moment.isDuration = isDuration; +moment.monthsShort = monthsShort; +moment.weekdaysMin = weekdaysMin; +moment.defineLocale = defineLocale; +moment.updateLocale = updateLocale; +moment.locales = locales; +moment.weekdaysShort = weekdaysShort; +moment.normalizeUnits = normalizeUnits; +moment.relativeTimeRounding = relativeTimeRounding; +moment.relativeTimeThreshold = relativeTimeThreshold; +moment.calendarFormat = getCalendarFormat; +moment.prototype = fn; + +// currently HTML5 input type only supports 24-hour formats +moment.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'YYYY-[W]WW', // + MONTH: 'YYYY-MM' // +}; + +export default moment; diff --git a/nodejs/node_modules/node-schedule/.eslintrc b/nodejs/node_modules/node-schedule/.eslintrc new file mode 100755 index 0000000..d564a82 --- /dev/null +++ b/nodejs/node_modules/node-schedule/.eslintrc @@ -0,0 +1,17 @@ +{ + "env": { + "node": true, + "es6": true + }, + "rules": { + "eqeqeq": ["error", "smart"], + "indent": ["error", 2, { "SwitchCase": 1 }], + "no-constant-condition": "off", + "no-redeclare": "warn", + "no-underscore-dangle": "off", + "no-use-before-define": ["warn","nofunc"], + "quotes": ["error", "single"], + "space-before-blocks": "error", + "strict": "error" + } +} diff --git a/nodejs/node_modules/node-schedule/.travis.yml b/nodejs/node_modules/node-schedule/.travis.yml new file mode 100755 index 0000000..a560547 --- /dev/null +++ b/nodejs/node_modules/node-schedule/.travis.yml @@ -0,0 +1,15 @@ +language: node_js +node_js: + - "0.12" + - "0.10" + - "4" + - "6" + - "7" +before_script: > + if nvm ls-remote --lts | grep "$(nvm current)"; then + echo "running on a LTS node version, linting" + npm test + else + echo "running on a non-LTS node version, skipping linting" + fi +script: ./node_modules/.bin/istanbul cover ./node_modules/.bin/nodeunit test && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage diff --git a/nodejs/node_modules/node-schedule/CONTRIBUTING.md b/nodejs/node_modules/node-schedule/CONTRIBUTING.md new file mode 100755 index 0000000..ebb0783 --- /dev/null +++ b/nodejs/node_modules/node-schedule/CONTRIBUTING.md @@ -0,0 +1,31 @@ +## Rules +1. **No `--force` pushes** or modifying the git history in any way +2. Follow existing code style +3. Pull requests with tests are much more likely to be accepted +4. Follow the guidelines below + +## Bugfix or Feature? + +This project uses the [gitflow workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow). Simply put, you need to decide if your contribution will be a bug fix that could be released as a patch, or a feature that will end up being a minor or major release. + +### Found a bug that can be fixed without affecting the API? + +1. **Fork** this repo +2. Create a new branch from `master` to work in +3. **Add tests** if needed +4. Make sure your code **lints** by running `npm run lint` +5. Make sure your code **passes tests** by running `npm test` +6. Submit a **pull request** against the `master` branch + +### New feature or anything that would result in a change to the API? + +1. **Fork** this repo +2. Create a new branch from `develop` to work in +3. **Add tests** to as needed +4. Make sure your code **lints** by running `npm run lint` +5. Make sure your code **passes tests** by running `npm test` +6. Submit a **pull request** against the `develop` branch + +## Releases + +Declaring formal releases remains the prerogative of the project maintainer. diff --git a/nodejs/node_modules/node-schedule/LICENSE b/nodejs/node_modules/node-schedule/LICENSE new file mode 100755 index 0000000..6ead200 --- /dev/null +++ b/nodejs/node_modules/node-schedule/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2015 Matt Patenaude. + +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/nodejs/node_modules/node-schedule/README.md b/nodejs/node_modules/node-schedule/README.md new file mode 100755 index 0000000..0c371f6 --- /dev/null +++ b/nodejs/node_modules/node-schedule/README.md @@ -0,0 +1,256 @@ +# Node Schedule + +[![NPM version](http://img.shields.io/npm/v/node-schedule.svg)](https://www.npmjs.com/package/node-schedule) +[![Downloads](https://img.shields.io/npm/dm/node-schedule.svg)](https://www.npmjs.com/package/node-schedule) +[![Build Status](https://travis-ci.org/node-schedule/node-schedule.svg?branch=master)](https://travis-ci.org/node-schedule/node-schedule) +[![Join the chat at https://gitter.im/node-schedule/node-schedule](https://img.shields.io/badge/gitter-chat-green.svg)](https://gitter.im/node-schedule/node-schedule?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +[![NPM](https://nodei.co/npm/node-schedule.png?downloads=true)](https://nodei.co/npm/node-schedule/) + +Node Schedule is a flexible cron-like and not-cron-like job scheduler for Node.js. +It allows you to schedule jobs (arbitrary functions) for execution at +specific dates, with optional recurrence rules. It only uses a single timer +at any given time (rather than reevaluating upcoming jobs every second/minute). + +## Usage + +### Installation + +You can install using [npm](https://www.npmjs.com/package/node-schedule). + +``` +npm install node-schedule +``` + +### Overview + +Node Schedule is for time-based scheduling, not interval-based scheduling. +While you can easily bend it to your will, if you only want to do something like +"run this function every 5 minutes", you'll find `setInterval` much easier to use, +and far more appropriate. But if you want to, say, "run this function at the :20 +and :50 of every hour on the third Tuesday of every month," you'll find that +Node Schedule suits your needs better. Additionally, Node Schedule has Windows +support unlike true cron since the node runtime is now fully supported. + +Note that Node Schedule is designed for in-process scheduling, i.e. scheduled jobs +will only fire as long as your script is running, and the schedule will disappear +when execution completes. If you need to schedule jobs that will persist even when +your script *isn't* running, consider using actual [cron]. + +### Jobs and Scheduling + +Every scheduled job in Node Schedule is represented by a `Job` object. You can +create jobs manually, then execute the `schedule()` method to apply a schedule, +or use the convenience function `scheduleJob()` as demonstrated below. + +`Job` objects are `EventEmitter`'s, and emit a `run` event after each execution. +They also emit a `scheduled` event each time they're scheduled to run, and a +`canceled` event when an invocation is canceled before it's executed (both events +receive a JavaScript date object as a parameter). Note that jobs are scheduled the +first time immediately, so if you create a job using the `scheduleJob()` +convenience method, you'll miss the first `scheduled` event, but you can query the +invocation manually (see below). Also note that `canceled` is the single-L American +spelling. + +### Cron-style Scheduling + +The cron format consists of: +``` +* * * * * * +┬ ┬ ┬ ┬ ┬ ┬ +│ │ │ │ │ │ +│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun) +│ │ │ │ └───── month (1 - 12) +│ │ │ └────────── day of month (1 - 31) +│ │ └─────────────── hour (0 - 23) +│ └──────────────────── minute (0 - 59) +└───────────────────────── second (0 - 59, OPTIONAL) +``` + +Examples with the cron format: + +```js +var schedule = require('node-schedule'); + +var j = schedule.scheduleJob('42 * * * *', function(){ + console.log('The answer to life, the universe, and everything!'); +}); +``` + +Execute a cron job when the minute is 42 (e.g. 19:42, 20:42, etc.). + +And: + +```js +var j = schedule.scheduleJob('0 17 ? * 0,4-6', function(){ + console.log('Today is recognized by Rebecca Black!'); +}); +``` + +Execute a cron job every 5 Minutes = */5 * * * * + +You can also get when it is scheduled to run for every invocation of the job: +```js +var j = schedule.scheduleJob('0 1 * * *', function(fireDate){ + console.log('This job was supposed to run at ' + fireDate + ', but actually ran at ' + new Date()); +}); +``` +This is useful when you need to check if there is a delay of the job invocation when the system is busy, or save a record of all invocations of a job for audit purpose. +#### Unsupported Cron Features + +Currently, `W` (nearest weekday), `L` (last day of month/week), and `#` (nth weekday +of the month) are not supported. Most other features supported by popular cron +implementations should work just fine. + +[cron-parser] is used to parse crontab instructions. + +### Date-based Scheduling + +Say you very specifically want a function to execute at 5:30am on December 21, 2012. +Remember - in JavaScript - 0 - January, 11 - December. + +```js +var schedule = require('node-schedule'); +var date = new Date(2012, 11, 21, 5, 30, 0); + +var j = schedule.scheduleJob(date, function(){ + console.log('The world is going to end today.'); +}); +``` + +To use current data in the future you can use binding: + +```js +var schedule = require('node-schedule'); +var date = new Date(2012, 11, 21, 5, 30, 0); +var x = 'Tada!'; +var j = schedule.scheduleJob(date, function(y){ + console.log(y); +}.bind(null,x)); +x = 'Changing Data'; +``` +This will log 'Tada!' when the scheduled Job runs, rather than 'Changing Data', +which x changes to immediately after scheduling. + +### Recurrence Rule Scheduling + +You can build recurrence rules to specify when a job should recur. For instance, +consider this rule, which executes the function every hour at 42 minutes after the hour: + +```js +var schedule = require('node-schedule'); + +var rule = new schedule.RecurrenceRule(); +rule.minute = 42; + +var j = schedule.scheduleJob(rule, function(){ + console.log('The answer to life, the universe, and everything!'); +}); +``` + +You can also use arrays to specify a list of acceptable values, and the `Range` +object to specify a range of start and end values, with an optional step parameter. +For instance, this will print a message on Thursday, Friday, Saturday, and Sunday at 5pm: + +```js +var rule = new schedule.RecurrenceRule(); +rule.dayOfWeek = [0, new schedule.Range(4, 6)]; +rule.hour = 17; +rule.minute = 0; + +var j = schedule.scheduleJob(rule, function(){ + console.log('Today is recognized by Rebecca Black!'); +}); +``` + +#### RecurrenceRule properties + +- `second` +- `minute` +- `hour` +- `date` +- `month` +- `year` +- `dayOfWeek` + +> **Note**: It's worth noting that the default value of a component of a recurrence rule is +> `null` (except for second, which is 0 for familiarity with cron). *If we did not +> explicitly set `minute` to 0 above, the message would have instead been logged at +> 5:00pm, 5:01pm, 5:02pm, ..., 5:59pm.* Probably not what you want. + +#### Object Literal Syntax + +To make things a little easier, an object literal syntax is also supported, like +in this example which will log a message every Sunday at 2:30pm: + +```js +var j = schedule.scheduleJob({hour: 14, minute: 30, dayOfWeek: 0}, function(){ + console.log('Time for tea!'); +}); +``` + +#### Set StartTime and EndTime + +It will run after 5 seconds and stop after 10 seconds in this example. +The ruledat supports the above. + +```js +let startTime = new Date(Date.now() + 5000); +let endTime = new Date(startTime.getTime() + 5000); +var j = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 * * * * *' }, function(){ + console.log('Time for tea!'); +}); +``` + +### Handle Jobs and Job Invocations + +There are some function to get informations for a Job and to handle the Job and +Invocations. + + +#### job.cancel(reshedule) +You can invalidate any job with the `cancel()` method: + +```js +j.cancel(); +``` +All planned invocations will be canceled. When you set the parameter ***reschedule*** +to true then the Job is newly scheduled afterwards. + +#### job.cancelNext(reshedule) +This method invalidates the next planned invocation or the job. +When you set the parameter ***reschedule*** to true then the Job is newly scheduled +afterwards. + +#### job.reschedule(spec) +This method cancels all pending invocation and registers the Job completely new again using the given specification. +Return true/false on success/failure. + +#### job.nextInvocation() +This method returns a Date object for the planned next Invocation for this Job. If no invocation is planned the method returns null. + +## Contributing + +This module was originally developed by [Matt Patenaude], and is now maintained by +[Tejas Manohar] and [other wonderful contributors]. + +We'd love to get your contributions. Individuals making significant and valuable +contributions are given commit-access to the project to contribute as they see fit. + +Before jumping in, check out our [Contributing] page guide! + +## Copyright and license + +Copyright 2015 Matt Patenaude. + +Licensed under the **[MIT License] [license]**. + + +[cron]: http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5 +[Contributing]: https://github.com/node-schedule/node-schedule/blob/master/CONTRIBUTING.md +[Matt Patenaude]: https://github.com/mattpat +[Tejas Manohar]: http://tejas.io +[license]: https://github.com/node-schedule/node-schedule/blob/master/LICENSE +[Tejas Manohar]: https://github.com/tejasmanohar +[other wonderful contributors]: https://github.com/node-schedule/node-schedule/graphs/contributors +[cron-parser]: https://github.com/harrisiirak/cron-parser diff --git a/nodejs/node_modules/node-schedule/lib/schedule.js b/nodejs/node_modules/node-schedule/lib/schedule.js new file mode 100755 index 0000000..64bdfbd --- /dev/null +++ b/nodejs/node_modules/node-schedule/lib/schedule.js @@ -0,0 +1,648 @@ + +'use strict'; + +/* + node-schedule + A cron-like and not-cron-like job scheduler for Node. +*/ + +var events = require('events'), + util = require('util'), + cronParser = require('cron-parser'), + CronDate = require('cron-parser/lib/date'), + lt = require('long-timeout'), + sorted = require('sorted-array-functions'); + +/* Job object */ +var anonJobCounter = 0; +var scheduledJobs = {}; + +function isValidDate(date) { + // Taken from http://stackoverflow.com/a/12372720/1562178 + // If getTime() returns NaN it'll return false anyway + return date.getTime() === date.getTime(); +} + +function Job(name, job, callback) { + // setup a private pendingInvocations variable + var pendingInvocations = []; + + //setup a private number of invocations variable + var triggeredJobs = 0; + + // Set scope vars + var jobName = name && typeof name === 'string' ? name : ''; + this.job = name && typeof name === 'function' ? name : job; + + // Make sure callback is actually a callback + if (this.job === name) { + // Name wasn't provided and maybe a callback is there + this.callback = typeof job === 'function' ? job : false; + } else { + // Name was provided, and maybe a callback is there + this.callback = typeof callback === 'function' ? callback : false; + } + + // Check for generator + if (typeof this.job === 'function' && + this.job.prototype && + this.job.prototype.next) { + this.job = function() { + return this.next().value; + }.bind(this.job.call(this)); + } + + // define properties + Object.defineProperty(this, 'name', { + value: jobName, + writable: false, + enumerable: true + }); + + // method that require private access + this.trackInvocation = function(invocation) { + // add to our invocation list + sorted.add(pendingInvocations, invocation, sorter); + return true; + }; + this.stopTrackingInvocation = function(invocation) { + var invIdx = pendingInvocations.indexOf(invocation); + if (invIdx > -1) { + pendingInvocations.splice(invIdx, 1); + return true; + } + + return false; + }; + this.triggeredJobs = function() { + return triggeredJobs; + }; + this.setTriggeredJobs = function(triggeredJob) { + triggeredJobs = triggeredJob; + }; + this.cancel = function(reschedule) { + reschedule = (typeof reschedule == 'boolean') ? reschedule : false; + + var inv, newInv; + var newInvs = []; + for (var j = 0; j < pendingInvocations.length; j++) { + inv = pendingInvocations[j]; + + cancelInvocation(inv); + + if (reschedule && inv.recurrenceRule.recurs) { + newInv = scheduleNextRecurrence(inv.recurrenceRule, this, inv.fireDate, inv.endDate); + if (newInv !== null) { + newInvs.push(newInv); + } + } + } + + pendingInvocations = []; + + for (var k = 0; k < newInvs.length; k++) { + this.trackInvocation(newInvs[k]); + } + + // remove from scheduledJobs if reschedule === false + if (!reschedule) { + if (this.name) { + delete scheduledJobs[this.name]; + } + } + + return true; + }; + this.cancelNext = function(reschedule) { + reschedule = (typeof reschedule == 'boolean') ? reschedule : true; + + if (!pendingInvocations.length) { + return false; + } + + var newInv; + var nextInv = pendingInvocations.shift(); + + cancelInvocation(nextInv); + + if (reschedule && nextInv.recurrenceRule.recurs) { + newInv = scheduleNextRecurrence(nextInv.recurrenceRule, this, nextInv.fireDate, nextInv.endDate); + if (newInv !== null) { + this.trackInvocation(newInv); + } + } + + return true; + }; + this.reschedule = function(spec) { + var inv; + var cInvs = pendingInvocations.slice(); + + for (var j = 0; j < cInvs.length; j++) { + inv = cInvs[j]; + + cancelInvocation(inv); + } + + pendingInvocations = []; + + if (this.schedule(spec)) { + this.setTriggeredJobs(0); + return true; + } else { + pendingInvocations = cInvs; + return false; + } + }; + this.nextInvocation = function() { + if (!pendingInvocations.length) { + return null; + } + return pendingInvocations[0].fireDate; + }; + this.pendingInvocations = function() { + return pendingInvocations; + }; +} + +util.inherits(Job, events.EventEmitter); + +Job.prototype.invoke = function(fireDate) { + if (typeof this.job == 'function') { + this.setTriggeredJobs(this.triggeredJobs() + 1); + this.job(fireDate); + } else { + this.job.execute(fireDate); + } +}; + +Job.prototype.runOnDate = function(date) { + return this.schedule(date); +}; + +Job.prototype.schedule = function(spec) { + var self = this; + var success = false; + var inv; + var start; + var end; + var tz; + + if (typeof spec === 'object' && spec.rule) { + start = spec.start || undefined; + end = spec.end || undefined; + tz = spec.tz; + spec = spec.rule; + + if (start) { + if (!(start instanceof Date)) { + start = new Date(start); + } + + start = new CronDate(start, tz); + if (!isValidDate(start) || start.getTime() < Date.now()) { + start = undefined; + } + } + + if (end && !(end instanceof Date) && !isValidDate(end = new Date(end))) { + end = undefined; + } + + if (end) { + end = new CronDate(end, tz); + } + } + + try { + var res = cronParser.parseExpression(spec, { currentDate: start, tz: tz }); + inv = scheduleNextRecurrence(res, self, start, end); + if (inv !== null) { + success = self.trackInvocation(inv); + } + } catch (err) { + var type = typeof spec; + if ((type === 'string') || (type === 'number')) { + spec = new Date(spec); + } + + if ((spec instanceof Date) && (isValidDate(spec))) { + spec = new CronDate(spec); + if (spec.getTime() >= Date.now()) { + inv = new Invocation(self, spec); + scheduleInvocation(inv); + success = self.trackInvocation(inv); + } + } else if (type === 'object') { + if (!(spec instanceof RecurrenceRule)) { + var r = new RecurrenceRule(); + if ('year' in spec) { + r.year = spec.year; + } + if ('month' in spec) { + r.month = spec.month; + } + if ('date' in spec) { + r.date = spec.date; + } + if ('dayOfWeek' in spec) { + r.dayOfWeek = spec.dayOfWeek; + } + if ('hour' in spec) { + r.hour = spec.hour; + } + if ('minute' in spec) { + r.minute = spec.minute; + } + if ('second' in spec) { + r.second = spec.second; + } + + spec = r; + } + + spec.tz = tz; + inv = scheduleNextRecurrence(spec, self, start, end); + if (inv !== null) { + success = self.trackInvocation(inv); + } + } + } + + scheduledJobs[this.name] = this; + return success; +}; + +/* API + invoke() + runOnDate(date) + schedule(date || recurrenceRule || cronstring) + cancel(reschedule = false) + cancelNext(reschedule = true) + + Property constraints + name: readonly + job: readwrite +*/ + +/* DoesntRecur rule */ +var DoesntRecur = new RecurrenceRule(); +DoesntRecur.recurs = false; + +/* Invocation object */ +function Invocation(job, fireDate, recurrenceRule, endDate) { + this.job = job; + this.fireDate = fireDate; + this.endDate = endDate; + this.recurrenceRule = recurrenceRule || DoesntRecur; + + this.timerID = null; +} + +function sorter(a, b) { + return (a.fireDate.getTime() - b.fireDate.getTime()); +} + +/* Range object */ +function Range(start, end, step) { + this.start = start || 0; + this.end = end || 60; + this.step = step || 1; +} + +Range.prototype.contains = function(val) { + if (this.step === null || this.step === 1) { + return (val >= this.start && val <= this.end); + } else { + for (var i = this.start; i < this.end; i += this.step) { + if (i === val) { + return true; + } + } + + return false; + } +}; + +/* RecurrenceRule object */ +/* + Interpreting each property: + null - any value is valid + number - fixed value + Range - value must fall in range + array - value must validate against any item in list + + NOTE: Cron months are 1-based, but RecurrenceRule months are 0-based. +*/ +function RecurrenceRule(year, month, date, dayOfWeek, hour, minute, second) { + this.recurs = true; + + this.year = (year == null) ? null : year; + this.month = (month == null) ? null : month; + this.date = (date == null) ? null : date; + this.dayOfWeek = (dayOfWeek == null) ? null : dayOfWeek; + this.hour = (hour == null) ? null : hour; + this.minute = (minute == null) ? null : minute; + this.second = (second == null) ? 0 : second; +} + +RecurrenceRule.prototype.isValid = function() { + function isValidType(num) { + if (Array.isArray(num) || (num instanceof Array)) { + return num.every(function(e) { + return isValidType(e); + }); + } + return !(Number.isNaN(Number(num)) && !(num instanceof Range)); + } + if (this.month !== null && (this.month < 0 || this.month > 11 || !isValidType(this.month))) { + return false; + } + if (this.dayOfWeek !== null && (this.dayOfWeek < 0 || this.dayOfWeek > 6 || !isValidType(this.dayOfWeek))) { + return false; + } + if (this.hour !== null && (this.hour < 0 || this.hour > 23 || !isValidType(this.hour))) { + return false; + } + if (this.minute !== null && (this.minute < 0 || this.minute > 59 || !isValidType(this.minute))) { + return false; + } + if (this.second !== null && (this.second < 0 || this.second > 59 || !isValidType(this.second))) { + return false; + } + if (this.date !== null) { + if(!isValidType(this.date)) { + return false; + } + switch (this.month) { + case 3: + case 5: + case 8: + case 10: + if (this.date < 1 || this. date > 30) { + return false; + } + break; + case 1: + if (this.date < 1 || this. date > 29) { + return false; + } + break; + default: + if (this.date < 1 || this. date > 31) { + return false; + } + } + } + return true; +}; + +RecurrenceRule.prototype.nextInvocationDate = function(base) { + base = ((base instanceof CronDate) || (base instanceof Date)) ? base : (new Date()); + if (!this.recurs) { + return null; + } + + if(!this.isValid()) { + return null; + } + + var now = new CronDate(Date.now(), this.tz); + var fullYear = now.getFullYear(); + if ((this.year !== null) && + (typeof this.year == 'number') && + (this.year < fullYear)) { + return null; + } + + var next = new CronDate(base.getTime(), this.tz); + next.addSecond(); + + while (true) { + if (this.year !== null) { + fullYear = next.getFullYear(); + if ((typeof this.year == 'number') && (this.year < fullYear)) { + next = null; + break; + } + + if (!recurMatch(fullYear, this.year)) { + next.addYear(); + next.setMonth(0); + next.setDate(1); + next.setHours(0); + next.setMinutes(0); + next.setSeconds(0); + continue; + } + } + if (this.month != null && !recurMatch(next.getMonth(), this.month)) { + next.addMonth(); + continue; + } + if (this.date != null && !recurMatch(next.getDate(), this.date)) { + next.addDay(); + continue; + } + if (this.dayOfWeek != null && !recurMatch(next.getDay(), this.dayOfWeek)) { + next.addDay(); + continue; + } + if (this.hour != null && !recurMatch(next.getHours(), this.hour)) { + next.addHour(); + continue; + } + if (this.minute != null && !recurMatch(next.getMinutes(), this.minute)) { + next.addMinute(); + continue; + } + if (this.second != null && !recurMatch(next.getSeconds(), this.second)) { + next.addSecond(); + continue; + } + + break; + } + + return next ? next.toDate() : null; +}; + +function recurMatch(val, matcher) { + if (matcher == null) { + return true; + } + + if (typeof matcher === 'number') { + return (val === matcher); + } else if(typeof matcher === 'string') { + return (val === Number(matcher)); + } else if (matcher instanceof Range) { + return matcher.contains(val); + } else if (Array.isArray(matcher) || (matcher instanceof Array)) { + for (var i = 0; i < matcher.length; i++) { + if (recurMatch(val, matcher[i])) { + return true; + } + } + } + + return false; +} + +/* Date-based scheduler */ +function runOnDate(date, job) { + var now = Date.now(); + var then = date.getTime(); + + return lt.setTimeout(function() { + if (then > Date.now()) + runOnDate(date, job); + else + job(); + }, (then < now ? 0 : then - now)); +} + +var invocations = []; +var currentInvocation = null; + +function scheduleInvocation(invocation) { + sorted.add(invocations, invocation, sorter); + prepareNextInvocation(); + var date = invocation.fireDate instanceof CronDate ? invocation.fireDate.toDate() : invocation.fireDate; + invocation.job.emit('scheduled', date); +} + +function prepareNextInvocation() { + if (invocations.length > 0 && currentInvocation !== invocations[0]) { + if (currentInvocation !== null) { + lt.clearTimeout(currentInvocation.timerID); + currentInvocation.timerID = null; + currentInvocation = null; + } + + currentInvocation = invocations[0]; + + var job = currentInvocation.job; + var cinv = currentInvocation; + currentInvocation.timerID = runOnDate(currentInvocation.fireDate, function() { + currentInvocationFinished(); + + if (job.callback) { + job.callback(); + } + + if (cinv.recurrenceRule.recurs || cinv.recurrenceRule._endDate === null) { + var inv = scheduleNextRecurrence(cinv.recurrenceRule, cinv.job, cinv.fireDate, cinv.endDate); + if (inv !== null) { + inv.job.trackInvocation(inv); + } + } + + job.stopTrackingInvocation(cinv); + + job.invoke(cinv.fireDate instanceof CronDate ? cinv.fireDate.toDate() : cinv.fireDate); + job.emit('run'); + }); + } +} + +function currentInvocationFinished() { + invocations.shift(); + currentInvocation = null; + prepareNextInvocation(); +} + +function cancelInvocation(invocation) { + var idx = invocations.indexOf(invocation); + if (idx > -1) { + invocations.splice(idx, 1); + if (invocation.timerID !== null) { + lt.clearTimeout(invocation.timerID); + } + + if (currentInvocation === invocation) { + currentInvocation = null; + } + + invocation.job.emit('canceled', invocation.fireDate); + prepareNextInvocation(); + } +} + +/* Recurrence scheduler */ +function scheduleNextRecurrence(rule, job, prevDate, endDate) { + + prevDate = (prevDate instanceof CronDate) ? prevDate : new CronDate(); + + var date = (rule instanceof RecurrenceRule) ? rule.nextInvocationDate(prevDate) : rule.next(); + if (date === null) { + return null; + } + + if ((endDate instanceof CronDate) && date.getTime() > endDate.getTime()) { + return null; + } + + var inv = new Invocation(job, date, rule, endDate); + scheduleInvocation(inv); + + return inv; +} + +/* Convenience methods */ +function scheduleJob() { + if (arguments.length < 2) { + return null; + } + + var name = (arguments.length >= 3 && typeof arguments[0] === 'string') ? arguments[0] : null; + var spec = name ? arguments[1] : arguments[0]; + var method = name ? arguments[2] : arguments[1]; + var callback = name ? arguments[3] : arguments[2]; + + var job = new Job(name, method, callback); + + if (job.schedule(spec)) { + return job; + } + + return null; +} + +function rescheduleJob(job, spec) { + if (job instanceof Job) { + if (job.reschedule(spec)) { + return job; + } + } else if (typeof job == 'string' || job instanceof String) { + if (job in scheduledJobs && scheduledJobs.hasOwnProperty(job)) { + if (scheduledJobs[job].reschedule(spec)) { + return scheduledJobs[job]; + } + } + } + return null; +} + +function cancelJob(job) { + var success = false; + if (job instanceof Job) { + success = job.cancel(); + } else if (typeof job == 'string' || job instanceof String) { + if (job in scheduledJobs && scheduledJobs.hasOwnProperty(job)) { + success = scheduledJobs[job].cancel(); + } + } + + return success; +} + +/* Public API */ +module.exports.Job = Job; +module.exports.Range = Range; +module.exports.RecurrenceRule = RecurrenceRule; +module.exports.Invocation = Invocation; +module.exports.scheduleJob = scheduleJob; +module.exports.rescheduleJob = rescheduleJob; +module.exports.scheduledJobs = scheduledJobs; +module.exports.cancelJob = cancelJob; diff --git a/nodejs/node_modules/node-schedule/package.json b/nodejs/node_modules/node-schedule/package.json new file mode 100755 index 0000000..1fd4317 --- /dev/null +++ b/nodejs/node_modules/node-schedule/package.json @@ -0,0 +1,70 @@ +{ + "_args": [ + [ + "node-schedule@1.3.0", + "/www/wwwroot/Adminx.cc/nodejs" + ] + ], + "_from": "node-schedule@1.3.0", + "_id": "node-schedule@1.3.0", + "_inBundle": false, + "_integrity": "sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A==", + "_location": "/node-schedule", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "node-schedule@1.3.0", + "name": "node-schedule", + "escapedName": "node-schedule", + "rawSpec": "1.3.0", + "saveSpec": null, + "fetchSpec": "1.3.0" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-1.3.0.tgz", + "_spec": "1.3.0", + "_where": "/www/wwwroot/Adminx.cc/nodejs", + "author": { + "name": "Matt Patenaude", + "email": "matt@mattpatenaude.com", + "url": "http://mattpatenaude.com" + }, + "bugs": { + "url": "https://github.com/node-schedule/node-schedule/issues" + }, + "dependencies": { + "cron-parser": "^2.4.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.0.0" + }, + "description": "A cron-like and not-cron-like job scheduler for Node.", + "devDependencies": { + "coveralls": "^2.11.2", + "eslint": "^3.19.0", + "istanbul": "^0.4.5", + "nodeunit": "^0.10.2", + "sinon": "^1.14.1" + }, + "homepage": "https://github.com/node-schedule/node-schedule#readme", + "keywords": [ + "schedule", + "task", + "job", + "cron" + ], + "license": "MIT", + "main": "./lib/schedule.js", + "name": "node-schedule", + "repository": { + "type": "git", + "url": "git+https://github.com/node-schedule/node-schedule.git" + }, + "scripts": { + "lint": "eslint lib test", + "test": "nodeunit" + }, + "version": "1.3.0" +} diff --git a/nodejs/node_modules/node-schedule/test/.eslintrc b/nodejs/node_modules/node-schedule/test/.eslintrc new file mode 100755 index 0000000..194f187 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/.eslintrc @@ -0,0 +1,5 @@ +{ + "rules": { + "quotes": ["off"] + } +} diff --git a/nodejs/node_modules/node-schedule/test/cancel-long-running-jobs.js b/nodejs/node_modules/node-schedule/test/cancel-long-running-jobs.js new file mode 100755 index 0000000..9ea3897 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/cancel-long-running-jobs.js @@ -0,0 +1,24 @@ +'use strict'; + +var schedule = require('../lib/schedule'); + +module.exports = { + 'Cancel Long Running Job': { + 'should work even when recurring jobs are to be run on the past': function (test) { + var ok = true; + var job = schedule.scheduleJob('*/1 * * * * *', function () { + test.ok(ok); + var time = Date.now(); + while (ok && (Date.now() - time < 2000)) { + } + }); + + test.ok(job); + setTimeout(function () { + job.cancel(); + test.done(); + ok = false; + }, 2100); + } + } +}; diff --git a/nodejs/node_modules/node-schedule/test/convenience-method-test.js b/nodejs/node_modules/node-schedule/test/convenience-method-test.js new file mode 100755 index 0000000..a4a58a0 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/convenience-method-test.js @@ -0,0 +1,713 @@ + +'use strict'; + +var sinon = require('sinon'); +var main = require('../package.json').main; +var schedule = require('../' + main); + +var clock; + +module.exports = { + setUp: function(cb) { + clock = sinon.useFakeTimers(); + cb(); + }, + ".scheduleJob": { + "Returns Job instance": function(test) { + var job = schedule.scheduleJob(new Date(Date.now() + 1000), function() {}); + + test.ok(job instanceof schedule.Job); + + job.cancel(); + test.done(); + } + }, + ".scheduleJob(Date, fn)": { + "Runs job once at some date": function(test) { + test.expect(1); + + schedule.scheduleJob(new Date(Date.now() + 3000), function() { + test.ok(true); + }); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job doesn't emit initial 'scheduled' event": function(test) { + var job = schedule.scheduleJob(new Date(Date.now() + 1000), function() {}); + + job.on('scheduled', function() { + test.ok(false); + }); + + setTimeout(function() { + test.done(); + }, 1250); + + clock.tick(1250); + }, + "Won't run job if scheduled in the past": function(test) { + test.expect(1); + var job = schedule.scheduleJob(new Date(Date.now() - 3000), function() { + test.ok(false); + }); + + test.equal(job, null); + + setTimeout(function() { + test.done(); + }, 1000); + + clock.tick(1000); + } + }, + ".scheduleJob(RecurrenceRule, fn)": { + "Runs job at interval based on recur rule, repeating indefinitely": function(test) { + test.expect(3); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job doesn't emit initial 'scheduled' event": function(test) { + /* + * If this was Job#schedule it'd fire 4 times. + */ + test.expect(3); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = new schedule.scheduleJob(rule, function() {}); + + job.on('scheduled', function(runOnDate) { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Doesn't invoke job if recur rule schedules it in the past": function(test) { + test.expect(1); + var rule = new schedule.RecurrenceRule(); + rule.year = 1960; + + var job = schedule.scheduleJob(rule, function() { + test.ok(false); + }); + + test.equal(job, null); + + setTimeout(function() { + test.done(); + }, 1000); + + clock.tick(1000); + } + }, + ".scheduleJob({...}, fn)": { + "Runs job at interval based on object, repeating indefinitely": function(test) { + test.expect(3); + + var job = new schedule.scheduleJob({ + second: null // Fire every second + }, function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job doesn't emit initial 'scheduled' event": function(test) { + /* + * With Job#schedule this would be 3: + * scheduled at time 0 + * scheduled at time 1000 + * scheduled at time 2000 + */ + test.expect(2); + + var job = schedule.scheduleJob({ + second: null // fire every second + }, function() {}); + + job.on('scheduled', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 2250); + + clock.tick(2250); + }, + "Doesn't invoke job if object schedules it in the past": function(test) { + test.expect(1); + + var job = schedule.scheduleJob({ + year: 1960 + }, function() { + test.ok(false); + }); + + test.equal(job, null); + + setTimeout(function() { + test.done(); + }, 1000); + + clock.tick(1000); + } + }, + ".scheduleJob({...}, {...}, fn)": { + "Callback called for each job if callback is provided": function(test) { + test.expect(3); + + var job = new schedule.scheduleJob({ + second: null // Fire every second + }, function() {}, function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + ".rescheduleJob(job, {...})": { + "Reschedule jobs from object based to object based": function(test) { + test.expect(3); + + var job = new schedule.scheduleJob({ + second: null + }, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job, { + minute: null + }); + }, 3250); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 5000); + + clock.tick(5000); + }, + "Reschedule jobs from every minutes to every second": function(test) { + test.expect(3); + + var timeout = 60 * 1000; + + var job = new schedule.scheduleJob({ + minute: null + }, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job, { + second: null + }); + }, timeout); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout + 2250); + + clock.tick(timeout + 2250); + } + }, + ".rescheduleJob(job, Date)": { + "Reschedule jobs from Date to Date": function(test) { + test.expect(1); + + var job = new schedule.scheduleJob(new Date(Date.now() + 3000), function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job, new Date(Date.now() + 5000)); + }, 1000); + + setTimeout(function() { + test.done(); + }, 6150); + + clock.tick(6150); + }, + "Reschedule jobs that has been executed": function(test) { + test.expect(2); + + var job = new schedule.scheduleJob(new Date(Date.now() + 1000), function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job, new Date(Date.now() + 2000)); + }, 2000); + + setTimeout(function() { + test.done(); + }, 5150); + + clock.tick(5150); + } + }, + ".rescheduleJob(job, RecurrenceRule)": { + "Reschedule jobs from RecurrenceRule to RecurrenceRule": function(test) { + test.expect(3); + + var timeout = 60 * 1000; + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + var newRule = new schedule.RecurrenceRule(); + newRule.minute = null; + + setTimeout(function() { + schedule.rescheduleJob(job, newRule); + }, 2250); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout + 2250); + + clock.tick(timeout + 2250); + }, + "Reschedule jobs from RecurrenceRule to Date": function(test) { + test.expect(3); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job, new Date(Date.now() + 2000)); + }, 2150); + + setTimeout(function() { + test.done(); + }, 4250); + + clock.tick(4250); + }, + "Reschedule jobs from RecurrenceRule to {...}": function(test) { + test.expect(3); + + var timeout = 60 * 1000; + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job, { + minute: null + }); + }, 2150); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout + 2150); + + clock.tick(timeout + 2150); + }, + "Reschedule jobs that is not available": function(test) { + test.expect(4); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(null, new Date(Date.now() + 2000)); + }, 2150); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 4250); + + clock.tick(4250); + } + }, + '.rescheduleJob("job name", {...})': { + "Reschedule jobs from object based to object based": function(test) { + test.expect(3); + + var job = new schedule.scheduleJob({ + second: null + }, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job.name, { + minute: null + }); + }, 3250); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 5000); + + clock.tick(5000); + }, + "Reschedule jobs from every minutes to every second": function(test) { + test.expect(3); + + var timeout = 60 * 1000; + + var job = new schedule.scheduleJob({ + minute: null + }, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job.name, { + second: null + }); + }, timeout); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout + 2250); + + clock.tick(timeout + 2250); + } + }, + '.rescheduleJob("job name", Date)': { + "Reschedule jobs from Date to Date": function(test) { + test.expect(1); + + var job = new schedule.scheduleJob(new Date(Date.now() + 3000), function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job.name, new Date(Date.now() + 5000)); + }, 1000); + + setTimeout(function() { + test.done(); + }, 6150); + + clock.tick(6150); + }, + "Reschedule jobs that has been executed": function(test) { + test.expect(2); + + var job = new schedule.scheduleJob(new Date(Date.now() + 1000), function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job.name, new Date(Date.now() + 2000)); + }, 2000); + + setTimeout(function() { + test.done(); + }, 5150); + + clock.tick(5150); + } + }, + '.rescheduleJob("job name", RecurrenceRule)': { + "Reschedule jobs from RecurrenceRule to RecurrenceRule": function(test) { + test.expect(3); + + var timeout = 60 * 1000; + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + var newRule = new schedule.RecurrenceRule(); + newRule.minute = null; + + setTimeout(function() { + schedule.rescheduleJob(job.name, newRule); + }, 2250); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout + 2250); + + clock.tick(timeout + 2250); + }, + "Reschedule jobs from RecurrenceRule to Date": function(test) { + test.expect(3); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job.name, new Date(Date.now() + 2000)); + }, 2150); + + setTimeout(function() { + test.done(); + }, 4250); + + clock.tick(4250); + }, + "Reschedule jobs from RecurrenceRule to {...}": function(test) { + test.expect(3); + + var timeout = 60 * 1000; + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob(job.name, { + minute: null + }); + }, 2150); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout + 2150); + + clock.tick(timeout + 2150); + }, + "Reschedule jobs that is not available": function(test) { + test.expect(4); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + var job = schedule.scheduleJob(rule, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.rescheduleJob("Blah", new Date(Date.now() + 2000)); + }, 2150); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 4250); + + clock.tick(4250); + } + }, + ".cancelJob(Job)": { + "Prevents all future invocations of Job passed in": function(test) { + test.expect(2); + + var job = schedule.scheduleJob({ + second: null + }, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.cancelJob(job); + }, 2250); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Can cancel Jobs scheduled with Job#schedule": function(test) { + test.expect(2); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.schedule({ + second: null + }); + + setTimeout(function() { + schedule.cancelJob(job); + }, 2250); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job emits 'canceled' event": function(test) { + test.expect(1); + + var job = schedule.scheduleJob({ + second: null + }, function() {}); + + job.on('canceled', function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.cancelJob(job); + test.done(); + }, 1250); + + clock.tick(1250); + } + }, + '.cancelJob("job name")': { + "Prevents all future invocations of Job identified by name": function(test) { + test.expect(2); + + var job = schedule.scheduleJob({ + second: null + }, function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.cancelJob(job.name); + }, 2250); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + /* + "Can cancel Jobs scheduled with Job#schedule": function(test) { + test.expect(2); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.schedule({ + second: null + }); + + setTimeout(function() { + schedule.cancelJob(job.name); + }, 2250); + + setTimeout(function() { + test.done(); + }, 3250); + },*/ + "Job emits 'canceled' event": function(test) { + test.expect(1); + + var job = schedule.scheduleJob({ + second: null + }, function() {}); + + job.on('canceled', function() { + test.ok(true); + }); + + setTimeout(function() { + schedule.cancelJob(job.name); + test.done(); + }, 1250); + + clock.tick(1250); + }, + "Does nothing if no job found by that name": function(test) { + test.expect(3); + + var job = schedule.scheduleJob({ + second: null + }, function() { + test.ok(true); + }); + + setTimeout(function() { + // This cancel should not affect anything + schedule.cancelJob('blah'); + }, 2250); + + setTimeout(function() { + job.cancel(); // prevent tests from hanging + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + '.pendingInvocations()': { + "Retrieves pendingInvocations of the job": function(test) { + var job = schedule.scheduleJob(new Date(Date.now() + 1000), function() {}); + + test.ok(job instanceof schedule.Job); + test.ok(job.pendingInvocations()[0].job); + + job.cancel(); + test.done(); + } + }, + tearDown: function(cb) { + clock.restore(); + cb(); + } +}; diff --git a/nodejs/node_modules/node-schedule/test/date-convenience-methods-test.js b/nodejs/node_modules/node-schedule/test/date-convenience-methods-test.js new file mode 100755 index 0000000..10826bc --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/date-convenience-methods-test.js @@ -0,0 +1,59 @@ + +'use strict'; + +var sinon = require('sinon'); +var main = require('../package.json').main; +var schedule = require('../' + main); + +var clock; + +module.exports = { + setUp: function(cb) { + clock = sinon.useFakeTimers(); + cb(); + }, + "Date string": { + "Should accept a valid date string": function(test) { + test.expect(1); + + schedule.scheduleJob(new Date(Date.now() + 1000).toString(), function() { + test.ok(true); + }); + + setTimeout(function() { + test.done(); + }, 1250); + + clock.tick(1250); + }, + "Should not accept invalid string as valid date": function(test) { + test.expect(1); + + var job = schedule.scheduleJob("hello!!", function() { + }); + + test.equal(job, null); + test.done(); + + } + }, + "UTC": { + "Should accept a valid UTC date in milliseconds": function(test) { + test.expect(1); + + schedule.scheduleJob(new Date(Date.now() + 1000).getTime(), function() { + test.ok(true); + }); + + setTimeout(function() { + test.done(); + }, 1250); + + clock.tick(1250); + } + }, + tearDown: function(cb) { + clock.restore(); + cb(); + } +}; diff --git a/nodejs/node_modules/node-schedule/test/es6/job-test.js b/nodejs/node_modules/node-schedule/test/es6/job-test.js new file mode 100755 index 0000000..754a866 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/es6/job-test.js @@ -0,0 +1,33 @@ + +'use strict'; + +module.exports = function(schedule) { + return { + jobInGenerator: function(test) { + test.expect(1); + + var job = new schedule.Job(function*() { + test.ok(true); + }); + + job.runOnDate(new Date(Date.now() + 3000)); + + setTimeout(function() { + test.done(); + }, 3250); + }, + jobContextInGenerator: function(test) { + test.expect(1); + + var job = new schedule.Job('name of job', function*() { + test.ok(this.name === 'name of job'); + }); + + job.runOnDate(new Date(Date.now() + 3000)); + + setTimeout(function() { + test.done(); + }, 3250); + } + } +} diff --git a/nodejs/node_modules/node-schedule/test/job-test.js b/nodejs/node_modules/node-schedule/test/job-test.js new file mode 100755 index 0000000..3beff80 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/job-test.js @@ -0,0 +1,517 @@ + +'use strict'; + +var sinon = require('sinon'); +var main = require('../package.json').main; +var schedule = require('../' + main); + +var es6; +try { + eval('(function* () {})()'); + es6 = require('./es6/job-test')(schedule); +} catch (e) {} + +var clock; + +module.exports = { + setUp: function(cb) { + clock = sinon.useFakeTimers(); + cb(); + }, + "Job constructor": { + "Accepts Job name and function to run": function(test) { + var job = new schedule.Job('the job', function() {}); + + test.equal(job.name, 'the job'); + test.done(); + }, + "Job name is optional and will be auto-generated": function(test) { + var job = new schedule.Job(); + + test.ok(job.name); + test.done(); + }, + "Uses unique names across auto-generated Job names": function(test) { + var job1 = new schedule.Job(); + var job2 = new schedule.Job(); + + test.notEqual(job1.name, job2.name); + test.done(); + } + }, + "#schedule(Date)": { + "Runs job once at some date": function(test) { + test.expect(1); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.schedule(new Date(Date.now() + 3000)); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Cancel next job before it runs": function(test) { + test.expect(1); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.schedule(new Date(Date.now() + 1500)); + job.schedule(new Date(Date.now() + 3000)); + job.cancelNext(); + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Run job on specified date": function(test) { + test.expect(1); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.runOnDate(new Date(Date.now() + 3000)); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Run job in generator": function(test) { + if (!es6) { + test.expect(0); + test.done(); + return; + } + + es6.jobInGenerator(test); + + clock.tick(3250); + }, + "Context is passed into generator correctly": function(test) { + if (!es6) { + test.expect(0); + test.done(); + return; + } + + es6.jobContextInGenerator(test); + + clock.tick(3250); + }, + "Won't run job if scheduled in the past": function(test) { + test.expect(0); + + var job = new schedule.Job(function() { + test.ok(false); + }); + + job.schedule(new Date(Date.now() - 3000)); + + setTimeout(function() { + test.done(); + }, 1000); + + clock.tick(1000); + }, + "Jobs still run after scheduling a Job in the past": function(test) { + test.expect(1); + + var pastJob = new schedule.Job(function() { + // Should not run, blow up if it does + test.ok(false); + }); + + pastJob.schedule(new Date(Date.now() - 3000)); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.schedule(new Date(Date.now() + 3000)); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job emits 'scheduled' event with 'run at' Date": function(test) { + test.expect(1); + + var date = new Date(Date.now() + 3000); + var job = new schedule.Job(function() { + test.done(); + }); + + job.on('scheduled', function(runAtDate) { + test.equal(runAtDate.getTime(), date.getTime()); + }); + + job.schedule(date); + clock.tick(3250); + } + }, + "#schedule(Date, fn)": { + "Runs job once at some date, calls callback when done": function(test) { + test.expect(1); + + var job = new schedule.Job(function() {}, function() { + test.ok(true); + }); + + job.schedule(new Date(Date.now() + 3000)); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + "#schedule(RecurrenceRule)": { + "Runs job at interval based on recur rule, repeating indefinitely": function(test) { + test.expect(3); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + job.schedule(rule); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job emits 'scheduled' event for every next invocation": function(test) { + // Job will run 3 times but be scheduled 4 times, 4th run never happens + // due to cancel. + test.expect(4); + + var job = new schedule.Job(function() {}); + + job.on('scheduled', function(runOnDate) { + test.ok(true); + }); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // fire every second + + job.schedule(rule); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Doesn't invoke job if recur rule schedules it in the past": function(test) { + test.expect(0); + + var job = new schedule.Job(function() { + test.ok(false); + }); + + var rule = new schedule.RecurrenceRule(); + rule.year = 2000; + + job.schedule(rule); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 1000); + + clock.tick(1000); + } + }, + "#schedule({...})": { + "Runs job at interval based on object, repeating indefinitely": function(test) { + test.expect(3); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job emits 'scheduled' event for every next invocation": function(test) { + // Job will run 3 times but be scheduled 4 times, 4th run never happens + // due to cancel. + test.expect(4); + + var job = new schedule.Job(function() {}); + + job.on('scheduled', function(runOnDate) { + test.ok(true); + }); + + job.schedule({ + second: null // Fire every second + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Doesn't invoke job if object schedules it in the past": function(test) { + test.expect(0); + + var job = new schedule.Job(function() { + test.ok(false); + }); + + job.schedule({ + year: 2000 + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 1000); + + clock.tick(1000); + } + }, + "#schedule('jobName', {...})": { + "Runs job with a custom name input": function(test) { + test.expect(3); + + var job = new schedule.Job('jobName', function() { + test.equal(job.name, 'jobName'); + }); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + "#schedule({...}, {...})": { + "Runs job and run callback when job is done if callback is provided": function(test) { + test.expect(3); + + var job = new schedule.Job(function() {}, function() { + test.ok(true); + }); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Runs job with a custom name input and run callback when job is done": function(test) { + test.expect(3); + + var job = new schedule.Job('MyJob', function() {}, function() { + test.equal(job.name, 'MyJob'); + }); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + "#cancel": { + "Prevents all future invocations": function(test) { + test.expect(1); + + var job = new schedule.Job(function() { + test.ok(true); + }); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function() { + job.cancel(); + }, 1250); + + setTimeout(function() { + test.done(); + }, 2250); + + clock.tick(2250); + }, + "Job emits 'canceled' event": function(test) { + test.expect(1); + + var job = new schedule.Job(function() {}); + + job.on('canceled', function() { + test.ok(true); + }); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function() { + job.cancel(); + }, 1250); + + setTimeout(function() { + test.done(); + }, 2250); + + clock.tick(2250); + }, + "Job is added to scheduledJobs when created and removed when cancelled": function(test) { + test.expect(4); + + var job1 = new schedule.Job('cancelJob', function() {}); + job1.schedule({ + second: null // fire every second + }); + + var job2 = schedule.scheduleJob('second', + { second: null }, + function() {}, + function() {}); + + test.strictEqual(schedule.scheduledJobs.cancelJob, job1); + test.strictEqual(schedule.scheduledJobs.second, job2); + setTimeout(function() { + job1.cancel(); + job2.cancel(); + test.strictEqual(schedule.scheduledJobs.cancelJob, undefined); + test.strictEqual(schedule.scheduledJobs.second, undefined); + test.done(); + }, 1250); + + clock.tick(1250); + } + }, + "#reschedule": { + "When rescheduled counter will be reset to zero": function(test) { + + var job = new schedule.scheduleJob({ + second: null + }, function() {}); + + setTimeout(function() { + test.equal(job.triggeredJobs(), 3); + schedule.rescheduleJob(job, { + minute: null + }); + }, 3250); + + setTimeout(function() { + job.cancel(); + test.equal(job.triggeredJobs(), 0); + test.done(); + }, 5000); + + clock.tick(5000); + } + }, + "When invoked": { + "Job emits 'run' event": function(test) { + test.expect(1); + + var job = new schedule.Job(function() {}); + + job.on('run', function() { + test.ok(true); + }); + + job.schedule(new Date(Date.now() + 3000)); + + setTimeout(function() { + test.done(); + }, 3250); + + clock.tick(3250); + }, + "Job counter increase properly": function(test) { + var job = new schedule.Job(function() {}); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function() { + job.cancel(); + test.equal(job.triggeredJobs(), 2); + test.done(); + }, 2250); + + clock.tick(2250); + }, + "Job gets invoked with the fire date": function (test) { + test.expect(2); + var prevFireDate; + var job = new schedule.Job(function (fireDate) { + if (!prevFireDate) { + test.ok(fireDate instanceof Date); + } else { + test.equal(fireDate.getTime() - prevFireDate.getTime(), 1000); + } + prevFireDate = fireDate; + }); + + job.schedule({ + second: null // fire every second + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 2250); + + clock.tick(2250); + } + }, + tearDown: function(cb) { + clock.restore(); + cb(); + } +}; diff --git a/nodejs/node_modules/node-schedule/test/range-test.js b/nodejs/node_modules/node-schedule/test/range-test.js new file mode 100755 index 0000000..e325928 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/range-test.js @@ -0,0 +1,77 @@ + +'use strict'; + +var main = require('../package.json').main; +var schedule = require('../' + main); + +module.exports = { + "step defaults to 1": function(test) { + var range = new schedule.Range(2, 6); + + test.equals(1, range.step); + + test.done(); + }, + "when step is 1": { + "setUp": function(done) { + this.range = new schedule.Range(2, 6, 1); + + done(); + }, + "includes start value": function(test) { + test.ok(this.range.contains(2)); + + test.done(); + }, + "includes end value": function(test) { + test.ok(this.range.contains(6)); + + test.done(); + }, + "includes value between start and end": function(test) { + test.ok(this.range.contains(3)); + + test.done(); + }, + "excludes values outside of start and end": function(test) { + test.ok(!this.range.contains(1)); + test.ok(!this.range.contains(7)); + + test.done(); + } + }, + "when step > 1": { + "setUp": function(done) { + this.range = new schedule.Range(2, 6, 2); + + done(); + }, + "includes start value": function(test) { + test.ok(this.range.contains(2)); + + test.done(); + }, + "excludes end value": function(test) { + test.ok(!this.range.contains(6)); + + test.done(); + }, + "includes value between start and end that is evenly divisible by step": function(test) { + test.ok(this.range.contains(4)); + + test.done(); + }, + "excludes value between start and end that is not evenly divisible by step": function(test) { + test.ok(!this.range.contains(5)); + + test.done(); + }, + "excludes values outside of start and end": function(test) { + test.ok(!this.range.contains(1)); + test.ok(!this.range.contains(7)); + + test.done(); + } + } + +}; diff --git a/nodejs/node_modules/node-schedule/test/recurrence-rule-test.js b/nodejs/node_modules/node-schedule/test/recurrence-rule-test.js new file mode 100755 index 0000000..7654bae --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/recurrence-rule-test.js @@ -0,0 +1,375 @@ + +'use strict'; + +var main = require('../package.json').main; +var schedule = require('../' + main); +var sinon = require('sinon'); +var clock; + +// 12:30:15 pm Thursday 29 April 2010 in the timezone this code is being run in +var base = new Date(2010, 3, 29, 12, 30, 15, 0); +var baseMs = base.getTime(); + +module.exports = { + "setUp": function(cb) { + clock = sinon.useFakeTimers(baseMs); + cb(); + }, + "tearDown": function(cb) { + clock.restore(); + cb(); + }, + "#nextInvocationDate(Date)": { + "next second": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = null; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 29, 12, 30, 16, 0), next); + test.done(); + }, + "next 25th second": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = 25; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 29, 12, 30, 25, 0), next); + test.done(); + }, + "next 5th second (minutes incremented)": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = 5; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 29, 12, 31, 5, 0), next); + test.done(); + }, + "next 40th minute": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.minute = 40; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 29, 12, 40, 0, 0), next); + test.done(); + }, + "next 1st minute (hours incremented)": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.minute = 1; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 29, 13, 1, 0, 0), next); + test.done(); + }, + "next 23rd hour": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.hour = 23; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 29, 23, 0, 0, 0), next); + test.done(); + }, + "next 3rd hour (days incremented)": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.hour = 3; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 30, 3, 0, 0, 0), next); + test.done(); + }, + "next Friday": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.dayOfWeek = 5; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 30, 0, 0, 0, 0), next); + test.done(); + }, + "next Monday (months incremented)": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.dayOfWeek = 1; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 4, 3, 0, 0, 0, 0), next); + test.done(); + }, + "next 30th date": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.date = 30; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 30, 0, 0, 0, 0), next); + test.done(); + }, + "next 5th date (months incremented)": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.date = 5; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 4, 5, 0, 0, 0, 0), next); + test.done(); + }, + "next October": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.month = 9; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 9, 1, 0, 0, 0, 0), next); + test.done(); + }, + "next February (years incremented)": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.month = 1; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2011, 1, 1, 0, 0, 0, 0), next); + test.done(); + }, + "in the year 2040": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.year = 2040; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2040, 0, 1, 0, 0, 0, 0), next); + test.done(); + }, + "using past year": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.year = 2000; + + var next = rule.nextInvocationDate(base); + + test.equal(null, next); + test.done(); + }, + "using mixed time components": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = 50; + rule.minute = 5; + rule.hour = 10; + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 30, 10, 5, 50, 0), next); + test.done(); + }, + /* + "using date and dayOfWeek together": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.dayOfWeek = 4; // This is Thursday April 1st + rule.date = 10; // This is Saturday April 10th + + var next = rule.nextInvocationDate(base); + + test.deepEqual(new Date(2010, 3, 1, 0, 0, 0, 0), next); + test.done(); + }*/ + "returns null when no invocations left": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.year = 2000; + + var next = rule.nextInvocationDate(base); + + test.strictEqual(null, next); + test.done(); + }, + "specify span of components using Range": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.minute = new schedule.Range(4, 6); + + var next; + + next = rule.nextInvocationDate(base); + test.deepEqual(new Date(2010, 3, 29, 13, 4, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 13, 5, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 13, 6, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 14, 4, 0, 0), next); + + test.done(); + }, + "specify intervals within span of components using Range with step": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.minute = new schedule.Range(4, 8, 2); + + var next; + + next = rule.nextInvocationDate(base); + test.deepEqual(new Date(2010, 3, 29, 13, 4, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 13, 6, 0, 0), next); + + /* Should Range stay inclusive on both ends when step > 1 + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 13, 8, 0, 0), next); + */ + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 14, 4, 0, 0), next); + + test.done(); + }, + "specify span and explicit components using Array of Ranges and Numbers": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.minute = [2, new schedule.Range(4, 6)]; + + var next; + + next = rule.nextInvocationDate(base); + test.deepEqual(new Date(2010, 3, 29, 13, 2, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 13, 4, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 13, 5, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 13, 6, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2010, 3, 29, 14, 2, 0, 0), next); + + test.done(); + }, + "From 31th May schedule the 1st of every June": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = 0; + rule.minute = 0; + rule.hour = 0; + rule.date = 1; + rule.month = 5; + + var next; + var base1 = new Date(2010, 4, 31, 12, 30, 15, 0); + + next = rule.nextInvocationDate(base1); + test.deepEqual(new Date(2010, 5, 1, 0, 0, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.deepEqual(new Date(2011, 5, 1, 0, 0, 0, 0), next); + + test.done(); + }, + "With the year set should not loop indefinetely": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = 0; + rule.minute = 0; + rule.hour = 0; + rule.date = 1; + rule.month = 5; + rule.year = 2010; + + var next; + var base1 = new Date(2010, 4, 31, 12, 30, 15, 0); + + next = rule.nextInvocationDate(base1); + test.deepEqual(new Date(2010, 5, 1, 0, 0, 0, 0), next); + + next = rule.nextInvocationDate(next); + test.equal(next, null); + + test.done(); + }, + "using rule with string properties": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = '50'; + rule.minute = '5'; + rule.hour = '10'; + var next = rule.nextInvocationDate(base); + test.deepEqual(new Date(2010, 3, 30, 10, 5, 50, 0), next); + test.done(); + }, + "nextInvocationDate on an invalid month should return null": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.month = 12; + var next = rule.nextInvocationDate(); + test.equal(next, null); + + var rule2 = new schedule.RecurrenceRule(); + rule2.month = 'asdfasdf'; + var next2 = rule2.nextInvocationDate(next); + test.equal(next2, null); + + test.done(); + }, + "nextInvocationDate on an invalid second should return null": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.second = 60; + var next = rule.nextInvocationDate(); + test.equal(next, null); + + var rule2 = new schedule.RecurrenceRule(); + rule2.second = 'asdfasdf'; + var next2 = rule2.nextInvocationDate(); + test.equal(next2, null); + + test.done(); + }, + "nextInvocationDate on an invalid hour should return null": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.hour = 24; + var next = rule.nextInvocationDate(); + test.equal(next, null); + + var rule2 = new schedule.RecurrenceRule(); + rule2.hour = 'asdfasdf'; + var next2 = rule2.nextInvocationDate(); + test.equal(next2, null); + + test.done(); + }, + "nextInvocationDate on an invalid date should return null": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.date = 90; + var next = rule.nextInvocationDate(); + test.equal(next, null); + + // Test February + var rule2 = new schedule.RecurrenceRule(); + rule2.month = 1; + rule2.date = 30; + var next2 = rule2.nextInvocationDate(); + test.equal(next2, null); + + var rule3 = new schedule.RecurrenceRule(); + rule3.date = 'asdfasdf'; + var next3 = rule3.nextInvocationDate(); + test.equal(next3, null); + + test.done(); + }, + "nextInvocationDate on an invalid dayOfWeek should return null": function(test) { + var rule = new schedule.RecurrenceRule(); + rule.dayOfWeek = 90; + var next = rule.nextInvocationDate(); + test.equal(next, null); + + var rule2 = new schedule.RecurrenceRule(); + rule2.dayOfWeek = 'asdfasdf'; + var next2 = rule.nextInvocationDate(); + test.equal(next2, null); + + test.done(); + } + } +}; diff --git a/nodejs/node_modules/node-schedule/test/schedule-cron-jobs.js b/nodejs/node_modules/node-schedule/test/schedule-cron-jobs.js new file mode 100755 index 0000000..0818355 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/schedule-cron-jobs.js @@ -0,0 +1,134 @@ + +'use strict'; + +var sinon = require('sinon'); +var main = require('../package.json').main; +var schedule = require('../' + main); + +var clock; + +module.exports = { + ".scheduleJob(cron_expr, fn)": { + setUp: function(cb) { + clock = sinon.useFakeTimers(); + cb(); + }, + "Runs job every second": function(test) { + test.expect(3); + + var timeout = 3 * 1000 + 150; + + var job = schedule.scheduleJob('* * * * * *', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout); + + clock.tick(timeout); + }, + "Runs job every minute": function(test) { + test.expect(3); + + var timeout = 3 * 60 * 1000 + 150; + + var job = schedule.scheduleJob('0 * * * * *', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout); + + clock.tick(timeout); + }, + "Runs job every hour": function(test) { + test.expect(3); + + var timeout = 3 * 60 * 60 * 1000 + 150; + + var job = schedule.scheduleJob('0 0 * * * *', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout); + + clock.tick(timeout); + }, + "Runs job every day": function(test) { + test.expect(3); + + var timeout = 3 * 24 * 60 * 60 * 1000 + 150; + + var job = schedule.scheduleJob('0 0 0 * * *', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout); + + clock.tick(timeout); + }, + "Runs job every week": function(test) { + test.expect(3); + + var timeout = 3 * 7 * 24 * 60 * 60 * 1000 + 150; + + var job = schedule.scheduleJob('0 0 0 * * 1', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout); + + clock.tick(timeout); + }, + "Runs job every month": function(test) { + test.expect(48); + + var timeout = 4 * 365.25 * 24 * 60 * 60 * 1000 + 150; + + var job = schedule.scheduleJob('0 0 0 1 * *', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout); + + clock.tick(timeout); + + }, + "Runs job every year": function(test) { + test.expect(4); + + var timeout = 4 * 365.25 * 24 * 60 * 60 * 1000 + 150; + + var job = schedule.scheduleJob('0 0 0 1 1 *', function() { + test.ok(true); + }); + + setTimeout(function() { + job.cancel(); + test.done(); + }, timeout); + + clock.tick(timeout); + }, + tearDown: function(cb) { + clock.restore(); + cb(); + } + } +}; diff --git a/nodejs/node_modules/node-schedule/test/start-end-test.js b/nodejs/node_modules/node-schedule/test/start-end-test.js new file mode 100755 index 0000000..51dacd2 --- /dev/null +++ b/nodejs/node_modules/node-schedule/test/start-end-test.js @@ -0,0 +1,327 @@ +'use strict'; + +var sinon = require('sinon'); +var main = require('../package.json').main; +var schedule = require('../' + main); + +var clock; + +module.exports = { + setUp: function (cb) { + clock = sinon.useFakeTimers(); + cb(); + }, + 'RecurrenceRule': { + 'no endTime , startTime less than now': function (test) { + test.expect(3); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // every second + + job.schedule({ + start: new Date(Date.now() - 2000), + rule: rule + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no endTime , startTime greater than now': function (test) { + test.expect(1); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // every second + + job.schedule({ + start: new Date(Date.now() + 2000), + rule: rule + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no startTime , endTime less than now': function (test) { + test.expect(0); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // every second + + job.schedule({ + end: new Date(Date.now() - 2000), + rule: rule + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no startTime , endTime greater than now': function (test) { + test.expect(2); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // every second + + job.schedule({ + end: new Date(Date.now() + 2000), + rule: rule + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'has startTime and endTime': function (test) { + test.expect(1); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + var rule = new schedule.RecurrenceRule(); + rule.second = null; // every second + + job.schedule({ + start: new Date(Date.now() + 1000), + end: new Date(Date.now() + 2000), + rule: rule + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + 'Object Literal': { + 'no endTime , startTime less than now': function (test) { + test.expect(3); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + start: new Date(Date.now() - 2000), + rule: { second: null } + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no endTime , startTime greater than now': function (test) { + test.expect(1); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + start: new Date(Date.now() + 2000), + rule: { second: null } + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no startTime , endTime less than now': function (test) { + test.expect(0); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + end: new Date(Date.now() - 2000), + rule: { second: null } + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no startTime , endTime greater than now': function (test) { + test.expect(2); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + end: new Date(Date.now() + 2000), + rule: { second: null } + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'has startTime and endTime': function (test) { + test.expect(1); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + start: new Date(Date.now() + 1000), + end: new Date(Date.now() + 2000), + rule: { second: null } + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + 'cron-style': { + 'no endTime , startTime less than now': function (test) { + test.expect(3); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + start: new Date(Date.now() - 2000), + rule: '*/1 * * * * *' + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no endTime , startTime greater than now': function (test) { + test.expect(1); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + start: new Date(Date.now() + 2000), + rule: '*/1 * * * * *' + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no startTime , endTime less than now': function (test) { + test.expect(0); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + end: new Date(Date.now() - 2000), + rule: '*/1 * * * * *' + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'no startTime , endTime greater than now': function (test) { + test.expect(2); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + end: new Date(Date.now() + 2000), + rule: '*/1 * * * * *' + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + }, + 'has startTime and endTime': function (test) { + test.expect(1); + + var job = new schedule.Job(function () { + test.ok(true); + }); + + job.schedule({ + start: new Date(Date.now() + 1000), + end: new Date(Date.now() + 2000), + rule: '*/1 * * * * *' + }); + + setTimeout(function () { + job.cancel(); + test.done(); + }, 3250); + + clock.tick(3250); + } + }, + tearDown: function (cb) { + clock.restore(); + cb(); + } +}; diff --git a/nodejs/node_modules/object-keys/.editorconfig b/nodejs/node_modules/object-keys/.editorconfig new file mode 100755 index 0000000..eaa2141 --- /dev/null +++ b/nodejs/node_modules/object-keys/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_style = tab; +insert_final_newline = true; +quote_type = auto; +space_after_anonymous_functions = true; +space_after_control_statements = true; +spaces_around_operators = true; +trim_trailing_whitespace = true; +spaces_in_brackets = false; +end_of_line = lf; + diff --git a/nodejs/node_modules/object-keys/.eslintrc b/nodejs/node_modules/object-keys/.eslintrc new file mode 100755 index 0000000..9a8d5b0 --- /dev/null +++ b/nodejs/node_modules/object-keys/.eslintrc @@ -0,0 +1,17 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "complexity": [2, 23], + "id-length": [2, { "min": 1, "max": 40 }], + "max-params": [2, 3], + "max-statements": [2, 23], + "max-statements-per-line": [2, { "max": 2 }], + "no-extra-parens": [1], + "no-invalid-this": [1], + "no-restricted-syntax": [2, "BreakStatement", "ContinueStatement", "LabeledStatement", "WithStatement"], + "operator-linebreak": [2, "after"] + } +} diff --git a/nodejs/node_modules/object-keys/.jscs.json b/nodejs/node_modules/object-keys/.jscs.json new file mode 100755 index 0000000..4782896 --- /dev/null +++ b/nodejs/node_modules/object-keys/.jscs.json @@ -0,0 +1,175 @@ +{ + "es3": true, + + "additionalRules": [], + + "requireSemicolons": true, + + "disallowMultipleSpaces": true, + + "disallowIdentifierNames": [], + + "requireCurlyBraces": { + "allExcept": [], + "keywords": ["if", "else", "for", "while", "do", "try", "catch"] + }, + + "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"], + + "disallowSpaceAfterKeywords": [], + + "disallowSpaceBeforeComma": true, + "disallowSpaceAfterComma": false, + "disallowSpaceBeforeSemicolon": true, + + "disallowNodeTypes": [ + "DebuggerStatement", + "LabeledStatement", + "SwitchCase", + "SwitchStatement", + "WithStatement" + ], + + "requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] }, + + "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true }, + "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, + "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, + "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, + "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true }, + + "requireSpaceBetweenArguments": true, + + "disallowSpacesInsideParentheses": true, + + "disallowSpacesInsideArrayBrackets": true, + + "disallowQuotedKeysInObjects": { "allExcept": ["reserved"] }, + + "disallowSpaceAfterObjectKeys": true, + + "requireCommaBeforeLineBreak": true, + + "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], + "requireSpaceAfterPrefixUnaryOperators": [], + + "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], + "requireSpaceBeforePostfixUnaryOperators": [], + + "disallowSpaceBeforeBinaryOperators": [], + "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], + + "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], + "disallowSpaceAfterBinaryOperators": [], + + "disallowImplicitTypeConversion": ["binary", "string"], + + "disallowKeywords": ["with", "eval"], + + "requireKeywordsOnNewLine": [], + "disallowKeywordsOnNewLine": ["else"], + + "requireLineFeedAtFileEnd": true, + + "disallowTrailingWhitespace": true, + + "disallowTrailingComma": true, + + "excludeFiles": ["node_modules/**", "vendor/**"], + + "disallowMultipleLineStrings": true, + + "requireDotNotation": { "allExcept": ["keywords"] }, + + "requireParenthesesAroundIIFE": true, + + "validateLineBreaks": "LF", + + "validateQuoteMarks": { + "escape": true, + "mark": "'" + }, + + "disallowOperatorBeforeLineBreak": [], + + "requireSpaceBeforeKeywords": [ + "do", + "for", + "if", + "else", + "switch", + "case", + "try", + "catch", + "finally", + "while", + "with", + "return" + ], + + "validateAlignedFunctionParameters": { + "lineBreakAfterOpeningBraces": true, + "lineBreakBeforeClosingBraces": true + }, + + "requirePaddingNewLinesBeforeExport": true, + + "validateNewlineAfterArrayElements": { + "maximum": 7 + }, + + "requirePaddingNewLinesAfterUseStrict": true, + + "disallowArrowFunctions": true, + + "disallowMultiLineTernary": true, + + "validateOrderInObjectKeys": "asc-insensitive", + + "disallowIdenticalDestructuringNames": true, + + "disallowNestedTernaries": { "maxLevel": 1 }, + + "requireSpaceAfterComma": { "allExcept": ["trailing"] }, + "requireAlignedMultilineParams": false, + + "requireSpacesInGenerator": { + "afterStar": true + }, + + "disallowSpacesInGenerator": { + "beforeStar": true + }, + + "disallowVar": false, + + "requireArrayDestructuring": false, + + "requireEnhancedObjectLiterals": false, + + "requireObjectDestructuring": false, + + "requireEarlyReturn": false, + + "requireCapitalizedConstructorsNew": { + "allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"] + }, + + "requireImportAlphabetized": false, + + "requireSpaceBeforeObjectValues": true, + "requireSpaceBeforeDestructuredValues": true, + + "disallowSpacesInsideTemplateStringPlaceholders": true, + + "disallowArrayDestructuringReturn": false, + + "requireNewlineBeforeSingleStatementsInIf": false, + + "disallowUnusedVariables": true, + + "requireSpacesInsideImportedObjectBraces": true, + + "requireUseStrict": true +} + diff --git a/nodejs/node_modules/object-keys/.travis.yml b/nodejs/node_modules/object-keys/.travis.yml new file mode 100755 index 0000000..767256c --- /dev/null +++ b/nodejs/node_modules/object-keys/.travis.yml @@ -0,0 +1,225 @@ +language: node_js +os: + - linux +node_js: + - "10.4" + - "9.11" + - "8.11" + - "7.10" + - "6.14" + - "5.12" + - "4.9" + - "iojs-v3.3" + - "iojs-v2.5" + - "iojs-v1.8" + - "0.12" + - "0.10" + - "0.8" +before_install: + - 'case "${TRAVIS_NODE_VERSION}" in 0.*) export NPM_CONFIG_STRICT_SSL=false ;; esac' + - 'nvm install-latest-npm' +install: + - 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.9" ]; then nvm install --latest-npm 0.8 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;' +script: + - 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi' + - 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi' + - 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi' + - 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi' +sudo: false +env: + - TEST=true +matrix: + fast_finish: true + include: + - node_js: "lts/*" + env: PRETEST=true + - node_js: "lts/*" + env: POSTTEST=true + - node_js: "4" + env: COVERAGE=true + - node_js: "10.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "10.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "9.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "8.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "7.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.13" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.12" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.11" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "6.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.11" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.10" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "5.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.8" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "4.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v3.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v3.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v3.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v2.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.7" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.5" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.4" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.3" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.2" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.1" + env: TEST=true ALLOW_FAILURE=true + - node_js: "iojs-v1.0" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.11" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.9" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.6" + env: TEST=true ALLOW_FAILURE=true + - node_js: "0.4" + env: TEST=true ALLOW_FAILURE=true + allow_failures: + - os: osx + - env: TEST=true ALLOW_FAILURE=true + - env: COVERAGE=true diff --git a/nodejs/node_modules/object-keys/CHANGELOG.md b/nodejs/node_modules/object-keys/CHANGELOG.md new file mode 100755 index 0000000..27123c4 --- /dev/null +++ b/nodejs/node_modules/object-keys/CHANGELOG.md @@ -0,0 +1,220 @@ +1.0.12 / 2018-06-18 +================= + * [Fix] avoid accessing `window.applicationCache`, to avoid issues with latest Chrome on HTTP (#46) + +1.0.11 / 2016-07-05 +================= + * [Fix] exclude keys regarding the style (eg. `pageYOffset`) on `window` to avoid reflow (#32) + +1.0.10 / 2016-07-04 +================= + * [Fix] exclude `height` and `width` keys on `window` to avoid reflow (#31) + * [Fix] In IE 6, `window.external` makes `Object.keys` throw + * [Tests] up to `node` `v6.2`, `v5.10`, `v4.4` + * [Tests] use pretest/posttest for linting/security + * [Dev Deps] update `tape`, `jscs`, `nsp`, `eslint`, `@ljharb/eslint-config` + * [Dev Deps] remove unused eccheck script + dep + +1.0.9 / 2015-10-19 +================= + * [Fix] Blacklist 'frame' property on window (#16, #17) + * [Dev Deps] update `jscs`, `eslint`, `@ljharb/eslint-config` + +1.0.8 / 2015-10-14 +================= + * [Fix] wrap automation equality bug checking in try/catch, per [es5-shim#327](https://github.com/es-shims/es5-shim/issues/327) + * [Fix] Blacklist 'window.frameElement' per [es5-shim#322](https://github.com/es-shims/es5-shim/issues/322) + * [Docs] Switch from vb.teelaun.ch to versionbadg.es for the npm version badge SVG + * [Tests] up to `io.js` `v3.3`, `node` `v4.2` + * [Dev Deps] update `eslint`, `tape`, `@ljharb/eslint-config`, `jscs` + +1.0.7 / 2015-07-18 +================= + * [Fix] A proper fix for 176f03335e90d5c8d0d8125a99f27819c9b9cdad / https://github.com/es-shims/es5-shim/issues/275 that doesn't break dontEnum/constructor fixes in IE 8. + * [Fix] Remove deprecation message in Chrome by touching deprecated window properties (#15) + * [Tests] Improve test output for automation equality bugfix + * [Tests] Test on `io.js` `v2.4` + +1.0.6 / 2015-07-09 +================= + * [Fix] Use an object lookup rather than ES5's `indexOf` (#14) + * [Tests] ES3 browsers don't have `Array.isArray` + * [Tests] Fix `no-shadow` rule, as well as an IE 8 bug caused by engine NFE shadowing bugs. + +1.0.5 / 2015-07-03 +================= + * [Fix] Fix a flabbergasting IE 8 bug where `localStorage.constructor.prototype === localStorage` throws + * [Tests] Test up to `io.js` `v2.3` + * [Dev Deps] Update `nsp`, `eslint` + +1.0.4 / 2015-05-23 +================= + * Fix a Safari 5.0 bug with `Object.keys` not working with `arguments` + * Test on latest `node` and `io.js` + * Update `jscs`, `tape`, `eslint`, `nsp`, `is`, `editorconfig-tools`, `covert` + +1.0.3 / 2015-01-06 +================= + * Revert "Make `object-keys` more robust against later environment tampering" to maintain ES3 compliance + +1.0.2 / 2014-12-28 +================= + * Update lots of dev dependencies + * Tweaks to README + * Make `object-keys` more robust against later environment tampering + +1.0.1 / 2014-09-03 +================= + * Update URLs and badges in README + +1.0.0 / 2014-08-26 +================= + * v1.0.0 + +0.6.1 / 2014-08-25 +================= + * v0.6.1 + * Updating dependencies (tape, covert, is) + * Update badges in readme + * Use separate var statements + +0.6.0 / 2014-04-23 +================= + * v0.6.0 + * Updating dependencies (tape, covert) + * Make sure boxed primitives, and arguments objects, work properly in ES3 browsers + * Improve test matrix: test all node versions, but only latest two stables are a failure + * Remove internal foreach shim. + +0.5.1 / 2014-03-09 +================= + * 0.5.1 + * Updating dependencies (tape, covert, is) + * Removing forEach from the module (but keeping it in tests) + +0.5.0 / 2014-01-30 +================= + * 0.5.0 + * Explicitly returning the shim, instead of returning native Object.keys when present + * Adding a changelog. + * Cleaning up IIFE wrapping + * Testing on node 0.4 through 0.11 + +0.4.0 / 2013-08-14 +================== + + * v0.4.0 + * In Chrome 4-10 and Safari 4, typeof (new RegExp) === 'function' + * If it's a string, make sure to use charAt instead of brackets. + * Only use Function#call if necessary. + * Making sure the context tests actually run. + * Better function detection + * Adding the android browser + * Fixing testling files + * Updating tape + * Removing the "is" dependency. + * Making an isArguments shim. + * Adding a local forEach shim and tests. + * Updating paths. + * Moving the shim test. + * v0.3.0 + +0.3.0 / 2013-05-18 +================== + + * README tweak. + * Fixing constructor enum issue. Fixes [#5](https://github.com/ljharb/object-keys/issues/5). + * Adding a test for [#5](https://github.com/ljharb/object-keys/issues/5) + * Updating readme. + * Updating dependencies. + * Giving credit to lodash. + * Make sure that a prototype's constructor property is not enumerable. Fixes [#3](https://github.com/ljharb/object-keys/issues/3). + * Adding additional tests to handle arguments objects, and to skip "prototype" in functions. Fixes [#2](https://github.com/ljharb/object-keys/issues/2). + * Fixing a typo on this test for [#3](https://github.com/ljharb/object-keys/issues/3). + * Adding node 0.10 to travis. + * Adding an IE < 9 test per [#3](https://github.com/ljharb/object-keys/issues/3) + * Adding an iOS 5 mobile Safari test per [#2](https://github.com/ljharb/object-keys/issues/2) + * Moving "indexof" and "is" to be dev dependencies. + * Making sure the shim works with functions. + * Flattening the tests. + +0.2.0 / 2013-05-10 +================== + + * v0.2.0 + * Object.keys should work with arrays. + +0.1.8 / 2013-05-10 +================== + + * v0.1.8 + * Upgrading dependencies. + * Using a simpler check. + * Fixing a bug in hasDontEnumBug browsers. + * Using the newest tape! + * Fixing this error test. + * "undefined" is probably a reserved word in ES3. + * Better test message. + +0.1.7 / 2013-04-17 +================== + + * Upgrading "is" once more. + * The key "null" is breaking some browsers. + +0.1.6 / 2013-04-17 +================== + + * v0.1.6 + * Upgrading "is" + +0.1.5 / 2013-04-14 +================== + + * Bumping version. + * Adding more testling browsers. + * Updating "is" + +0.1.4 / 2013-04-08 +================== + + * Using "is" instead of "is-extended". + +0.1.3 / 2013-04-07 +================== + + * Using "foreach" instead of my own shim. + * Removing "tap"; I'll just wait for "tape" to fix its node 0.10 bug. + +0.1.2 / 2013-04-03 +================== + + * Adding dependency status; moving links to an index at the bottom. + * Upgrading is-extended; version 0.1.2 + * Adding an npm version badge. + +0.1.1 / 2013-04-01 +================== + + * Adding Travis CI. + * Bumping the version. + * Adding indexOf since IE sucks. + * Adding a forEach shim since older browsers don't have Array#forEach. + * Upgrading tape - 0.3.2 uses Array#map + * Using explicit end instead of plan. + * Can't test with Array.isArray in older browsers. + * Using is-extended. + * Fixing testling files. + * JSHint/JSLint-ing. + * Removing an unused object. + * Using strict mode. + +0.1.0 / 2013-03-30 +================== + + * Changing the exports should have meant a higher version bump. + * Oops, fixing the repo URL. + * Adding more tests. + * 0.0.2 + * Merge branch 'export_one_thing'; closes [#1](https://github.com/ljharb/object-keys/issues/1) + * Move shim export to a separate file. diff --git a/nodejs/node_modules/object-keys/LICENSE b/nodejs/node_modules/object-keys/LICENSE new file mode 100755 index 0000000..28553fd --- /dev/null +++ b/nodejs/node_modules/object-keys/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (C) 2013 Jordan Harband + +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. \ No newline at end of file diff --git a/nodejs/node_modules/object-keys/README.md b/nodejs/node_modules/object-keys/README.md new file mode 100755 index 0000000..ed4c277 --- /dev/null +++ b/nodejs/node_modules/object-keys/README.md @@ -0,0 +1,76 @@ +#object-keys [![Version Badge][npm-version-svg]][package-url] + +[![Build Status][travis-svg]][travis-url] +[![dependency status][deps-svg]][deps-url] +[![dev dependency status][dev-deps-svg]][dev-deps-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +[![browser support][testling-svg]][testling-url] + +An Object.keys shim. Invoke its "shim" method to shim Object.keys if it is unavailable. + +Most common usage: +```js +var keys = Object.keys || require('object-keys'); +``` + +## Example + +```js +var keys = require('object-keys'); +var assert = require('assert'); +var obj = { + a: true, + b: true, + c: true +}; + +assert.deepEqual(keys(obj), ['a', 'b', 'c']); +``` + +```js +var keys = require('object-keys'); +var assert = require('assert'); +/* when Object.keys is not present */ +delete Object.keys; +var shimmedKeys = keys.shim(); +assert.equal(shimmedKeys, keys); +assert.deepEqual(Object.keys(obj), keys(obj)); +``` + +```js +var keys = require('object-keys'); +var assert = require('assert'); +/* when Object.keys is present */ +var shimmedKeys = keys.shim(); +assert.equal(shimmedKeys, Object.keys); +assert.deepEqual(Object.keys(obj), keys(obj)); +``` + +## Source +Implementation taken directly from [es5-shim][es5-shim-url], with modifications, including from [lodash][lodash-url]. + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/object-keys +[npm-version-svg]: http://versionbadg.es/ljharb/object-keys.svg +[travis-svg]: https://travis-ci.org/ljharb/object-keys.svg +[travis-url]: https://travis-ci.org/ljharb/object-keys +[deps-svg]: https://david-dm.org/ljharb/object-keys.svg +[deps-url]: https://david-dm.org/ljharb/object-keys +[dev-deps-svg]: https://david-dm.org/ljharb/object-keys/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/object-keys#info=devDependencies +[testling-svg]: https://ci.testling.com/ljharb/object-keys.png +[testling-url]: https://ci.testling.com/ljharb/object-keys +[es5-shim-url]: https://github.com/es-shims/es5-shim/blob/master/es5-shim.js#L542-589 +[lodash-url]: https://github.com/lodash/lodash +[npm-badge-png]: https://nodei.co/npm/object-keys.png?downloads=true&stars=true +[license-image]: http://img.shields.io/npm/l/object-keys.svg +[license-url]: LICENSE +[downloads-image]: http://img.shields.io/npm/dm/object-keys.svg +[downloads-url]: http://npm-stat.com/charts.html?package=object-keys + diff --git a/nodejs/node_modules/object-keys/index.js b/nodejs/node_modules/object-keys/index.js new file mode 100755 index 0000000..3f2463e --- /dev/null +++ b/nodejs/node_modules/object-keys/index.js @@ -0,0 +1,141 @@ +'use strict'; + +// modified from https://github.com/es-shims/es5-shim +var has = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; +var slice = Array.prototype.slice; +var isArgs = require('./isArguments'); +var isEnumerable = Object.prototype.propertyIsEnumerable; +var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString'); +var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype'); +var dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' +]; +var equalsConstructorPrototype = function (o) { + var ctor = o.constructor; + return ctor && ctor.prototype === o; +}; +var excludedKeys = { + $applicationCache: true, + $console: true, + $external: true, + $frame: true, + $frameElement: true, + $frames: true, + $innerHeight: true, + $innerWidth: true, + $outerHeight: true, + $outerWidth: true, + $pageXOffset: true, + $pageYOffset: true, + $parent: true, + $scrollLeft: true, + $scrollTop: true, + $scrollX: true, + $scrollY: true, + $self: true, + $webkitIndexedDB: true, + $webkitStorageInfo: true, + $window: true +}; +var hasAutomationEqualityBug = (function () { + /* global window */ + if (typeof window === 'undefined') { return false; } + for (var k in window) { + try { + if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') { + try { + equalsConstructorPrototype(window[k]); + } catch (e) { + return true; + } + } + } catch (e) { + return true; + } + } + return false; +}()); +var equalsConstructorPrototypeIfNotBuggy = function (o) { + /* global window */ + if (typeof window === 'undefined' || !hasAutomationEqualityBug) { + return equalsConstructorPrototype(o); + } + try { + return equalsConstructorPrototype(o); + } catch (e) { + return false; + } +}; + +var keysShim = function keys(object) { + var isObject = object !== null && typeof object === 'object'; + var isFunction = toStr.call(object) === '[object Function]'; + var isArguments = isArgs(object); + var isString = isObject && toStr.call(object) === '[object String]'; + var theKeys = []; + + if (!isObject && !isFunction && !isArguments) { + throw new TypeError('Object.keys called on a non-object'); + } + + var skipProto = hasProtoEnumBug && isFunction; + if (isString && object.length > 0 && !has.call(object, 0)) { + for (var i = 0; i < object.length; ++i) { + theKeys.push(String(i)); + } + } + + if (isArguments && object.length > 0) { + for (var j = 0; j < object.length; ++j) { + theKeys.push(String(j)); + } + } else { + for (var name in object) { + if (!(skipProto && name === 'prototype') && has.call(object, name)) { + theKeys.push(String(name)); + } + } + } + + if (hasDontEnumBug) { + var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); + + for (var k = 0; k < dontEnums.length; ++k) { + if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) { + theKeys.push(dontEnums[k]); + } + } + } + return theKeys; +}; + +keysShim.shim = function shimObjectKeys() { + if (Object.keys) { + var keysWorksWithArguments = (function () { + // Safari 5.0 bug + return (Object.keys(arguments) || '').length === 2; + }(1, 2)); + if (!keysWorksWithArguments) { + var originalKeys = Object.keys; + Object.keys = function keys(object) { // eslint-disable-line func-name-matching + if (isArgs(object)) { + return originalKeys(slice.call(object)); + } else { + return originalKeys(object); + } + }; + } + } else { + Object.keys = keysShim; + } + return Object.keys || keysShim; +}; + +module.exports = keysShim; diff --git a/nodejs/node_modules/object-keys/isArguments.js b/nodejs/node_modules/object-keys/isArguments.js new file mode 100755 index 0000000..f2a2a90 --- /dev/null +++ b/nodejs/node_modules/object-keys/isArguments.js @@ -0,0 +1,17 @@ +'use strict'; + +var toStr = Object.prototype.toString; + +module.exports = function isArguments(value) { + var str = toStr.call(value); + var isArgs = str === '[object Arguments]'; + if (!isArgs) { + isArgs = str !== '[object Array]' && + value !== null && + typeof value === 'object' && + typeof value.length === 'number' && + value.length >= 0 && + toStr.call(value.callee) === '[object Function]'; + } + return isArgs; +}; diff --git a/nodejs/node_modules/object-keys/package.json b/nodejs/node_modules/object-keys/package.json new file mode 100755 index 0000000..9c34041 --- /dev/null +++ b/nodejs/node_modules/object-keys/package.json @@ -0,0 +1,122 @@ +{ + "_args": [ + [ + "object-keys@1.0.12", + "/www/wwwroot/Adminx.cc/nodejs" + ] + ], + "_from": "object-keys@1.0.12", + "_id": "object-keys@1.0.12", + "_inBundle": false, + "_integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "_location": "/object-keys", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "object-keys@1.0.12", + "name": "object-keys", + "escapedName": "object-keys", + "rawSpec": "1.0.12", + "saveSpec": null, + "fetchSpec": "1.0.12" + }, + "_requiredBy": [ + "/define-properties" + ], + "_resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "_spec": "1.0.12", + "_where": "/www/wwwroot/Adminx.cc/nodejs", + "author": { + "name": "Jordan Harband", + "email": "ljharb@gmail.com", + "url": "http://ljharb.codes" + }, + "bugs": { + "url": "https://github.com/ljharb/object-keys/issues" + }, + "contributors": [ + { + "name": "Jordan Harband", + "email": "ljharb@gmail.com", + "url": "http://ljharb.codes" + }, + { + "name": "Raynos", + "email": "raynos2@gmail.com" + }, + { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net" + }, + { + "name": "Ivan Starkov", + "email": "istarkov@gmail.com" + }, + { + "name": "Gary Katsevman", + "email": "git@gkatsev.com" + } + ], + "dependencies": {}, + "description": "An Object.keys replacement, in case Object.keys is not available. From https://github.com/es-shims/es5-shim", + "devDependencies": { + "@ljharb/eslint-config": "^12.2.1", + "covert": "^1.1.0", + "eslint": "^4.19.1", + "foreach": "^2.0.5", + "indexof": "^0.0.1", + "is": "^3.2.1", + "jscs": "^3.0.7", + "nsp": "^3.2.1", + "tape": "^4.9.1" + }, + "engines": { + "node": ">= 0.4" + }, + "homepage": "https://github.com/ljharb/object-keys#readme", + "keywords": [ + "Object.keys", + "keys", + "ES5", + "shim" + ], + "license": "MIT", + "main": "index.js", + "name": "object-keys", + "repository": { + "type": "git", + "url": "git://github.com/ljharb/object-keys.git" + }, + "scripts": { + "coverage": "covert test/*.js", + "coverage-quiet": "covert test/*.js --quiet", + "eslint": "eslint test/*.js *.js", + "jscs": "jscs test/*.js *.js", + "lint": "npm run --silent jscs && npm run --silent eslint", + "posttest": "npm run --silent security", + "pretest": "npm run --silent lint", + "security": "nsp check", + "test": "npm run --silent tests-only", + "tests-only": "node test/index.js" + }, + "testling": { + "files": "test/index.js", + "browsers": [ + "iexplore/6.0..latest", + "firefox/3.0..6.0", + "firefox/15.0..latest", + "firefox/nightly", + "chrome/4.0..10.0", + "chrome/20.0..latest", + "chrome/canary", + "opera/10.0..latest", + "opera/next", + "safari/4.0..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2" + ] + }, + "version": "1.0.12" +} diff --git a/nodejs/node_modules/object-keys/test/index.js b/nodejs/node_modules/object-keys/test/index.js new file mode 100755 index 0000000..5402465 --- /dev/null +++ b/nodejs/node_modules/object-keys/test/index.js @@ -0,0 +1,5 @@ +'use strict'; + +require('./isArguments'); + +require('./shim'); diff --git a/nodejs/node_modules/redis-commands/.travis.yml b/nodejs/node_modules/redis-commands/.travis.yml new file mode 100755 index 0000000..2badd29 --- /dev/null +++ b/nodejs/node_modules/redis-commands/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +sudo: false +node_js: + - "6" + - "8" + - "9" + - "10" +after_success: + - CODECLIMATE_REPO_TOKEN=b57723fafcf0516f275d6b380cd506fd082ea88d86507eb82c8abd489b9b9a09 node ./node_modules/.bin/codeclimate-test-reporter < coverage/lcov.info diff --git a/nodejs/node_modules/redis-commands/LICENSE b/nodejs/node_modules/redis-commands/LICENSE new file mode 100755 index 0000000..39d23f8 --- /dev/null +++ b/nodejs/node_modules/redis-commands/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 NodeRedis + +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/nodejs/node_modules/redis-commands/README.md b/nodejs/node_modules/redis-commands/README.md new file mode 100755 index 0000000..de51822 --- /dev/null +++ b/nodejs/node_modules/redis-commands/README.md @@ -0,0 +1,51 @@ +# Redis Commands + +[![Build Status](https://travis-ci.org/NodeRedis/redis-commands.png?branch=master)](https://travis-ci.org/NodeRedis/redis-commands) +[![Code Climate](https://codeclimate.com/github/NodeRedis/redis-commands/badges/gpa.svg)](https://codeclimate.com/github/NodeRedis/redis-commands) +[![Test Coverage](https://codeclimate.com/github/NodeRedis/redis-commands/badges/coverage.svg)](https://codeclimate.com/github/NodeRedis/redis-commands/coverage) + +This module exports all the commands that Redis supports. + +## Install + +```shell +$ npm install redis-commands +``` + +## Usage + +```javascript +var commands = require('redis-commands'); +``` + +`.list` is an array contains all the lowercased commands: + +```javascript +commands.list.forEach(function (command) { + console.log(command); +}); +``` + +`.exists()` is used to check if the command exists: + +```javascript +commands.exists('set') // true +commands.exists('other-command') // false +``` + +`.hasFlag()` is used to check if the command has the flag: + +```javascript +commands.hasFlag('set', 'readonly') // false +``` + +`.getKeyIndexes()` is used to get the indexes of keys in the command arguments: + +```javascript +commands.getKeyIndexes('set', ['key', 'value']) // [0] +commands.getKeyIndexes('mget', ['key1', 'key2']) // [0, 1] +``` + +## Acknowledgment + +Thank [@Yuan Chuan](https://github.com/yuanchuan) for the package name. The original redis-commands is renamed to [@yuanchuan/redis-commands](https://www.npmjs.com/package/@yuanchuan/redis-commands). diff --git a/nodejs/node_modules/redis-commands/changelog.md b/nodejs/node_modules/redis-commands/changelog.md new file mode 100755 index 0000000..3ddfc5f --- /dev/null +++ b/nodejs/node_modules/redis-commands/changelog.md @@ -0,0 +1,58 @@ +## v.1.3.5 - 28 Feb, 2018 + +Bugfix + +- Rebuild the commands with the latest stable release. + In v.1.3.3 the wrong Redis version was used. + +## v.1.3.4 - 26 Feb, 2018 + +Chore + +- Removed coverage folder from npm + +## v.1.3.3 - 24 Feb, 2018 + +Features + +- Rebuild the commands + +## v.1.3.2 - 24 Feb, 2018 + +Chore + +- Updated dependencies +- Fixed typos + +## v.1.3.1 - 25 Jan, 2017 + +Bugfix + +- Fix require for for webpack + +## v.1.3.0 - 20 Oct, 2016 + +Features + +- Rebuild the commands with the newest Redis unstable release + +## v.1.2.0 - 21 Apr, 2016 + +Features + +- Added support for `MIGRATE [...] KEYS key1, key2` (Redis >= v.3.0.6) +- Added build sanity check for unhandled commands with moveable keys +- Rebuild the commands with the newest unstable release +- Improved performance of .getKeyIndexes() + +Bugfix + +- Fixed command command returning the wrong arity due to a Redis bug +- Fixed brpop command returning the wrong keystop due to a Redis bug + +## v.1.1.0 - 09 Feb, 2016 + +Features + +- Added .exists() to check for command existence +- Improved performance of .hasFlag() diff --git a/nodejs/node_modules/redis-commands/commands.json b/nodejs/node_modules/redis-commands/commands.json new file mode 100755 index 0000000..140517b --- /dev/null +++ b/nodejs/node_modules/redis-commands/commands.json @@ -0,0 +1,1992 @@ +{ + "append": { + "arity": 3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "asking": { + "arity": 1, + "flags": [ + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "auth": { + "arity": 2, + "flags": [ + "noscript", + "loading", + "stale", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "bgrewriteaof": { + "arity": 1, + "flags": [ + "admin" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "bgsave": { + "arity": -1, + "flags": [ + "admin" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "bitcount": { + "arity": -2, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "bitfield": { + "arity": -2, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "bitop": { + "arity": -4, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 2, + "keyStop": -1, + "step": 1 + }, + "bitpos": { + "arity": -3, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "blpop": { + "arity": -3, + "flags": [ + "write", + "noscript" + ], + "keyStart": 1, + "keyStop": -2, + "step": 1 + }, + "brpop": { + "arity": -3, + "flags": [ + "write", + "noscript" + ], + "keyStart": 1, + "keyStop": -2, + "step": 1 + }, + "brpoplpush": { + "arity": 4, + "flags": [ + "write", + "denyoom", + "noscript" + ], + "keyStart": 1, + "keyStop": 2, + "step": 1 + }, + "bzpopmax": { + "arity": -2, + "flags": [ + "write", + "noscript", + "fast" + ], + "keyStart": 1, + "keyStop": -2, + "step": 1 + }, + "bzpopmin": { + "arity": -2, + "flags": [ + "write", + "noscript", + "fast" + ], + "keyStart": 1, + "keyStop": -2, + "step": 1 + }, + "client": { + "arity": -2, + "flags": [ + "admin", + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "cluster": { + "arity": -2, + "flags": [ + "admin" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "command": { + "arity": 1, + "flags": [ + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "config": { + "arity": -2, + "flags": [ + "admin", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "dbsize": { + "arity": 1, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "debug": { + "arity": -2, + "flags": [ + "admin", + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "decr": { + "arity": 2, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "decrby": { + "arity": 3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "del": { + "arity": -2, + "flags": [ + "write" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "discard": { + "arity": 1, + "flags": [ + "noscript", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "dump": { + "arity": 2, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "echo": { + "arity": 2, + "flags": [ + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "eval": { + "arity": -3, + "flags": [ + "noscript", + "movablekeys" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "evalsha": { + "arity": -3, + "flags": [ + "noscript", + "movablekeys" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "exec": { + "arity": 1, + "flags": [ + "noscript", + "skip_monitor" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "exists": { + "arity": -2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "expire": { + "arity": 3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "expireat": { + "arity": 3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "flushall": { + "arity": -1, + "flags": [ + "write" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "flushdb": { + "arity": -1, + "flags": [ + "write" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "geoadd": { + "arity": -5, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "geodist": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "geohash": { + "arity": -2, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "geopos": { + "arity": -2, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "georadius": { + "arity": -6, + "flags": [ + "write", + "movablekeys" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "georadius_ro": { + "arity": -6, + "flags": [ + "readonly", + "movablekeys" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "georadiusbymember": { + "arity": -5, + "flags": [ + "write", + "movablekeys" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "georadiusbymember_ro": { + "arity": -5, + "flags": [ + "readonly", + "movablekeys" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "get": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "getbit": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "getrange": { + "arity": 4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "getset": { + "arity": 3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hdel": { + "arity": -3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hexists": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hget": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hgetall": { + "arity": 2, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hincrby": { + "arity": 4, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hincrbyfloat": { + "arity": 4, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hkeys": { + "arity": 2, + "flags": [ + "readonly", + "sort_for_script" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hlen": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hmget": { + "arity": -3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hmset": { + "arity": -4, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "host:": { + "arity": -1, + "flags": [ + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "hscan": { + "arity": -3, + "flags": [ + "readonly", + "random" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hset": { + "arity": -4, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hsetnx": { + "arity": 4, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hstrlen": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "hvals": { + "arity": 2, + "flags": [ + "readonly", + "sort_for_script" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "incr": { + "arity": 2, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "incrby": { + "arity": 3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "incrbyfloat": { + "arity": 3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "info": { + "arity": -1, + "flags": [ + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "keys": { + "arity": 2, + "flags": [ + "readonly", + "sort_for_script" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "lastsave": { + "arity": 1, + "flags": [ + "random", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "latency": { + "arity": -2, + "flags": [ + "admin", + "noscript", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "lindex": { + "arity": 3, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "linsert": { + "arity": 5, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "llen": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "lpop": { + "arity": 2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "lpush": { + "arity": -3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "lpushx": { + "arity": -3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "lrange": { + "arity": 4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "lrem": { + "arity": 4, + "flags": [ + "write" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "lset": { + "arity": 4, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "ltrim": { + "arity": 4, + "flags": [ + "write" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "memory": { + "arity": -2, + "flags": [ + "readonly" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "mget": { + "arity": -2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "migrate": { + "arity": -6, + "flags": [ + "write", + "movablekeys" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "module": { + "arity": -2, + "flags": [ + "admin", + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "monitor": { + "arity": 1, + "flags": [ + "admin", + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "move": { + "arity": 3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "mset": { + "arity": -3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": -1, + "step": 2 + }, + "msetnx": { + "arity": -3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": -1, + "step": 2 + }, + "multi": { + "arity": 1, + "flags": [ + "noscript", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "object": { + "arity": -2, + "flags": [ + "readonly" + ], + "keyStart": 2, + "keyStop": 2, + "step": 1 + }, + "persist": { + "arity": 2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "pexpire": { + "arity": 3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "pexpireat": { + "arity": 3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "pfadd": { + "arity": -2, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "pfcount": { + "arity": -2, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "pfdebug": { + "arity": -3, + "flags": [ + "write" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "pfmerge": { + "arity": -2, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "pfselftest": { + "arity": 1, + "flags": [ + "admin" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "ping": { + "arity": -1, + "flags": [ + "stale", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "post": { + "arity": -1, + "flags": [ + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "psetex": { + "arity": 4, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "psubscribe": { + "arity": -2, + "flags": [ + "pubsub", + "noscript", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "psync": { + "arity": 3, + "flags": [ + "readonly", + "admin", + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "pttl": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "publish": { + "arity": 3, + "flags": [ + "pubsub", + "loading", + "stale", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "pubsub": { + "arity": -2, + "flags": [ + "pubsub", + "random", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "punsubscribe": { + "arity": -1, + "flags": [ + "pubsub", + "noscript", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "quit": { + "arity": 1, + "flags": [ + "loading", + "stale", + "readonly" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "randomkey": { + "arity": 1, + "flags": [ + "readonly", + "random" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "readonly": { + "arity": 1, + "flags": [ + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "readwrite": { + "arity": 1, + "flags": [ + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "rename": { + "arity": 3, + "flags": [ + "write" + ], + "keyStart": 1, + "keyStop": 2, + "step": 1 + }, + "renamenx": { + "arity": 3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 2, + "step": 1 + }, + "replconf": { + "arity": -1, + "flags": [ + "admin", + "noscript", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "restore": { + "arity": -4, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "restore-asking": { + "arity": -4, + "flags": [ + "write", + "denyoom", + "asking" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "role": { + "arity": 1, + "flags": [ + "noscript", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "rpop": { + "arity": 2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "rpoplpush": { + "arity": 3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 2, + "step": 1 + }, + "rpush": { + "arity": -3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "rpushx": { + "arity": -3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "sadd": { + "arity": -3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "save": { + "arity": 1, + "flags": [ + "admin", + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "scan": { + "arity": -2, + "flags": [ + "readonly", + "random" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "scard": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "script": { + "arity": -2, + "flags": [ + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "sdiff": { + "arity": -2, + "flags": [ + "readonly", + "sort_for_script" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "sdiffstore": { + "arity": -3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "select": { + "arity": 2, + "flags": [ + "loading", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "set": { + "arity": -3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "setbit": { + "arity": 4, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "setex": { + "arity": 4, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "setnx": { + "arity": 3, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "setrange": { + "arity": 4, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "shutdown": { + "arity": -1, + "flags": [ + "admin", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "sinter": { + "arity": -2, + "flags": [ + "readonly", + "sort_for_script" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "sinterstore": { + "arity": -3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "sismember": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "slaveof": { + "arity": 3, + "flags": [ + "admin", + "noscript", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "slowlog": { + "arity": -2, + "flags": [ + "admin" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "smembers": { + "arity": 2, + "flags": [ + "readonly", + "sort_for_script" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "smove": { + "arity": 4, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 2, + "step": 1 + }, + "sort": { + "arity": -2, + "flags": [ + "write", + "denyoom", + "movablekeys" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "spop": { + "arity": -2, + "flags": [ + "write", + "random", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "srandmember": { + "arity": -2, + "flags": [ + "readonly", + "random" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "srem": { + "arity": -3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "sscan": { + "arity": -3, + "flags": [ + "readonly", + "random" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "strlen": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "subscribe": { + "arity": -2, + "flags": [ + "pubsub", + "noscript", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "substr": { + "arity": 4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "sunion": { + "arity": -2, + "flags": [ + "readonly", + "sort_for_script" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "sunionstore": { + "arity": -3, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "swapdb": { + "arity": 3, + "flags": [ + "write", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "sync": { + "arity": 1, + "flags": [ + "readonly", + "admin", + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "time": { + "arity": 1, + "flags": [ + "random", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "touch": { + "arity": -2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "ttl": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "type": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "unlink": { + "arity": -2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "unsubscribe": { + "arity": -1, + "flags": [ + "pubsub", + "noscript", + "loading", + "stale" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "unwatch": { + "arity": 1, + "flags": [ + "noscript", + "fast" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "wait": { + "arity": 3, + "flags": [ + "noscript" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "watch": { + "arity": -2, + "flags": [ + "noscript", + "fast" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "xack": { + "arity": -3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xadd": { + "arity": -5, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xclaim": { + "arity": -5, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xdel": { + "arity": -2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xgroup": { + "arity": -2, + "flags": [ + "write", + "denyoom" + ], + "keyStart": 2, + "keyStop": 2, + "step": 1 + }, + "xinfo": { + "arity": -2, + "flags": [ + "readonly" + ], + "keyStart": 2, + "keyStop": 2, + "step": 1 + }, + "xlen": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xpending": { + "arity": -3, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xrange": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xread": { + "arity": -3, + "flags": [ + "readonly", + "noscript", + "movablekeys" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xreadgroup": { + "arity": -3, + "flags": [ + "write", + "noscript", + "movablekeys" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xrevrange": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "xtrim": { + "arity": -2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zadd": { + "arity": -4, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zcard": { + "arity": 2, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zcount": { + "arity": 4, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zincrby": { + "arity": 4, + "flags": [ + "write", + "denyoom", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zinterstore": { + "arity": -4, + "flags": [ + "write", + "denyoom", + "movablekeys" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + }, + "zlexcount": { + "arity": 4, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zpopmax": { + "arity": -2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "zpopmin": { + "arity": -2, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": -1, + "step": 1 + }, + "zrange": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrangebylex": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrangebyscore": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrank": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrem": { + "arity": -3, + "flags": [ + "write", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zremrangebylex": { + "arity": 4, + "flags": [ + "write" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zremrangebyrank": { + "arity": 4, + "flags": [ + "write" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zremrangebyscore": { + "arity": 4, + "flags": [ + "write" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrevrange": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrevrangebylex": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrevrangebyscore": { + "arity": -4, + "flags": [ + "readonly" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zrevrank": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zscan": { + "arity": -3, + "flags": [ + "readonly", + "random" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zscore": { + "arity": 3, + "flags": [ + "readonly", + "fast" + ], + "keyStart": 1, + "keyStop": 1, + "step": 1 + }, + "zunionstore": { + "arity": -4, + "flags": [ + "write", + "denyoom", + "movablekeys" + ], + "keyStart": 0, + "keyStop": 0, + "step": 0 + } +} \ No newline at end of file diff --git a/nodejs/node_modules/redis-commands/index.js b/nodejs/node_modules/redis-commands/index.js new file mode 100755 index 0000000..8b58437 --- /dev/null +++ b/nodejs/node_modules/redis-commands/index.js @@ -0,0 +1,155 @@ +'use strict' + +var commands = require('./commands.json') + +/** + * Redis command list + * + * All commands are lowercased. + * + * @var {string[]} + * @public + */ +exports.list = Object.keys(commands) + +var flags = {} +exports.list.forEach(function (commandName) { + flags[commandName] = commands[commandName].flags.reduce(function (flags, flag) { + flags[flag] = true + return flags + }, {}) +}) +/** + * Check if the command exists + * + * @param {string} commandName - the command name + * @return {boolean} result + * @public + */ +exports.exists = function (commandName) { + return Boolean(commands[commandName]) +} + +/** + * Check if the command has the flag + * + * Some of possible flags: readonly, noscript, loading + * @param {string} commandName - the command name + * @param {string} flag - the flag to check + * @return {boolean} result + * @public + */ +exports.hasFlag = function (commandName, flag) { + if (!flags[commandName]) { + throw new Error('Unknown command ' + commandName) + } + + return Boolean(flags[commandName][flag]) +} + +/** + * Get indexes of keys in the command arguments + * + * @param {string} commandName - the command name + * @param {string[]} args - the arguments of the command + * @param {object} [options] - options + * @param {boolean} [options.parseExternalKey] - parse external keys + * @return {number[]} - the list of the index + * @public + * + * @example + * ```javascript + * getKeyIndexes('set', ['key', 'value']) // [0] + * getKeyIndexes('mget', ['key1', 'key2']) // [0, 1] + * ``` + */ +exports.getKeyIndexes = function (commandName, args, options) { + var command = commands[commandName] + if (!command) { + throw new Error('Unknown command ' + commandName) + } + + if (!Array.isArray(args)) { + throw new Error('Expect args to be an array') + } + + var keys = [] + var i, keyStart, keyStop, parseExternalKey + switch (commandName) { + case 'zunionstore': + case 'zinterstore': + keys.push(0) + // fall through + case 'eval': + case 'evalsha': + keyStop = Number(args[1]) + 2 + for (i = 2; i < keyStop; i++) { + keys.push(i) + } + break + case 'sort': + parseExternalKey = options && options.parseExternalKey + keys.push(0) + for (i = 1; i < args.length - 1; i++) { + if (typeof args[i] !== 'string') { + continue + } + var directive = args[i].toUpperCase() + if (directive === 'GET') { + i += 1 + if (args[i] !== '#') { + if (parseExternalKey) { + keys.push([i, getExternalKeyNameLength(args[i])]) + } else { + keys.push(i) + } + } + } else if (directive === 'BY') { + i += 1 + if (parseExternalKey) { + keys.push([i, getExternalKeyNameLength(args[i])]) + } else { + keys.push(i) + } + } else if (directive === 'STORE') { + i += 1 + keys.push(i) + } + } + break + case 'migrate': + if (args[2] === '') { + for (i = 5; i < args.length - 1; i++) { + if (args[i].toUpperCase() === 'KEYS') { + for (var j = i + 1; j < args.length; j++) { + keys.push(j) + } + break + } + } + } else { + keys.push(2) + } + break + default: + // step has to be at least one in this case, otherwise the command does not contain a key + if (command.step > 0) { + keyStart = command.keyStart - 1 + keyStop = command.keyStop > 0 ? command.keyStop : args.length + command.keyStop + 1 + for (i = keyStart; i < keyStop; i += command.step) { + keys.push(i) + } + } + break + } + + return keys +} + +function getExternalKeyNameLength (key) { + if (typeof key !== 'string') { + key = String(key) + } + var hashPos = key.indexOf('->') + return hashPos === -1 ? key.length : hashPos +} diff --git a/nodejs/node_modules/redis-commands/package.json b/nodejs/node_modules/redis-commands/package.json new file mode 100755 index 0000000..4a28ca3 --- /dev/null +++ b/nodejs/node_modules/redis-commands/package.json @@ -0,0 +1,72 @@ +{ + "_args": [ + [ + "redis-commands@1.4.0", + "/www/wwwroot/Adminx.cc/nodejs" + ] + ], + "_from": "redis-commands@1.4.0", + "_id": "redis-commands@1.4.0", + "_inBundle": false, + "_integrity": "sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==", + "_location": "/redis-commands", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "redis-commands@1.4.0", + "name": "redis-commands", + "escapedName": "redis-commands", + "rawSpec": "1.4.0", + "saveSpec": null, + "fetchSpec": "1.4.0" + }, + "_requiredBy": [ + "/redis" + ], + "_resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.4.0.tgz", + "_spec": "1.4.0", + "_where": "/www/wwwroot/Adminx.cc/nodejs", + "author": { + "name": "luin", + "email": "i@zihua.li", + "url": "http://zihua.li" + }, + "bugs": { + "url": "https://github.com/NodeRedis/redis-commands/issues" + }, + "description": "Redis commands", + "devDependencies": { + "chai": "^4.0.1", + "codeclimate-test-reporter": "^0.4.0", + "ioredis": "^3.0.0", + "istanbul": "^0.4.3", + "mocha": "^5.0.0", + "safe-stable-stringify": "^1.0.0", + "snazzy": "^8.0.0", + "standard": "^11.0.0" + }, + "homepage": "https://github.com/NodeRedis/redis-commands", + "keywords": [ + "redis", + "commands", + "prefix" + ], + "license": "MIT", + "main": "index.js", + "name": "redis-commands", + "repository": { + "type": "git", + "url": "git+https://github.com/NodeRedis/redis-commands.git" + }, + "scripts": { + "build": "node tools/build", + "coverage": "node ./node_modules/istanbul/lib/cli.js cover --preserve-comments ./node_modules/mocha/bin/_mocha -- -R spec", + "coverage:check": "node ./node_modules/istanbul/lib/cli.js check-coverage --branch 100 --statement 100", + "lint": "standard --fix --verbose | snazzy", + "posttest": "npm run coverage && npm run coverage:check", + "pretest": "npm run lint", + "test": "mocha" + }, + "version": "1.4.0" +} diff --git a/nodejs/node_modules/redis-commands/tools/build.js b/nodejs/node_modules/redis-commands/tools/build.js new file mode 100755 index 0000000..f5fca0a --- /dev/null +++ b/nodejs/node_modules/redis-commands/tools/build.js @@ -0,0 +1,62 @@ +var fs = require('fs') +var path = require('path') +var stringify = require('safe-stable-stringify') +var commandPath = path.join(__dirname, '..', 'commands.json') +var redisCommands = require('../') + +var Redis = require('ioredis') +var redis = new Redis(process.env.REDIS_URI) + +redis.command().then(function (res) { + redis.disconnect() + + // Find all special handled cases + var movableKeys = String(redisCommands.getKeyIndexes).match(/case '[a-z-]+':/g).map(function (entry) { + return entry.replace(/^case '|':$/g, '') + }) + + var commands = res.reduce(function (prev, current) { + var currentCommandPos = movableKeys.indexOf(current[0]) + if (currentCommandPos !== -1 && current[2].indexOf('movablekeys') !== -1) { + movableKeys.splice(currentCommandPos, 1) + } + // https://github.com/antirez/redis/issues/2598 + if (current[0] === 'brpop' && current[4] === 1) { + current[4] = -2 + } + prev[current[0]] = { + arity: current[1] || 1, // https://github.com/antirez/redis/pull/2986 + flags: current[2], + keyStart: current[3], + keyStop: current[4], + step: current[5] + } + return prev + }, {}) + + // Future proof. Redis might implement this at some point + // https://github.com/antirez/redis/pull/2982 + if (!commands.quit) { + commands.quit = { + arity: 1, + flags: [ + 'loading', + 'stale', + 'readonly' + ], + keyStart: 0, + keyStop: 0, + step: 0 + } + } + + if (movableKeys.length !== 0) { + throw new Error('Not all commands (\'' + movableKeys.join('\', \'') + '\') with the "movablekeys" flag are handled in the code') + } + + // Use safe-stable-stringify instead fo JSON.stringify + // for easier diffing + var content = stringify(commands, null, ' ') + + fs.writeFileSync(commandPath, content) +}) diff --git a/nodejs/node_modules/redis-parser/.npmignore b/nodejs/node_modules/redis-parser/.npmignore new file mode 100755 index 0000000..af7d371 --- /dev/null +++ b/nodejs/node_modules/redis-parser/.npmignore @@ -0,0 +1,15 @@ +# IntelliJ project files +.idea +*.iml +out +gen + +# Unrelevant files and folders +benchmark +coverage +test +.travis.yml +.gitignore +*.log +.vscode +.codeclimate.yml \ No newline at end of file diff --git a/nodejs/node_modules/redis-parser/LICENSE b/nodejs/node_modules/redis-parser/LICENSE new file mode 100755 index 0000000..39d23f8 --- /dev/null +++ b/nodejs/node_modules/redis-parser/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 NodeRedis + +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/nodejs/node_modules/redis-parser/README.md b/nodejs/node_modules/redis-parser/README.md new file mode 100755 index 0000000..ff448f0 --- /dev/null +++ b/nodejs/node_modules/redis-parser/README.md @@ -0,0 +1,163 @@ +[![Build Status](https://travis-ci.org/NodeRedis/node-redis-parser.png?branch=master)](https://travis-ci.org/NodeRedis/node-redis-parser) +[![Test Coverage](https://codeclimate.com/github/NodeRedis/node-redis-parser/badges/coverage.svg)](https://codeclimate.com/github/NodeRedis/node-redis-parser/coverage) +[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) + +# redis-parser + +A high performance javascript redis parser built for [node_redis](https://github.com/NodeRedis/node_redis) and [ioredis](https://github.com/luin/ioredis). Parses all [RESP](http://redis.io/topics/protocol) data. + +## Install + +Install with [NPM](https://npmjs.org/): + + npm install redis-parser + +## Usage + +```js +var Parser = require('redis-parser'); + +var myParser = new Parser(options); +``` + +### Options + +* `returnReply`: *function*; mandatory +* `returnError`: *function*; mandatory +* `returnFatalError`: *function*; optional, defaults to the returnError function +* `returnBuffers`: *boolean*; optional, defaults to false +* `stringNumbers`: *boolean*; optional, defaults to false + +### Functions + +* `reset()`: reset the parser to it's initial state +* `setReturnBuffers(boolean)`: (JSParser only) set the returnBuffers option on/off without resetting the parser +* `setStringNumbers(boolean)`: (JSParser only) set the stringNumbers option on/off without resetting the parser + +### Error classes + +* `RedisError` sub class of Error +* `ReplyError` sub class of RedisError +* `ParserError` sub class of RedisError + +All Redis errors will be returned as `ReplyErrors` while a parser error is returned as `ParserError`. +All error classes are exported by the parser. + +### Example + +```js +var Parser = require("redis-parser"); + +function Library () {} + +Library.prototype.returnReply = function (reply) { ... } +Library.prototype.returnError = function (err) { ... } +Library.prototype.returnFatalError = function (err) { ... } + +var lib = new Library(); + +var parser = new Parser({ + returnReply: function(reply) { + lib.returnReply(reply); + }, + returnError: function(err) { + lib.returnError(err); + }, + returnFatalError: function (err) { + lib.returnFatalError(err); + } +}); + +Library.prototype.streamHandler = function () { + this.stream.on('data', function (buffer) { + // Here the data (e.g. `new Buffer('$5\r\nHello\r\n'`)) is passed to the parser and the result is passed to either function depending on the provided data. + parser.execute(buffer); + }); +}; +``` +You do not have to use the returnFatalError function. Fatal errors will be returned in the normal error function in that case. + +And if you want to return buffers instead of strings, you can do this by adding the `returnBuffers` option. + +If you handle with big numbers that are to large for JS (Number.MAX_SAFE_INTEGER === 2^53 - 16) please use the `stringNumbers` option. That way all numbers are going to be returned as String and you can handle them safely. + +```js +// Same functions as in the first example + +var parser = new Parser({ + returnReply: function(reply) { + lib.returnReply(reply); + }, + returnError: function(err) { + lib.returnError(err); + }, + returnBuffers: true, // All strings are returned as Buffer e.g. + stringNumbers: true // All numbers are returned as String +}); + +// The streamHandler as above +``` + +## Protocol errors + +To handle protocol errors (this is very unlikely to happen) gracefully you should add the returnFatalError option, reject any still running command (they might have been processed properly but the reply is just wrong), destroy the socket and reconnect. Note that while doing this no new command may be added, so all new commands have to be buffered in the meantime, otherwise a chunk might still contain partial data of a following command that was already processed properly but answered in the same chunk as the command that resulted in the protocol error. + +## Contribute + +The parser is highly optimized but there may still be further optimizations possible. + + npm install + npm test + npm run benchmark + +Currently the benchmark compares the performance against the hiredis parser: + + HIREDIS: $ multiple chunks in a bulk string x 859,880 ops/sec ±1.22% (82 runs sampled) + HIREDIS BUF: $ multiple chunks in a bulk string x 608,869 ops/sec ±1.72% (85 runs sampled) + JS PARSER: $ multiple chunks in a bulk string x 910,590 ops/sec ±0.87% (89 runs sampled) + JS PARSER BUF: $ multiple chunks in a bulk string x 1,299,507 ops/sec ±2.18% (84 runs sampled) + + HIREDIS: + multiple chunks in a string x 1,787,203 ops/sec ±0.58% (96 runs sampled) + HIREDIS BUF: + multiple chunks in a string x 943,584 ops/sec ±1.62% (87 runs sampled) + JS PARSER: + multiple chunks in a string x 2,008,264 ops/sec ±1.01% (91 runs sampled) + JS PARSER BUF: + multiple chunks in a string x 2,045,546 ops/sec ±0.78% (91 runs sampled) + + HIREDIS: $ 4mb bulk string x 310 ops/sec ±1.58% (75 runs sampled) + HIREDIS BUF: $ 4mb bulk string x 471 ops/sec ±2.28% (78 runs sampled) + JS PARSER: $ 4mb bulk string x 747 ops/sec ±2.43% (85 runs sampled) + JS PARSER BUF: $ 4mb bulk string x 846 ops/sec ±5.52% (72 runs sampled) + + HIREDIS: + simple string x 2,324,866 ops/sec ±1.61% (90 runs sampled) + HIREDIS BUF: + simple string x 1,085,823 ops/sec ±2.47% (82 runs sampled) + JS PARSER: + simple string x 4,567,358 ops/sec ±1.97% (81 runs sampled) + JS PARSER BUF: + simple string x 5,433,901 ops/sec ±0.66% (93 runs sampled) + + HIREDIS: : integer x 2,332,946 ops/sec ±0.47% (93 runs sampled) + JS PARSER: : integer x 17,730,449 ops/sec ±0.73% (91 runs sampled) + JS PARSER STR: : integer x 12,942,037 ops/sec ±0.51% (92 runs sampled) + + HIREDIS: : big integer x 2,012,572 ops/sec ±0.33% (93 runs sampled) + JS PARSER: : big integer x 10,210,923 ops/sec ±0.94% (94 runs sampled) + JS PARSER STR: : big integer x 4,453,320 ops/sec ±0.52% (94 runs sampled) + + HIREDIS: * array x 44,479 ops/sec ±0.55% (94 runs sampled) + HIREDIS BUF: * array x 14,391 ops/sec ±1.04% (86 runs sampled) + JS PARSER: * array x 53,796 ops/sec ±2.08% (79 runs sampled) + JS PARSER BUF: * array x 72,428 ops/sec ±0.72% (93 runs sampled) + + HIREDIS: * big nested array x 217 ops/sec ±0.97% (83 runs sampled) + HIREDIS BUF: * big nested array x 255 ops/sec ±2.28% (77 runs sampled) + JS PARSER: * big nested array x 242 ops/sec ±1.10% (85 runs sampled) + JS PARSER BUF: * big nested array x 375 ops/sec ±1.21% (88 runs sampled) + + HIREDIS: - error x 78,821 ops/sec ±0.80% (93 runs sampled) + JS PARSER: - error x 143,382 ops/sec ±0.75% (92 runs sampled) + + Platform info: + Ubuntu 16.10 + Node.js 7.4.0 + Intel(R) Core(TM) i7-5600U CPU + +## License + +[MIT](./LICENSE) diff --git a/nodejs/node_modules/redis-parser/changelog.md b/nodejs/node_modules/redis-parser/changelog.md new file mode 100755 index 0000000..5cd9470 --- /dev/null +++ b/nodejs/node_modules/redis-parser/changelog.md @@ -0,0 +1,138 @@ +## v.2.6.0 - 03 Apr, 2017 + +Internals + +- Use Buffer.allocUnsafe instead of new Buffer() with modern Node.js versions + +## v.2.5.0 - 11 Mar, 2017 + +Features + +- Added a `ParserError` class to differentiate them to ReplyErrors. The class is also exported + +Bugfixes + +- All errors now show their error message again next to the error name in the stack trace +- ParserErrors now show the offset and buffer attributes while being logged + +## v.2.4.1 - 05 Feb, 2017 + +Bugfixes + +- Fixed minimal memory consumption overhead for chunked buffers + +## v.2.4.0 - 25 Jan, 2017 + +Features + +- Added `reset` function to reset the parser to it's initial values +- Added `setReturnBuffers` function to reset the returnBuffers option (Only for the JSParser) +- Added `setStringNumbers` function to reset the stringNumbers option (Only for the JSParser) +- All Errors are now of sub classes of the new `RedisError` class. It is also exported. +- Improved bulk string chunked data handling performance + +Bugfixes + +- Parsing time for big nested arrays is now linear + +## v.2.3.0 - 25 Nov, 2016 + +Features + +- Parsing time for big arrays (e.g. 4mb+) is now linear and works well for arbitrary array sizes + +This case is a magnitude faster than before + + OLD STR: * big array x 1.09 ops/sec ±2.15% (7 runs sampled) + OLD BUF: * big array x 1.23 ops/sec ±2.67% (8 runs sampled) + + NEW STR: * big array x 273 ops/sec ±2.09% (85 runs sampled) + NEW BUF: * big array x 259 ops/sec ±1.32% (85 runs sampled) + (~10mb array with 1000 entries) + +## v.2.2.0 - 18 Nov, 2016 + +Features + +- Improve `stringNumbers` parsing performance by up to 100% + +Bugfixes + +- Do not unref the interval anymore due to issues with NodeJS + +## v.2.1.1 - 31 Oct, 2016 + +Bugfixes + +- Remove erroneously added const to support Node.js 0.10 + +## v.2.1.0 - 30 Oct, 2016 + +Features + +- Improve parser errors by adding more detailed information to them +- Accept manipulated Object.prototypes +- Unref the interval if used + +## v.2.0.4 - 21 Jul, 2016 + +Bugfixes + +- Fixed multi byte characters getting corrupted + +## v.2.0.3 - 17 Jun, 2016 + +Bugfixes + +- Fixed parser not working with huge buffers (e.g. 300 MB) + +## v.2.0.2 - 08 Jun, 2016 + +Bugfixes + +- Fixed parser with returnBuffers option returning corrupted data + +## v.2.0.1 - 04 Jun, 2016 + +Bugfixes + +- Fixed multiple parsers working concurrently resulting in faulty data in some cases + +## v.2.0.0 - 29 May, 2016 + +The javascript parser got completely rewritten by [Michael Diarmid](https://github.com/Salakar) and [Ruben Bridgewater](https://github.com/BridgeAR) and is now a lot faster than the hiredis parser. +Therefore the hiredis parser was deprecated and should only be used for testing purposes and benchmarking comparison. + +All Errors returned by the parser are from now on of class ReplyError + +Features + +- Improved performance by up to 15x as fast as before +- Improved options validation +- Added ReplyError Class +- Added parser benchmark +- Switched default parser from hiredis to JS, no matter if hiredis is installed or not + +Removed + +- Deprecated hiredis support + +## v.1.3.0 - 27 Mar, 2016 + +Features + +- Added `auto` as parser name option to check what parser is available +- Non existing requested parsers falls back into auto mode instead of always choosing the JS parser + +## v.1.2.0 - 27 Mar, 2016 + +Features + +- Added `stringNumbers` option to make sure all numbers are returned as string instead of a js number for precision +- The parser is from now on going to print warnings if a parser is explicitly requested that does not exist and gracefully chooses the JS parser + +## v.1.1.0 - 26 Jan, 2016 + +Features + +- The parser is from now on going to reset itself on protocol errors diff --git a/nodejs/node_modules/redis-parser/index.js b/nodejs/node_modules/redis-parser/index.js new file mode 100755 index 0000000..a0c777d --- /dev/null +++ b/nodejs/node_modules/redis-parser/index.js @@ -0,0 +1,6 @@ +'use strict' + +module.exports = require('./lib/parser') +module.exports.ReplyError = require('./lib/replyError') +module.exports.RedisError = require('./lib/redisError') +module.exports.ParserError = require('./lib/redisError') diff --git a/nodejs/node_modules/redis-parser/lib/hiredis.js b/nodejs/node_modules/redis-parser/lib/hiredis.js new file mode 100755 index 0000000..0f94fbe --- /dev/null +++ b/nodejs/node_modules/redis-parser/lib/hiredis.js @@ -0,0 +1,62 @@ +'use strict' + +var hiredis = require('hiredis') +var ReplyError = require('../lib/replyError') +var ParserError = require('../lib/parserError') + +/** + * Parse data + * @param parser + * @returns {*} + */ +function parseData (parser, data) { + try { + return parser.reader.get() + } catch (err) { + // Protocol errors land here + // Reset the parser. Otherwise new commands can't be processed properly + parser.reader = new hiredis.Reader(parser.options) + parser.returnFatalError(new ParserError(err.message, JSON.stringify(data), -1)) + } +} + +/** + * Hiredis Parser + * @param options + * @constructor + */ +function HiredisReplyParser (options) { + this.returnError = options.returnError + this.returnFatalError = options.returnFatalError || options.returnError + this.returnReply = options.returnReply + this.name = 'hiredis' + this.options = { + return_buffers: !!options.returnBuffers + } + this.reader = new hiredis.Reader(this.options) +} + +HiredisReplyParser.prototype.execute = function (data) { + this.reader.feed(data) + var reply = parseData(this, data) + + while (reply !== undefined) { + if (reply && reply.name === 'Error') { + this.returnError(new ReplyError(reply.message)) + } else { + this.returnReply(reply) + } + reply = parseData(this, data) + } +} + +/** + * Reset the parser values to the initial state + * + * @returns {undefined} + */ +HiredisReplyParser.prototype.reset = function () { + this.reader = new hiredis.Reader(this.options) +} + +module.exports = HiredisReplyParser diff --git a/nodejs/node_modules/redis-parser/lib/parser.js b/nodejs/node_modules/redis-parser/lib/parser.js new file mode 100755 index 0000000..4ba6a18 --- /dev/null +++ b/nodejs/node_modules/redis-parser/lib/parser.js @@ -0,0 +1,581 @@ +'use strict' + +var StringDecoder = require('string_decoder').StringDecoder +var decoder = new StringDecoder() +var ReplyError = require('./replyError') +var ParserError = require('./parserError') +var bufferPool = bufferAlloc(32 * 1024) +var bufferOffset = 0 +var interval = null +var counter = 0 +var notDecreased = 0 +var isModern = typeof Buffer.allocUnsafe === 'function' + +/** + * For backwards compatibility + * @param len + * @returns {Buffer} + */ + +function bufferAlloc (len) { + return isModern ? Buffer.allocUnsafe(len) : new Buffer(len) +} + +/** + * Used for lengths and numbers only, faster perf on arrays / bulks + * @param parser + * @returns {*} + */ +function parseSimpleNumbers (parser) { + var offset = parser.offset + var length = parser.buffer.length - 1 + var number = 0 + var sign = 1 + + if (parser.buffer[offset] === 45) { + sign = -1 + offset++ + } + + while (offset < length) { + var c1 = parser.buffer[offset++] + if (c1 === 13) { // \r\n + parser.offset = offset + 1 + return sign * number + } + number = (number * 10) + (c1 - 48) + } +} + +/** + * Used for integer numbers in case of the returnNumbers option + * + * The maximimum possible integer to use is: Math.floor(Number.MAX_SAFE_INTEGER / 10) + * Staying in a SMI Math.floor((Math.pow(2, 32) / 10) - 1) is even more efficient though + * + * @param parser + * @returns {*} + */ +function parseStringNumbers (parser) { + var offset = parser.offset + var length = parser.buffer.length - 1 + var number = 0 + var res = '' + + if (parser.buffer[offset] === 45) { + res += '-' + offset++ + } + + while (offset < length) { + var c1 = parser.buffer[offset++] + if (c1 === 13) { // \r\n + parser.offset = offset + 1 + if (number !== 0) { + res += number + } + return res + } else if (number > 429496728) { + res += (number * 10) + (c1 - 48) + number = 0 + } else if (c1 === 48 && number === 0) { + res += 0 + } else { + number = (number * 10) + (c1 - 48) + } + } +} + +/** + * Returns a string or buffer of the provided offset start and + * end ranges. Checks `optionReturnBuffers`. + * + * If returnBuffers is active, all return values are returned as buffers besides numbers and errors + * + * @param parser + * @param start + * @param end + * @returns {*} + */ +function convertBufferRange (parser, start, end) { + parser.offset = end + 2 + if (parser.optionReturnBuffers === true) { + return parser.buffer.slice(start, end) + } + + return parser.buffer.toString('utf-8', start, end) +} + +/** + * Parse a '+' redis simple string response but forward the offsets + * onto convertBufferRange to generate a string. + * @param parser + * @returns {*} + */ +function parseSimpleString (parser) { + var start = parser.offset + var offset = start + var buffer = parser.buffer + var length = buffer.length - 1 + + while (offset < length) { + if (buffer[offset++] === 13) { // \r\n + return convertBufferRange(parser, start, offset - 1) + } + } +} + +/** + * Returns the string length via parseSimpleNumbers + * @param parser + * @returns {*} + */ +function parseLength (parser) { + var string = parseSimpleNumbers(parser) + if (string !== undefined) { + return string + } +} + +/** + * Parse a ':' redis integer response + * + * If stringNumbers is activated the parser always returns numbers as string + * This is important for big numbers (number > Math.pow(2, 53)) as js numbers + * are 64bit floating point numbers with reduced precision + * + * @param parser + * @returns {*} + */ +function parseInteger (parser) { + if (parser.optionStringNumbers) { + return parseStringNumbers(parser) + } + return parseSimpleNumbers(parser) +} + +/** + * Parse a '$' redis bulk string response + * @param parser + * @returns {*} + */ +function parseBulkString (parser) { + var length = parseLength(parser) + if (length === undefined) { + return + } + if (length === -1) { + return null + } + var offsetEnd = parser.offset + length + if (offsetEnd + 2 > parser.buffer.length) { + parser.bigStrSize = offsetEnd + 2 + parser.bigOffset = parser.offset + parser.totalChunkSize = parser.buffer.length + parser.bufferCache.push(parser.buffer) + return + } + + return convertBufferRange(parser, parser.offset, offsetEnd) +} + +/** + * Parse a '-' redis error response + * @param parser + * @returns {Error} + */ +function parseError (parser) { + var string = parseSimpleString(parser) + if (string !== undefined) { + if (parser.optionReturnBuffers === true) { + string = string.toString() + } + return new ReplyError(string) + } +} + +/** + * Parsing error handler, resets parser buffer + * @param parser + * @param error + */ +function handleError (parser, error) { + parser.buffer = null + parser.returnFatalError(error) +} + +/** + * Parse a '*' redis array response + * @param parser + * @returns {*} + */ +function parseArray (parser) { + var length = parseLength(parser) + if (length === undefined) { + return + } + if (length === -1) { + return null + } + var responses = new Array(length) + return parseArrayElements(parser, responses, 0) +} + +/** + * Push a partly parsed array to the stack + * + * @param parser + * @param elem + * @param i + * @returns {undefined} + */ +function pushArrayCache (parser, elem, pos) { + parser.arrayCache.push(elem) + parser.arrayPos.push(pos) +} + +/** + * Parse chunked redis array response + * @param parser + * @returns {*} + */ +function parseArrayChunks (parser) { + var tmp = parser.arrayCache.pop() + var pos = parser.arrayPos.pop() + if (parser.arrayCache.length) { + var res = parseArrayChunks(parser) + if (!res) { + pushArrayCache(parser, tmp, pos) + return + } + tmp[pos++] = res + } + return parseArrayElements(parser, tmp, pos) +} + +/** + * Parse redis array response elements + * @param parser + * @param responses + * @param i + * @returns {*} + */ +function parseArrayElements (parser, responses, i) { + var bufferLength = parser.buffer.length + while (i < responses.length) { + var offset = parser.offset + if (parser.offset >= bufferLength) { + pushArrayCache(parser, responses, i) + return + } + var response = parseType(parser, parser.buffer[parser.offset++]) + if (response === undefined) { + if (!parser.arrayCache.length) { + parser.offset = offset + } + pushArrayCache(parser, responses, i) + return + } + responses[i] = response + i++ + } + + return responses +} + +/** + * Called the appropriate parser for the specified type. + * @param parser + * @param type + * @returns {*} + */ +function parseType (parser, type) { + switch (type) { + case 36: // $ + return parseBulkString(parser) + case 58: // : + return parseInteger(parser) + case 43: // + + return parseSimpleString(parser) + case 42: // * + return parseArray(parser) + case 45: // - + return parseError(parser) + default: + return handleError(parser, new ParserError( + 'Protocol error, got ' + JSON.stringify(String.fromCharCode(type)) + ' as reply type byte', + JSON.stringify(parser.buffer), + parser.offset + )) + } +} + +// All allowed options including their typeof value +var optionTypes = { + returnError: 'function', + returnFatalError: 'function', + returnReply: 'function', + returnBuffers: 'boolean', + stringNumbers: 'boolean', + name: 'string' +} + +/** + * Javascript Redis Parser + * @param options + * @constructor + */ +function JavascriptRedisParser (options) { + if (!(this instanceof JavascriptRedisParser)) { + return new JavascriptRedisParser(options) + } + if (!options || !options.returnError || !options.returnReply) { + throw new TypeError('Please provide all return functions while initiating the parser') + } + for (var key in options) { + // eslint-disable-next-line valid-typeof + if (optionTypes.hasOwnProperty(key) && typeof options[key] !== optionTypes[key]) { + throw new TypeError('The options argument contains the property "' + key + '" that is either unknown or of a wrong type') + } + } + if (options.name === 'hiredis') { + /* istanbul ignore next: hiredis is only supported for legacy usage */ + try { + var Hiredis = require('./hiredis') + console.error(new TypeError('Using hiredis is discouraged. Please use the faster JS parser by removing the name option.').stack.replace('Error', 'Warning')) + return new Hiredis(options) + } catch (e) { + console.error(new TypeError('Hiredis is not installed. Please remove the `name` option. The (faster) JS parser is used instead.').stack.replace('Error', 'Warning')) + } + } + this.optionReturnBuffers = !!options.returnBuffers + this.optionStringNumbers = !!options.stringNumbers + this.returnError = options.returnError + this.returnFatalError = options.returnFatalError || options.returnError + this.returnReply = options.returnReply + this.name = 'javascript' + this.reset() +} + +/** + * Reset the parser values to the initial state + * + * @returns {undefined} + */ +JavascriptRedisParser.prototype.reset = function () { + this.offset = 0 + this.buffer = null + this.bigStrSize = 0 + this.bigOffset = 0 + this.totalChunkSize = 0 + this.bufferCache = [] + this.arrayCache = [] + this.arrayPos = [] +} + +/** + * Set the returnBuffers option + * + * @param returnBuffers + * @returns {undefined} + */ +JavascriptRedisParser.prototype.setReturnBuffers = function (returnBuffers) { + if (typeof returnBuffers !== 'boolean') { + throw new TypeError('The returnBuffers argument has to be a boolean') + } + this.optionReturnBuffers = returnBuffers +} + +/** + * Set the stringNumbers option + * + * @param stringNumbers + * @returns {undefined} + */ +JavascriptRedisParser.prototype.setStringNumbers = function (stringNumbers) { + if (typeof stringNumbers !== 'boolean') { + throw new TypeError('The stringNumbers argument has to be a boolean') + } + this.optionStringNumbers = stringNumbers +} + +/** + * Decrease the bufferPool size over time + * @returns {undefined} + */ +function decreaseBufferPool () { + if (bufferPool.length > 50 * 1024) { + // Balance between increasing and decreasing the bufferPool + if (counter === 1 || notDecreased > counter * 2) { + // Decrease the bufferPool by 10% by removing the first 10% of the current pool + var sliceLength = Math.floor(bufferPool.length / 10) + if (bufferOffset <= sliceLength) { + bufferOffset = 0 + } else { + bufferOffset -= sliceLength + } + bufferPool = bufferPool.slice(sliceLength, bufferPool.length) + } else { + notDecreased++ + counter-- + } + } else { + clearInterval(interval) + counter = 0 + notDecreased = 0 + interval = null + } +} + +/** + * Check if the requested size fits in the current bufferPool. + * If it does not, reset and increase the bufferPool accordingly. + * + * @param length + * @returns {undefined} + */ +function resizeBuffer (length) { + if (bufferPool.length < length + bufferOffset) { + var multiplier = length > 1024 * 1024 * 75 ? 2 : 3 + if (bufferOffset > 1024 * 1024 * 111) { + bufferOffset = 1024 * 1024 * 50 + } + bufferPool = bufferAlloc(length * multiplier + bufferOffset) + bufferOffset = 0 + counter++ + if (interval === null) { + interval = setInterval(decreaseBufferPool, 50) + } + } +} + +/** + * Concat a bulk string containing multiple chunks + * + * Notes: + * 1) The first chunk might contain the whole bulk string including the \r + * 2) We are only safe to fully add up elements that are neither the first nor any of the last two elements + * + * @param parser + * @returns {String} + */ +function concatBulkString (parser) { + var list = parser.bufferCache + var chunks = list.length + var offset = parser.bigStrSize - parser.totalChunkSize + parser.offset = offset + if (offset <= 2) { + if (chunks === 2) { + return list[0].toString('utf8', parser.bigOffset, list[0].length + offset - 2) + } + chunks-- + offset = list[list.length - 2].length + offset + } + var res = decoder.write(list[0].slice(parser.bigOffset)) + for (var i = 1; i < chunks - 1; i++) { + res += decoder.write(list[i]) + } + res += decoder.end(list[i].slice(0, offset - 2)) + return res +} + +/** + * Concat the collected chunks from parser.bufferCache. + * + * Increases the bufferPool size beforehand if necessary. + * + * @param parser + * @returns {Buffer} + */ +function concatBulkBuffer (parser) { + var list = parser.bufferCache + var chunks = list.length + var length = parser.bigStrSize - parser.bigOffset - 2 + var offset = parser.bigStrSize - parser.totalChunkSize + parser.offset = offset + if (offset <= 2) { + if (chunks === 2) { + return list[0].slice(parser.bigOffset, list[0].length + offset - 2) + } + chunks-- + offset = list[list.length - 2].length + offset + } + resizeBuffer(length) + var start = bufferOffset + list[0].copy(bufferPool, start, parser.bigOffset, list[0].length) + bufferOffset += list[0].length - parser.bigOffset + for (var i = 1; i < chunks - 1; i++) { + list[i].copy(bufferPool, bufferOffset) + bufferOffset += list[i].length + } + list[i].copy(bufferPool, bufferOffset, 0, offset - 2) + bufferOffset += offset - 2 + return bufferPool.slice(start, bufferOffset) +} + +/** + * Parse the redis buffer + * @param buffer + * @returns {undefined} + */ +JavascriptRedisParser.prototype.execute = function execute (buffer) { + if (this.buffer === null) { + this.buffer = buffer + this.offset = 0 + } else if (this.bigStrSize === 0) { + var oldLength = this.buffer.length + var remainingLength = oldLength - this.offset + var newBuffer = bufferAlloc(remainingLength + buffer.length) + this.buffer.copy(newBuffer, 0, this.offset, oldLength) + buffer.copy(newBuffer, remainingLength, 0, buffer.length) + this.buffer = newBuffer + this.offset = 0 + if (this.arrayCache.length) { + var arr = parseArrayChunks(this) + if (!arr) { + return + } + this.returnReply(arr) + } + } else if (this.totalChunkSize + buffer.length >= this.bigStrSize) { + this.bufferCache.push(buffer) + var tmp = this.optionReturnBuffers ? concatBulkBuffer(this) : concatBulkString(this) + this.bigStrSize = 0 + this.bufferCache = [] + this.buffer = buffer + if (this.arrayCache.length) { + this.arrayCache[0][this.arrayPos[0]++] = tmp + tmp = parseArrayChunks(this) + if (!tmp) { + return + } + } + this.returnReply(tmp) + } else { + this.bufferCache.push(buffer) + this.totalChunkSize += buffer.length + return + } + + while (this.offset < this.buffer.length) { + var offset = this.offset + var type = this.buffer[this.offset++] + var response = parseType(this, type) + if (response === undefined) { + if (!this.arrayCache.length) { + this.offset = offset + } + return + } + + if (type === 45) { + this.returnError(response) + } else { + this.returnReply(response) + } + } + + this.buffer = null +} + +module.exports = JavascriptRedisParser diff --git a/nodejs/node_modules/redis-parser/lib/parserError.js b/nodejs/node_modules/redis-parser/lib/parserError.js new file mode 100755 index 0000000..883e554 --- /dev/null +++ b/nodejs/node_modules/redis-parser/lib/parserError.js @@ -0,0 +1,25 @@ +'use strict' + +var util = require('util') +var assert = require('assert') +var RedisError = require('./redisError') +var ADD_STACKTRACE = false + +function ParserError (message, buffer, offset) { + assert(buffer) + assert.strictEqual(typeof offset, 'number') + RedisError.call(this, message, ADD_STACKTRACE) + this.offset = offset + this.buffer = buffer + Error.captureStackTrace(this, ParserError) +} + +util.inherits(ParserError, RedisError) + +Object.defineProperty(ParserError.prototype, 'name', { + value: 'ParserError', + configurable: true, + writable: true +}) + +module.exports = ParserError diff --git a/nodejs/node_modules/redis-parser/lib/redisError.js b/nodejs/node_modules/redis-parser/lib/redisError.js new file mode 100755 index 0000000..374bbb7 --- /dev/null +++ b/nodejs/node_modules/redis-parser/lib/redisError.js @@ -0,0 +1,24 @@ +'use strict' + +var util = require('util') + +function RedisError (message, stack) { + Object.defineProperty(this, 'message', { + value: message || '', + configurable: true, + writable: true + }) + if (stack || stack === undefined) { + Error.captureStackTrace(this, RedisError) + } +} + +util.inherits(RedisError, Error) + +Object.defineProperty(RedisError.prototype, 'name', { + value: 'RedisError', + configurable: true, + writable: true +}) + +module.exports = RedisError diff --git a/nodejs/node_modules/redis-parser/lib/replyError.js b/nodejs/node_modules/redis-parser/lib/replyError.js new file mode 100755 index 0000000..080214e --- /dev/null +++ b/nodejs/node_modules/redis-parser/lib/replyError.js @@ -0,0 +1,23 @@ +'use strict' + +var util = require('util') +var RedisError = require('./redisError') +var ADD_STACKTRACE = false + +function ReplyError (message) { + var tmp = Error.stackTraceLimit + Error.stackTraceLimit = 2 + RedisError.call(this, message, ADD_STACKTRACE) + Error.captureStackTrace(this, ReplyError) + Error.stackTraceLimit = tmp +} + +util.inherits(ReplyError, RedisError) + +Object.defineProperty(ReplyError.prototype, 'name', { + value: 'ReplyError', + configurable: true, + writable: true +}) + +module.exports = ReplyError diff --git a/nodejs/node_modules/redis-parser/package.json b/nodejs/node_modules/redis-parser/package.json new file mode 100755 index 0000000..4d13186 --- /dev/null +++ b/nodejs/node_modules/redis-parser/package.json @@ -0,0 +1,81 @@ +{ + "_args": [ + [ + "redis-parser@2.6.0", + "/www/wwwroot/Adminx.cc/nodejs" + ] + ], + "_from": "redis-parser@2.6.0", + "_id": "redis-parser@2.6.0", + "_inBundle": false, + "_integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", + "_location": "/redis-parser", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "redis-parser@2.6.0", + "name": "redis-parser", + "escapedName": "redis-parser", + "rawSpec": "2.6.0", + "saveSpec": null, + "fetchSpec": "2.6.0" + }, + "_requiredBy": [ + "/redis" + ], + "_resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "_spec": "2.6.0", + "_where": "/www/wwwroot/Adminx.cc/nodejs", + "author": { + "name": "Ruben Bridgewater" + }, + "bugs": { + "url": "https://github.com/NodeRedis/node-redis-parser/issues" + }, + "description": "Javascript Redis protocol (RESP) parser", + "devDependencies": { + "benchmark": "^2.1.0", + "codeclimate-test-reporter": "^0.4.0", + "hiredis": "^0.5.0", + "intercept-stdout": "^0.1.2", + "istanbul": "^0.4.0", + "mocha": "^3.1.2", + "standard": "^9.0.0" + }, + "directories": { + "test": "test", + "lib": "lib" + }, + "engines": { + "node": ">=0.10.0" + }, + "homepage": "https://github.com/NodeRedis/node-redis-parser#readme", + "keywords": [ + "redis", + "protocol", + "parser", + "database", + "javascript", + "node", + "nodejs", + "resp", + "hiredis" + ], + "license": "MIT", + "main": "index.js", + "name": "redis-parser", + "repository": { + "type": "git", + "url": "git+https://github.com/NodeRedis/node-redis-parser.git" + }, + "scripts": { + "benchmark": "node ./benchmark", + "coverage": "node ./node_modules/istanbul/lib/cli.js cover --preserve-comments ./node_modules/mocha/bin/_mocha -- -R spec", + "coverage:check": "node ./node_modules/istanbul/lib/cli.js check-coverage --branch 100 --statement 100", + "lint": "standard --fix", + "posttest": "npm run lint && npm run coverage:check", + "test": "npm run coverage" + }, + "version": "2.6.0" +} diff --git a/nodejs/node_modules/redis/.eslintignore b/nodejs/node_modules/redis/.eslintignore new file mode 100755 index 0000000..fd16de3 --- /dev/null +++ b/nodejs/node_modules/redis/.eslintignore @@ -0,0 +1,4 @@ +node_modules/** +coverage/** +**.md +**.log diff --git a/nodejs/node_modules/redis/.eslintrc b/nodejs/node_modules/redis/.eslintrc new file mode 100755 index 0000000..75c7334 --- /dev/null +++ b/nodejs/node_modules/redis/.eslintrc @@ -0,0 +1,108 @@ +env: + node: true + es6: false + +rules: + # Possible Errors + # http://eslint.org/docs/rules/#possible-errors + comma-dangle: [2, "only-multiline"] + no-constant-condition: 2 + no-control-regex: 2 + no-debugger: 2 + no-dupe-args: 2 + no-dupe-keys: 2 + no-duplicate-case: 2 + no-empty: 2 + no-empty-character-class: 2 + no-ex-assign: 2 + no-extra-boolean-cast : 2 + no-extra-parens: [2, "functions"] + no-extra-semi: 2 + no-func-assign: 2 + no-invalid-regexp: 2 + no-irregular-whitespace: 2 + no-negated-in-lhs: 2 + no-obj-calls: 2 + no-regex-spaces: 2 + no-sparse-arrays: 2 + no-inner-declarations: 2 + no-unexpected-multiline: 2 + no-unreachable: 2 + use-isnan: 2 + valid-typeof: 2 + + # Best Practices + # http://eslint.org/docs/rules/#best-practices + array-callback-return: 2 + block-scoped-var: 2 + dot-notation: 2 + eqeqeq: 2 + no-else-return: 2 + no-extend-native: 2 + no-floating-decimal: 2 + no-extra-bind: 2 + no-fallthrough: 2 + no-labels: 2 + no-lone-blocks: 2 + no-loop-func: 2 + no-multi-spaces: 2 + no-multi-str: 2 + no-native-reassign: 2 + no-new-wrappers: 2 + no-octal: 2 + no-proto: 2 + no-redeclare: 2 + no-return-assign: 2 + no-self-assign: 2 + no-self-compare: 2 + no-sequences: 2 + no-throw-literal: 2 + no-useless-call: 2 + no-useless-concat: 2 + no-useless-escape: 2 + no-void: 2 + no-unmodified-loop-condition: 2 + yoda: 2 + + # Strict Mode + # http://eslint.org/docs/rules/#strict-mode + strict: [2, "global"] + + # Variables + # http://eslint.org/docs/rules/#variables + no-delete-var: 2 + no-shadow-restricted-names: 2 + no-undef: 2 + no-unused-vars: [2, {"args": "none"}] + + # http://eslint.org/docs/rules/#nodejs-and-commonjs + no-mixed-requires: 2 + no-new-require: 2 + no-path-concat: 2 + + # Stylistic Issues + # http://eslint.org/docs/rules/#stylistic-issues + comma-spacing: 2 + eol-last: 2 + indent: [2, 4, {SwitchCase: 2}] + keyword-spacing: 2 + max-len: [2, 200, 2] + new-parens: 2 + no-mixed-spaces-and-tabs: 2 + no-multiple-empty-lines: [2, {max: 2}] + no-trailing-spaces: 2 + quotes: [2, "single", "avoid-escape"] + semi: 2 + space-before-blocks: [2, "always"] + space-before-function-paren: [2, "always"] + space-in-parens: [2, "never"] + space-infix-ops: 2 + space-unary-ops: 2 + +globals: + it: true + describe: true + before: true + after: true + beforeEach: true + afterEach: true diff --git a/nodejs/node_modules/redis/.github/ISSUE_TEMPLATE.md b/nodejs/node_modules/redis/.github/ISSUE_TEMPLATE.md new file mode 100755 index 0000000..42f2d3e --- /dev/null +++ b/nodejs/node_modules/redis/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,15 @@ +_Thanks for wanting to report an issue you've found in node_redis. Please delete +this text and fill in the template below. Please note that the issue tracker is only +for bug reports or feature requests. If you have a question, please ask that on [gitter]. +If unsure about something, just do as best as you're able._ + +_Note that it will be much easier to fix the issue if a test case that reproduces +the problem is provided. It is of course not always possible to reduce your code +to a small test case, but it's highly appreciated to have as much data as possible. +Thank you!_ + +* **Version**: What node_redis and what redis version is the issue happening on? +* **Platform**: What platform / version? (For example Node.js 0.10 or Node.js 5.7.0 on Windows 7 / Ubuntu 15.10 / Azure) +* **Description**: Description of your issue, stack traces from errors and code that reproduces the issue + +[gitter]: https://gitter.im/NodeRedis/node_redis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge \ No newline at end of file diff --git a/nodejs/node_modules/redis/.github/PULL_REQUEST_TEMPLATE.md b/nodejs/node_modules/redis/.github/PULL_REQUEST_TEMPLATE.md new file mode 100755 index 0000000..9706621 --- /dev/null +++ b/nodejs/node_modules/redis/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,14 @@ +### Pull Request check-list + +_Please make sure to review and check all of these items:_ + +- [ ] Does `npm test` pass with this change (including linting)? +- [ ] Is the new or changed code fully tested? +- [ ] Is a documentation update included (if this change modifies existing APIs, or introduces new ones)? + +_NOTE: these things are not required to open a PR and can be done +afterwards / while the PR is open._ + +### Description of change + +_Please provide a description of the change here._ \ No newline at end of file diff --git a/nodejs/node_modules/redis/.npmignore b/nodejs/node_modules/redis/.npmignore new file mode 100755 index 0000000..b0238e0 --- /dev/null +++ b/nodejs/node_modules/redis/.npmignore @@ -0,0 +1,10 @@ +examples/ +benchmarks/ +test/ +.nyc_output/ +coverage/ +.tern-port +*.log +*.rdb +*.out +*.yml diff --git a/nodejs/node_modules/redis/LICENSE b/nodejs/node_modules/redis/LICENSE new file mode 100755 index 0000000..710407f --- /dev/null +++ b/nodejs/node_modules/redis/LICENSE @@ -0,0 +1,24 @@ +LICENSE - "MIT License" + +Copyright (c) 2016 by NodeRedis + +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. \ No newline at end of file diff --git a/nodejs/node_modules/redis/README.md b/nodejs/node_modules/redis/README.md new file mode 100755 index 0000000..205503b --- /dev/null +++ b/nodejs/node_modules/redis/README.md @@ -0,0 +1,965 @@ +redis - a node.js redis client +=========================== + +[![Build Status](https://travis-ci.org/NodeRedis/node_redis.svg?branch=master)](https://travis-ci.org/NodeRedis/node_redis) +[![Coverage Status](https://coveralls.io/repos/NodeRedis/node_redis/badge.svg?branch=)](https://coveralls.io/r/NodeRedis/node_redis?branch=) +[![Windows Tests](https://img.shields.io/appveyor/ci/BridgeAR/node-redis/master.svg?label=Windows%20Tests)](https://ci.appveyor.com/project/BridgeAR/node-redis/branch/master) +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/NodeRedis/node_redis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) + +This is a complete and feature rich Redis client for node.js. __It supports all +Redis commands__ and focuses on high performance. + +Install with: + + npm install redis + +## Usage Example + +```js +var redis = require("redis"), + client = redis.createClient(); + +// if you'd like to select database 3, instead of 0 (default), call +// client.select(3, function() { /* ... */ }); + +client.on("error", function (err) { + console.log("Error " + err); +}); + +client.set("string key", "string val", redis.print); +client.hset("hash key", "hashtest 1", "some value", redis.print); +client.hset(["hash key", "hashtest 2", "some other value"], redis.print); +client.hkeys("hash key", function (err, replies) { + console.log(replies.length + " replies:"); + replies.forEach(function (reply, i) { + console.log(" " + i + ": " + reply); + }); + client.quit(); +}); +``` + +This will display: + + mjr:~/work/node_redis (master)$ node example.js + Reply: OK + Reply: 0 + Reply: 0 + 2 replies: + 0: hashtest 1 + 1: hashtest 2 + mjr:~/work/node_redis (master)$ + +Note that the API is entirely asynchronous. To get data back from the server, +you'll need to use a callback. From v.2.6 on the API supports camelCase and +snake_case and all options / variables / events etc. can be used either way. It +is recommended to use camelCase as this is the default for the Node.js +landscape. + +### Promises + +You can also use node_redis with promises by promisifying node_redis with +[bluebird](https://github.com/petkaantonov/bluebird) as in: + +```js +var redis = require('redis'); +bluebird.promisifyAll(redis.RedisClient.prototype); +bluebird.promisifyAll(redis.Multi.prototype); +``` + +It'll add a *Async* to all node_redis functions (e.g. return client.getAsync().then()) + +```js +// We expect a value 'foo': 'bar' to be present +// So instead of writing client.get('foo', cb); you have to write: +return client.getAsync('foo').then(function(res) { + console.log(res); // => 'bar' +}); + +// Using multi with promises looks like: + +return client.multi().get('foo').execAsync().then(function(res) { + console.log(res); // => 'bar' +}); +``` + +### Sending Commands + +Each Redis command is exposed as a function on the `client` object. +All functions take either an `args` Array plus optional `callback` Function or +a variable number of individual arguments followed by an optional callback. +Examples: + +```js +client.hmset(["key", "test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {}); +// Works the same as +client.hmset("key", ["test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {}); +// Or +client.hmset("key", "test keys 1", "test val 1", "test keys 2", "test val 2", function (err, res) {}); +``` + +Note that in either form the `callback` is optional: + +```js +client.set("some key", "some val"); +client.set(["some other key", "some val"]); +``` + +If the key is missing, reply will be null. Only if the [Redis Command +Reference](http://redis.io/commands) states something else it will not be null. + +```js +client.get("missingkey", function(err, reply) { + // reply is null when the key is missing + console.log(reply); +}); +``` + +For a list of Redis commands, see [Redis Command Reference](http://redis.io/commands) + +Minimal parsing is done on the replies. Commands that return a integer return +JavaScript Numbers, arrays return JavaScript Array. `HGETALL` returns an Object +keyed by the hash keys. All strings will either be returned as string or as +buffer depending on your setting. Please be aware that sending null, undefined +and Boolean values will result in the value coerced to a string! + +# Redis Commands + +This library is a 1 to 1 mapping to [Redis commands](https://redis.io/commands). +It is not a cache library so please refer to Redis commands page for full usage +details. + +Example setting key to auto expire using [SET command](https://redis.io/commands/set) + +```js +// this key will expire after 10 seconds +client.set('key', 'value!', 'EX', 10); +``` + +# API + +## Connection and other Events + +`client` will emit some events about the state of the connection to the Redis server. + +### "ready" + +`client` will emit `ready` once a connection is established. Commands issued +before the `ready` event are queued, then replayed just before this event is +emitted. + +### "connect" + +`client` will emit `connect` as soon as the stream is connected to the server. + +### "reconnecting" + +`client` will emit `reconnecting` when trying to reconnect to the Redis server +after losing the connection. Listeners are passed an object containing `delay` +(in ms) and `attempt` (the attempt #) attributes. + +### "error" + +`client` will emit `error` when encountering an error connecting to the Redis +server or when any other in node_redis occurs. If you use a command without +callback and encounter a ReplyError it is going to be emitted to the error +listener. + +So please attach the error listener to node_redis. + +### "end" + +`client` will emit `end` when an established Redis server connection has closed. + +### "drain" (deprecated) + +`client` will emit `drain` when the TCP connection to the Redis server has been +buffering, but is now writable. This event can be used to stream commands in to +Redis and adapt to backpressure. + +If the stream is buffering `client.should_buffer` is set to true. Otherwise the +variable is always set to false. That way you can decide when to reduce your +send rate and resume sending commands when you get `drain`. + +You can also check the return value of each command as it will also return the +backpressure indicator (deprecated). If false is returned the stream had to +buffer. + +### "warning" + +`client` will emit `warning` when password was set but none is needed and if a +deprecated option / function / similar is used. + +### "idle" (deprecated) + +`client` will emit `idle` when there are no outstanding commands that are +awaiting a response. + +## redis.createClient() +If you have `redis-server` running on the same machine as node, then the +defaults for port and host are probably fine and you don't need to supply any +arguments. `createClient()` returns a `RedisClient` object. Otherwise, +`createClient()` accepts these arguments: + +* `redis.createClient([options])` +* `redis.createClient(unix_socket[, options])` +* `redis.createClient(redis_url[, options])` +* `redis.createClient(port[, host][, options])` + +__Tip:__ If the Redis server runs on the same machine as the client consider +using unix sockets if possible to increase throughput. + +#### `options` object properties +| Property | Default | Description | +|-----------|-----------|-------------| +| host | 127.0.0.1 | IP address of the Redis server | +| port | 6379 | Port of the Redis server | +| path | null | The UNIX socket string of the Redis server | +| url | null | The URL of the Redis server. Format: `[redis:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]` (More info avaliable at [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)). | +| parser | javascript | __Deprecated__ Use either the built-in JS parser [`javascript`]() or the native [`hiredis`]() parser. __Note__ `node_redis` < 2.6 uses hiredis as default if installed. This changed in v.2.6.0. | +| string_numbers | null | Set to `true`, `node_redis` will return Redis number values as Strings instead of javascript Numbers. Useful if you need to handle big numbers (above `Number.MAX_SAFE_INTEGER === 2^53`). Hiredis is incapable of this behavior, so setting this option to `true` will result in the built-in javascript parser being used no matter the value of the `parser` option. | +| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. | +| detect_buffers | false | If set to `true`, then replies will be sent to callbacks as Buffers. This option lets you switch between Buffers and Strings on a per-command basis, whereas `return_buffers` applies to every command on a client. __Note__: This doesn't work properly with the pubsub mode. A subscriber has to either always return Strings or Buffers. | +| socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. | +| no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, `node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. | +| enable_offline_queue | true | By default, if there is no active connection to the Redis server, commands are added to a queue and are executed once the connection has been established. Setting `enable_offline_queue` to `false` will disable this feature and the callback will be executed immediately with an error, or an error will be emitted if no callback is specified. | +| retry_max_delay | null | __Deprecated__ _Please use `retry_strategy` instead._ By default, every time the client tries to connect and fails, the reconnection delay almost doubles. This delay normally grows infinitely, but setting `retry_max_delay` limits it to the maximum value provided in milliseconds. | +| connect_timeout | 3600000 | __Deprecated__ _Please use `retry_strategy` instead._ Setting `connect_timeout` limits the total time for the client to connect and reconnect. The value is provided in milliseconds and is counted from the moment a new client is created or from the time the connection is lost. The last retry is going to happen exactly at the timeout time. Default is to try connecting until the default system socket timeout has been exceeded and to try reconnecting until 1h has elapsed. | +| max_attempts | 0 | __Deprecated__ _Please use `retry_strategy` instead._ By default, a client will try reconnecting until connected. Setting `max_attempts` limits total amount of connection attempts. Setting this to 1 will prevent any reconnect attempt. | +| retry_unfulfilled_commands | false | If set to `true`, all commands that were unfulfilled while the connection is lost will be retried after the connection has been reestablished. Use this with caution if you use state altering commands (e.g. `incr`). This is especially useful if you use blocking commands. | +| password | null | If set, client will run Redis auth command on connect. Alias `auth_pass` __Note__ `node_redis` < 2.5 must use `auth_pass` | +| db | null | If set, client will run Redis `select` command on connect. | +| family | IPv4 | You can force using IPv6 if you set the family to 'IPv6'. See Node.js [net](https://nodejs.org/api/net.html) or [dns](https://nodejs.org/api/dns.html) modules on how to use the family type. | +| disable_resubscribing | false | If set to `true`, a client won't resubscribe after disconnecting. | +| rename_commands | null | Passing an object with renamed commands to use instead of the original functions. For example, if you renamed the command KEYS to "DO-NOT-USE" then the rename_commands object would be: `{ KEYS : "DO-NOT-USE" }` . See the [Redis security topics](http://redis.io/topics/security) for more info. | +| tls | null | An object containing options to pass to [tls.connect](http://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback) to set up a TLS connection to Redis (if, for example, it is set up to be accessible via a tunnel). | +| prefix | null | A string used to prefix all used keys (e.g. `namespace:test`). Please be aware that the `keys` command will not be prefixed. The `keys` command has a "pattern" as argument and no key and it would be impossible to determine the existing keys in Redis if this would be prefixed. | +| retry_strategy | function | A function that receives an options object as parameter including the retry `attempt`, the `total_retry_time` indicating how much time passed since the last time connected, the `error` why the connection was lost and the number of `times_connected` in total. If you return a number from this function, the retry will happen exactly after that time in milliseconds. If you return a non-number, no further retry will happen and all offline commands are flushed with errors. Return an error to return that specific error to all offline commands. Example below. | + +```js +var redis = require("redis"); +var client = redis.createClient({detect_buffers: true}); + +client.set("foo_rand000000000000", "OK"); + +// This will return a JavaScript String +client.get("foo_rand000000000000", function (err, reply) { + console.log(reply.toString()); // Will print `OK` +}); + +// This will return a Buffer since original key is specified as a Buffer +client.get(new Buffer("foo_rand000000000000"), function (err, reply) { + console.log(reply.toString()); // Will print `` +}); +client.quit(); +``` + +retry_strategy example + +```js +var client = redis.createClient({ + retry_strategy: function (options) { + if (options.error && options.error.code === 'ECONNREFUSED') { + // End reconnecting on a specific error and flush all commands with + // a individual error + return new Error('The server refused the connection'); + } + if (options.total_retry_time > 1000 * 60 * 60) { + // End reconnecting after a specific timeout and flush all commands + // with a individual error + return new Error('Retry time exhausted'); + } + if (options.attempt > 10) { + // End reconnecting with built in error + return undefined; + } + // reconnect after + return Math.min(options.attempt * 100, 3000); + } +}); +``` + +## client.auth(password[, callback]) + +When connecting to a Redis server that requires authentication, the `AUTH` +command must be sent as the first command after connecting. This can be tricky +to coordinate with reconnections, the ready check, etc. To make this easier, +`client.auth()` stashes `password` and will send it after each connection, +including reconnections. `callback` is invoked only once, after the response to +the very first `AUTH` command sent. +NOTE: Your call to `client.auth()` should not be inside the ready handler. If +you are doing this wrong, `client` will emit an error that looks +something like this `Error: Ready check failed: ERR operation not permitted`. + +## backpressure + +### stream + +The client exposed the used [stream](https://nodejs.org/api/stream.html) in +`client.stream` and if the stream or client had to +[buffer](https://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback) +the command in `client.should_buffer`. In combination this can be used to +implement backpressure by checking the buffer state before sending a command and +listening to the stream +[drain](https://nodejs.org/api/stream.html#stream_event_drain) event. + +## client.quit() + +This sends the quit command to the redis server and ends cleanly right after all +running commands were properly handled. If this is called while reconnecting +(and therefore no connection to the redis server exists) it is going to end the +connection right away instead of resulting in further reconnections! All offline +commands are going to be flushed with an error in that case. + +## client.end(flush) + +Forcibly close the connection to the Redis server. Note that this does not wait +until all replies have been parsed. If you want to exit cleanly, call +`client.quit()` as mentioned above. + +You should set flush to true, if you are not absolutely sure you do not care +about any other commands. If you set flush to false all still running commands +will silently fail. + +This example closes the connection to the Redis server before the replies have +been read. You probably don't want to do this: + +```js +var redis = require("redis"), + client = redis.createClient(); + +client.set("foo_rand000000000000", "some fantastic value", function (err, reply) { + // This will either result in an error (flush parameter is set to true) + // or will silently fail and this callback will not be called at all (flush set to false) + console.log(err); +}); +client.end(true); // No further commands will be processed +client.get("foo_rand000000000000", function (err, reply) { + console.log(err); // => 'The connection has already been closed.' +}); +``` + +`client.end()` without the flush parameter set to true should NOT be used in production! + +## Error handling (>= v.2.6) + +Currently the following error subclasses exist: + +* `RedisError`: _All errors_ returned by the client +* `ReplyError` subclass of `RedisError`: All errors returned by __Redis__ itself +* `AbortError` subclass of `RedisError`: All commands that could not finish due + to what ever reason +* `ParserError` subclass of `RedisError`: Returned in case of a parser error + (this should not happen) +* `AggregateError` subclass of `AbortError`: Emitted in case multiple unresolved + commands without callback got rejected in debug_mode instead of lots of + `AbortError`s. + +All error classes are exported by the module. + +Example: +```js +var redis = require('./'); +var assert = require('assert'); +var client = redis.createClient(); + +client.on('error', function (err) { + assert(err instanceof Error); + assert(err instanceof redis.AbortError); + assert(err instanceof redis.AggregateError); + // The set and get get aggregated in here + assert.strictEqual(err.errors.length, 2); + assert.strictEqual(err.code, 'NR_CLOSED'); +}); +client.set('foo', 123, 'bar', function (err, res) { // Too many arguments + assert(err instanceof redis.ReplyError); // => true + assert.strictEqual(err.command, 'SET'); + assert.deepStrictEqual(err.args, ['foo', 123, 'bar']); + + redis.debug_mode = true; + client.set('foo', 'bar'); + client.get('foo'); + process.nextTick(function () { + // Force closing the connection while the command did not yet return + client.end(true); + redis.debug_mode = false; + }); +}); + +``` + +Every `ReplyError` contains the `command` name in all-caps and the arguments (`args`). + +If node_redis emits a library error because of another error, the triggering +error is added to the returned error as `origin` attribute. + +___Error codes___ + +node_redis returns a `NR_CLOSED` error code if the clients connection dropped. +If a command unresolved command got rejected a `UNCERTAIN_STATE` code is +returned. A `CONNECTION_BROKEN` error code is used in case node_redis gives up +to reconnect. + +## client.unref() + +Call `unref()` on the underlying socket connection to the Redis server, allowing +the program to exit once no more commands are pending. + +This is an **experimental** feature, and only supports a subset of the Redis +protocol. Any commands where client state is saved on the Redis server, e.g. +`*SUBSCRIBE` or the blocking `BL*` commands will *NOT* work with `.unref()`. + +```js +var redis = require("redis") +var client = redis.createClient() + +/* + Calling unref() will allow this program to exit immediately after the get + command finishes. Otherwise the client would hang as long as the + client-server connection is alive. +*/ +client.unref() +client.get("foo", function (err, value){ + if (err) throw(err) + console.log(value) +}) +``` + +## Friendlier hash commands + +Most Redis commands take a single String or an Array of Strings as arguments, +and replies are sent back as a single String or an Array of Strings. When +dealing with hash values, there are a couple of useful exceptions to this. + +### client.hgetall(hash, callback) + +The reply from an HGETALL command will be converted into a JavaScript Object by +`node_redis`. That way you can interact with the responses using JavaScript +syntax. + +Example: + +```js +client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234"); +client.hgetall("hosts", function (err, obj) { + console.dir(obj); +}); +``` + +Output: + +```js +{ mjr: '1', another: '23', home: '1234' } +``` + +### client.hmset(hash, obj[, callback]) + +Multiple values in a hash can be set by supplying an object: + +```js +client.HMSET(key2, { + "0123456789": "abcdefghij", // NOTE: key and value will be coerced to strings + "some manner of key": "a type of value" +}); +``` + +The properties and values of this Object will be set as keys and values in the +Redis hash. + +### client.hmset(hash, key1, val1, ... keyn, valn, [callback]) + +Multiple values may also be set by supplying a list: + +```js +client.HMSET(key1, "0123456789", "abcdefghij", "some manner of key", "a type of value"); +``` + +## Publish / Subscribe + +Example of the publish / subscribe API. This program opens two +client connections, subscribes to a channel on one of them, and publishes to that +channel on the other: + +```js +var redis = require("redis"); +var sub = redis.createClient(), pub = redis.createClient(); +var msg_count = 0; + +sub.on("subscribe", function (channel, count) { + pub.publish("a nice channel", "I am sending a message."); + pub.publish("a nice channel", "I am sending a second message."); + pub.publish("a nice channel", "I am sending my last message."); +}); + +sub.on("message", function (channel, message) { + console.log("sub channel " + channel + ": " + message); + msg_count += 1; + if (msg_count === 3) { + sub.unsubscribe(); + sub.quit(); + pub.quit(); + } +}); + +sub.subscribe("a nice channel"); +``` + +When a client issues a `SUBSCRIBE` or `PSUBSCRIBE`, that connection is put into +a "subscriber" mode. At that point, only commands that modify the subscription +set are valid and quit (and depending on the redis version ping as well). When +the subscription set is empty, the connection is put back into regular mode. + +If you need to send regular commands to Redis while in subscriber mode, just +open another connection with a new client (hint: use `client.duplicate()`). + +## Subscriber Events + +If a client has subscriptions active, it may emit these events: + +### "message" (channel, message) + +Client will emit `message` for every message received that matches an active subscription. +Listeners are passed the channel name as `channel` and the message as `message`. + +### "pmessage" (pattern, channel, message) + +Client will emit `pmessage` for every message received that matches an active +subscription pattern. Listeners are passed the original pattern used with +`PSUBSCRIBE` as `pattern`, the sending channel name as `channel`, and the +message as `message`. + +### "message_buffer" (channel, message) + +This is the same as the `message` event with the exception, that it is always +going to emit a buffer. If you listen to the `message` event at the same time as +the `message_buffer`, it is always going to emit a string. + +### "pmessage_buffer" (pattern, channel, message) + +This is the same as the `pmessage` event with the exception, that it is always +going to emit a buffer. If you listen to the `pmessage` event at the same time +as the `pmessage_buffer`, it is always going to emit a string. + +### "subscribe" (channel, count) + +Client will emit `subscribe` in response to a `SUBSCRIBE` command. Listeners are +passed the channel name as `channel` and the new count of subscriptions for this +client as `count`. + +### "psubscribe" (pattern, count) + +Client will emit `psubscribe` in response to a `PSUBSCRIBE` command. Listeners +are passed the original pattern as `pattern`, and the new count of subscriptions +for this client as `count`. + +### "unsubscribe" (channel, count) + +Client will emit `unsubscribe` in response to a `UNSUBSCRIBE` command. Listeners +are passed the channel name as `channel` and the new count of subscriptions for +this client as `count`. When `count` is 0, this client has left subscriber mode +and no more subscriber events will be emitted. + +### "punsubscribe" (pattern, count) + +Client will emit `punsubscribe` in response to a `PUNSUBSCRIBE` command. +Listeners are passed the channel name as `channel` and the new count of +subscriptions for this client as `count`. When `count` is 0, this client has +left subscriber mode and no more subscriber events will be emitted. + +## client.multi([commands]) + +`MULTI` commands are queued up until an `EXEC` is issued, and then all commands +are run atomically by Redis. The interface in `node_redis` is to return an +individual `Multi` object by calling `client.multi()`. If any command fails to +queue, all commands are rolled back and none is going to be executed (For +further information look at +[transactions](http://redis.io/topics/transactions)). + +```js +var redis = require("./index"), + client = redis.createClient(), set_size = 20; + +client.sadd("bigset", "a member"); +client.sadd("bigset", "another member"); + +while (set_size > 0) { + client.sadd("bigset", "member " + set_size); + set_size -= 1; +} + +// multi chain with an individual callback +client.multi() + .scard("bigset") + .smembers("bigset") + .keys("*", function (err, replies) { + // NOTE: code in this callback is NOT atomic + // this only happens after the the .exec call finishes. + client.mget(replies, redis.print); + }) + .dbsize() + .exec(function (err, replies) { + console.log("MULTI got " + replies.length + " replies"); + replies.forEach(function (reply, index) { + console.log("Reply " + index + ": " + reply.toString()); + }); + }); +``` + +### Multi.exec([callback]) + +`client.multi()` is a constructor that returns a `Multi` object. `Multi` objects +share all of the same command methods as `client` objects do. Commands are +queued up inside the `Multi` object until `Multi.exec()` is invoked. + +If your code contains an syntax error an EXECABORT error is going to be thrown +and all commands are going to be aborted. That error contains a `.errors` +property that contains the concrete errors. +If all commands were queued successfully and an error is thrown by redis while +processing the commands that error is going to be returned in the result array! +No other command is going to be aborted though than the onces failing. + +You can either chain together `MULTI` commands as in the above example, or you +can queue individual commands while still sending regular client command as in +this example: + +```js +var redis = require("redis"), + client = redis.createClient(), multi; + +// start a separate multi command queue +multi = client.multi(); +multi.incr("incr thing", redis.print); +multi.incr("incr other thing", redis.print); + +// runs immediately +client.mset("incr thing", 100, "incr other thing", 1, redis.print); + +// drains multi queue and runs atomically +multi.exec(function (err, replies) { + console.log(replies); // 101, 2 +}); +``` + +In addition to adding commands to the `MULTI` queue individually, you can also +pass an array of commands and arguments to the constructor: + +```js +var redis = require("redis"), + client = redis.createClient(), multi; + +client.multi([ + ["mget", "multifoo", "multibar", redis.print], + ["incr", "multifoo"], + ["incr", "multibar"] +]).exec(function (err, replies) { + console.log(replies); +}); +``` + +### Multi.exec_atomic([callback]) + +Identical to Multi.exec but with the difference that executing a single command +will not use transactions. + +## client.batch([commands]) + +Identical to .multi without transactions. This is recommended if you want to +execute many commands at once but don't have to rely on transactions. + +`BATCH` commands are queued up until an `EXEC` is issued, and then all commands +are run atomically by Redis. The interface in `node_redis` is to return an +individual `Batch` object by calling `client.batch()`. The only difference +between .batch and .multi is that no transaction is going to be used. +Be aware that the errors are - just like in multi statements - in the result. +Otherwise both, errors and results could be returned at the same time. + +If you fire many commands at once this is going to boost the execution speed +significantly compared to firing the same commands in a loop without waiting for +the result! See the benchmarks for further comparison. Please remember that all +commands are kept in memory until they are fired. + +## Monitor mode + +Redis supports the `MONITOR` command, which lets you see all commands received +by the Redis server across all client connections, including from other client +libraries and other computers. + +A `monitor` event is going to be emitted for every command fired from any client +connected to the server including the monitoring client itself. The callback for +the `monitor` event takes a timestamp from the Redis server, an array of command +arguments and the raw monitoring string. + +Example: + +```js +var client = require("redis").createClient(); +client.monitor(function (err, res) { + console.log("Entering monitoring mode."); +}); +client.set('foo', 'bar'); + +client.on("monitor", function (time, args, raw_reply) { + console.log(time + ": " + args); // 1458910076.446514:['set', 'foo', 'bar'] +}); +``` + +# Extras + +Some other things you might like to know about. + +## client.server_info + +After the ready probe completes, the results from the INFO command are saved in +the `client.server_info` object. + +The `versions` key contains an array of the elements of the version string for +easy comparison. + + > client.server_info.redis_version + '2.3.0' + > client.server_info.versions + [ 2, 3, 0 ] + +## redis.print() + +A handy callback function for displaying return values when testing. Example: + +```js +var redis = require("redis"), + client = redis.createClient(); + +client.on("connect", function () { + client.set("foo_rand000000000000", "some fantastic value", redis.print); + client.get("foo_rand000000000000", redis.print); +}); +``` + +This will print: + + Reply: OK + Reply: some fantastic value + +Note that this program will not exit cleanly because the client is still connected. + +## Multi-word commands + +To execute redis multi-word commands like `SCRIPT LOAD` or `CLIENT LIST` pass +the second word as first parameter: + + client.script('load', 'return 1'); + client.multi().script('load', 'return 1').exec(...); + client.multi([['script', 'load', 'return 1']]).exec(...); + +## client.duplicate([options][, callback]) + +Duplicate all current options and return a new redisClient instance. All options +passed to the duplicate function are going to replace the original option. If +you pass a callback, duplicate is going to wait until the client is ready and +returns it in the callback. If an error occurs in the meanwhile, that is going +to return an error instead in the callback. + +One example of when to use duplicate() would be to accommodate the connection- +blocking redis commands BRPOP, BLPOP, and BRPOPLPUSH. If these commands +are used on the same redisClient instance as non-blocking commands, the +non-blocking ones may be queued up until after the blocking ones finish. + + var Redis=require('redis'); + var client = Redis.createClient(); + var clientBlocking = client.duplicate(); + + var get = function() { + console.log("get called"); + client.get("any_key",function() { console.log("get returned"); }); + setTimeout( get, 1000 ); + }; + var brpop = function() { + console.log("brpop called"); + clientBlocking.brpop("nonexistent", 5, function() { + console.log("brpop return"); + setTimeout( brpop, 1000 ); + }); + }; + get(); + brpop(); + +Another reason to use duplicate() is when multiple DBs on the same server are +accessed via the redis SELECT command. Each DB could use its own connection. + +## client.send_command(command_name[, [args][, callback]]) + +All Redis commands have been added to the `client` object. However, if new +commands are introduced before this library is updated or if you want to add +individual commands you can use `send_command()` to send arbitrary commands to +Redis. + +All commands are sent as multi-bulk commands. `args` can either be an Array of +arguments, or omitted / set to undefined. + +## client.add_command(command_name) + +Calling add_command will add a new command to the prototype. The exact command +name will be used when calling using this new command. Using arbitrary arguments +is possible as with any other command. + +## client.connected + +Boolean tracking the state of the connection to the Redis server. + +## client.command_queue_length + +The number of commands that have been sent to the Redis server but not yet +replied to. You can use this to enforce some kind of maximum queue depth for +commands while connected. + +## client.offline_queue_length + +The number of commands that have been queued up for a future connection. You can +use this to enforce some kind of maximum queue depth for pre-connection +commands. + +### Commands with Optional and Keyword arguments + +This applies to anything that uses an optional `[WITHSCORES]` or `[LIMIT offset +count]` in the [redis.io/commands](http://redis.io/commands) documentation. + +Example: + +```js +var args = [ 'myzset', 1, 'one', 2, 'two', 3, 'three', 99, 'ninety-nine' ]; +client.zadd(args, function (err, response) { + if (err) throw err; + console.log('added '+response+' items.'); + + // -Infinity and +Infinity also work + var args1 = [ 'myzset', '+inf', '-inf' ]; + client.zrevrangebyscore(args1, function (err, response) { + if (err) throw err; + console.log('example1', response); + // write your code here + }); + + var max = 3, min = 1, offset = 1, count = 2; + var args2 = [ 'myzset', max, min, 'WITHSCORES', 'LIMIT', offset, count ]; + client.zrevrangebyscore(args2, function (err, response) { + if (err) throw err; + console.log('example2', response); + // write your code here + }); +}); +``` + +## Performance + +Much effort has been spent to make `node_redis` as fast as possible for common +operations. + +``` +Lenovo T450s, i7-5600U and 12gb memory +clients: 1, NodeJS: 6.2.0, Redis: 3.2.0, parser: javascript, connected by: tcp + PING, 1/1 avg/max: 0.02/ 5.26 2501ms total, 46916 ops/sec + PING, batch 50/1 avg/max: 0.06/ 4.35 2501ms total, 755178 ops/sec + SET 4B str, 1/1 avg/max: 0.02/ 4.75 2501ms total, 40856 ops/sec + SET 4B str, batch 50/1 avg/max: 0.11/ 1.51 2501ms total, 432727 ops/sec + SET 4B buf, 1/1 avg/max: 0.05/ 2.76 2501ms total, 20659 ops/sec + SET 4B buf, batch 50/1 avg/max: 0.25/ 1.76 2501ms total, 194962 ops/sec + GET 4B str, 1/1 avg/max: 0.02/ 1.55 2501ms total, 45156 ops/sec + GET 4B str, batch 50/1 avg/max: 0.09/ 3.15 2501ms total, 524110 ops/sec + GET 4B buf, 1/1 avg/max: 0.02/ 3.07 2501ms total, 44563 ops/sec + GET 4B buf, batch 50/1 avg/max: 0.10/ 3.18 2501ms total, 473171 ops/sec + SET 4KiB str, 1/1 avg/max: 0.03/ 1.54 2501ms total, 32627 ops/sec + SET 4KiB str, batch 50/1 avg/max: 0.34/ 1.89 2501ms total, 146861 ops/sec + SET 4KiB buf, 1/1 avg/max: 0.05/ 2.85 2501ms total, 20688 ops/sec + SET 4KiB buf, batch 50/1 avg/max: 0.36/ 1.83 2501ms total, 138165 ops/sec + GET 4KiB str, 1/1 avg/max: 0.02/ 1.37 2501ms total, 39389 ops/sec + GET 4KiB str, batch 50/1 avg/max: 0.24/ 1.81 2501ms total, 208157 ops/sec + GET 4KiB buf, 1/1 avg/max: 0.02/ 2.63 2501ms total, 39918 ops/sec + GET 4KiB buf, batch 50/1 avg/max: 0.31/ 8.56 2501ms total, 161575 ops/sec + INCR, 1/1 avg/max: 0.02/ 4.69 2501ms total, 45685 ops/sec + INCR, batch 50/1 avg/max: 0.09/ 3.06 2501ms total, 539964 ops/sec + LPUSH, 1/1 avg/max: 0.02/ 3.04 2501ms total, 41253 ops/sec + LPUSH, batch 50/1 avg/max: 0.12/ 1.94 2501ms total, 425090 ops/sec + LRANGE 10, 1/1 avg/max: 0.02/ 2.28 2501ms total, 39850 ops/sec + LRANGE 10, batch 50/1 avg/max: 0.25/ 1.85 2501ms total, 194302 ops/sec + LRANGE 100, 1/1 avg/max: 0.05/ 2.93 2501ms total, 21026 ops/sec + LRANGE 100, batch 50/1 avg/max: 1.52/ 2.89 2501ms total, 32767 ops/sec + SET 4MiB str, 1/1 avg/max: 5.16/ 15.55 2502ms total, 193 ops/sec + SET 4MiB str, batch 20/1 avg/max: 89.73/ 99.96 2513ms total, 223 ops/sec + SET 4MiB buf, 1/1 avg/max: 2.23/ 8.35 2501ms total, 446 ops/sec + SET 4MiB buf, batch 20/1 avg/max: 41.47/ 50.91 2530ms total, 482 ops/sec + GET 4MiB str, 1/1 avg/max: 2.79/ 10.91 2502ms total, 358 ops/sec + GET 4MiB str, batch 20/1 avg/max: 101.61/118.11 2541ms total, 197 ops/sec + GET 4MiB buf, 1/1 avg/max: 2.32/ 14.93 2502ms total, 430 ops/sec + GET 4MiB buf, batch 20/1 avg/max: 65.01/ 84.72 2536ms total, 308 ops/sec + ``` + +## Debugging + +To get debug output run your `node_redis` application with `NODE_DEBUG=redis`. + +This is also going to result in good stack traces opposed to useless ones +otherwise for any async operation. +If you only want to have good stack traces but not the debug output run your +application in development mode instead (`NODE_ENV=development`). + +Good stack traces are only activated in development and debug mode as this +results in a significant performance penalty. + +___Comparison___: +Useless stack trace: +``` +ReplyError: ERR wrong number of arguments for 'set' command + at parseError (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:158:12) + at parseType (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:219:14) +``` +Good stack trace: +``` +ReplyError: ERR wrong number of arguments for 'set' command + at new Command (/home/ruben/repos/redis/lib/command.js:9:902) + at RedisClient.set (/home/ruben/repos/redis/lib/commands.js:9:3238) + at Context. (/home/ruben/repos/redis/test/good_stacks.spec.js:20:20) + at callFnAsync (/home/ruben/repos/redis/node_modules/mocha/lib/runnable.js:349:8) + at Test.Runnable.run (/home/ruben/repos/redis/node_modules/mocha/lib/runnable.js:301:7) + at Runner.runTest (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:422:10) + at /home/ruben/repos/redis/node_modules/mocha/lib/runner.js:528:12 + at next (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:342:14) + at /home/ruben/repos/redis/node_modules/mocha/lib/runner.js:352:7 + at next (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:284:14) + at Immediate._onImmediate (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:320:5) + at processImmediate [as _immediateCallback] (timers.js:383:17) +``` + +## How to Contribute +- Open a pull request or an issue about what you want to implement / change. We're glad for any help! + - Please be aware that we'll only accept fully tested code. + +## Contributors + +The original author of node_redis is [Matthew Ranney](https://github.com/mranney) + +The current lead maintainer is [Ruben Bridgewater](https://github.com/BridgeAR) + +Many [others](https://github.com/NodeRedis/node_redis/graphs/contributors) +contributed to `node_redis` too. Thanks to all of them! + +## License + +[MIT](LICENSE) + +### Consolidation: It's time for celebration + +Right now there are two great redis clients around and both have some advantages +above each other. We speak about ioredis and node_redis. So after talking to +each other about how we could improve in working together we (that is @luin and +@BridgeAR) decided to work towards a single library on the long run. But step by +step. + +First of all, we want to split small parts of our libraries into others so that +we're both able to use the same code. Those libraries are going to be maintained +under the NodeRedis organization. This is going to reduce the maintenance +overhead, allows others to use the very same code, if they need it and it's way +easyer for others to contribute to both libraries. + +We're very happy about this step towards working together as we both want to +give you the best redis experience possible. + +If you want to join our cause by help maintaining something, please don't +hesitate to contact either one of us. diff --git a/nodejs/node_modules/redis/changelog.md b/nodejs/node_modules/redis/changelog.md new file mode 100755 index 0000000..d650f9b --- /dev/null +++ b/nodejs/node_modules/redis/changelog.md @@ -0,0 +1,845 @@ +# Changelog + +## v.2.8.0 - 31 Jul, 2017 + +Features + +- Accept UPPER_CASE commands in send_command +- Add arbitrary commands to the prototype by using `Redis.addCommand(name)` + +Bugfixes + +- Fixed not always copying subscribe unsubscribe arguments +- Fixed emitting internal errors while reconnecting with auth +- Fixed crashing with invalid url option + +## v.2.7.1 - 14 Mar, 2017 + +Bugfixes + +- Fixed monitor mode not working in combination with IPv6 (2.6.0 regression) + +## v.2.7.0 - 11 Mar, 2017 + +Features + +- All returned errors are from now a subclass of `RedisError`. + +Bugfixes + +- Fixed rename_commands not accepting `null` as value +- Fixed `AbortError`s and `AggregateError`s not showing the error message in the stack trace + +## v.2.6.5 - 15 Jan, 2017 + +Bugfixes + +- Fixed parser not being reset in case the redis connection closed ASAP for overcoming of output buffer limits +- Fixed parser reset if (p)message_buffer listener is attached + +## v.2.6.4 - 12 Jan, 2017 + +Bugfixes + +- Fixed monitor mode not working in combination with IPv6, sockets or lua scripts (2.6.0 regression) + +## v.2.6.3 - 31 Oct, 2016 + +Bugfixes + +- Do not change the tls setting to camel_case +- Fix domain handling in combination with the offline queue (2.5.3 regression) + +## v.2.6.2 - 16 Jun, 2016 + +Bugfixes + +- Fixed individual callbacks of a transaction not being called (2.6.0 regression) + +## v.2.6.1 - 02 Jun, 2016 + +Bugfixes + +- Fixed invalid function name being exported + +## v.2.6.0 - 01 Jun, 2016 + +In addition to the pre-releases the following changes exist in v.2.6.0: + +Features + +- Updated [redis-parser](https://github.com/NodeRedis/node-redis-parser) dependency ([changelog](https://github.com/NodeRedis/node-redis-parser/releases/tag/v.2.0.0)) + - The JS parser is from now on the new default as it is a lot faster than the hiredis parser + - This is no BC as there is no changed behavior for the user at all but just a performance improvement. Explicitly requireing the Hiredis parser is still possible. +- Added name property to all Redis functions (Node.js >= 4.0) +- Improved stack traces in development and debug mode + +Bugfixes + +- Reverted support for `__proto__` (v.2.6.0-2) to prevent and breaking change + +Deprecations + +- The `parser` option is deprecated and should be removed. The built-in Javascript parser is a lot faster than the hiredis parser and has more features + +## v.2.6.0-2 - 29 Apr, 2016 + +Features + +- Added support for the new [CLIENT REPLY ON|OFF|SKIP](http://redis.io/commands/client-reply) command (Redis v.3.2) +- Added support for camelCase + - The Node.js landscape default is to use camelCase. node_redis is a bit out of the box here + but from now on it is possible to use both, just as you prefer! + - If there's any documented variable missing as camelCased, please open a issue for it +- Improve error handling significantly + - Only emit an error if the error has not already been handled in a callback + - Improved unspecific error messages e.g. "Connection gone from end / close event" + - Added `args` to command errors to improve identification of the error + - Added origin to errors if there's e.g. a connection error + - Added ReplyError class. All Redis errors are from now on going to be of that class + - Added AbortError class. A subclass of AbortError. All unresolved and by node_redis rejected commands are from now on of that class + - Added AggregateError class. If a unresolved and by node_redis rejected command has no callback and + this applies to more than a single command, the errors for the commands without callback are aggregated + to a single error that is emitted in debug_mode in that case. +- Added `message_buffer` / `pmessage_buffer` events. That event is always going to emit a buffer + - Listening to the `message` event at the same time is always going to return the same message as string +- Added callback option to the duplicate function +- Added support for `__proto__` and other reserved keywords as hgetall field +- Updated [redis-commands](https://github.com/NodeRedis/redis-commands) dependency ([changelog](https://github.com/NodeRedis/redis-commands/releases/tag/v.1.2.0)) + +Bugfixes + +- Fixed v.2.5.0 auth command regression (under special circumstances a reconnect would not authenticate properly) +- Fixed v.2.6.0-0 pub sub mode and quit command regressions: + - Entering pub sub mode not working if a earlier called and still running command returned an error + - Unsubscribe callback not called if unsubscribing from all channels and resubscribing right away + - Quit command resulting in an error in some cases +- Fixed special handled functions in batch and multi context not working the same as without (e.g. select and info) + - Be aware that not all commands work in combination with transactions but they all work with batch +- Fixed address always set to 127.0.0.1:6379 in case host / port is set in the `tls` options instead of the general options + +## v.2.6.0-1 - 01 Apr, 2016 + +A second pre-release with further fixes. This is likely going to be released as 2.6.0 stable without further changes. + +Features + +- Added type validations for client.send_command arguments + +Bugfixes + +- Fixed client.send_command not working properly with every command and every option +- Fixed pub sub mode unsubscribing from all channels in combination with the new `string_numbers` option crashing +- Fixed pub sub mode unsubscribing from all channels not respected while reconnecting +- Fixed pub sub mode events in combination with the `string_numbers` option emitting the number of channels not as number + +## v.2.6.0-0 - 27 Mar, 2016 + +This is mainly a very important bug fix release with some smaller features. + +Features + +- Monitor and pub sub mode now work together with the offline queue + - All commands that were send after a connection loss are now going to be send after reconnecting +- Activating monitor mode does now work together with arbitrary commands including pub sub mode +- Pub sub mode is completely rewritten and all known issues fixed +- Added `string_numbers` option to get back strings instead of numbers +- Quit command is from now on always going to end the connection properly + +Bugfixes + +- Fixed calling monitor command while other commands are still running +- Fixed monitor and pub sub mode not working together +- Fixed monitor mode not working in combination with the offline queue +- Fixed pub sub mode not working in combination with the offline queue +- Fixed pub sub mode resubscribing not working with non utf8 buffer channels +- Fixed pub sub mode crashing if calling unsubscribe / subscribe in various combinations +- Fixed pub sub mode emitting unsubscribe even if no channels were unsubscribed +- Fixed pub sub mode emitting a message without a message published +- Fixed quit command not ending the connection and resulting in further reconnection if called while reconnecting + +The quit command did not end connections earlier if the connection was down at that time and this could have +lead to strange situations, therefor this was fixed to end the connection right away in those cases. + +## v.2.5.3 - 21 Mar, 2016 + +Bugfixes + +- Revert throwing on invalid data types and print a warning instead + +## v.2.5.2 - 16 Mar, 2016 + +Bugfixes + +- Fixed breaking changes against Redis 2.4 introduced in 2.5.0 / 2.5.1 + +## v.2.5.1 - 15 Mar, 2016 + +Bugfixes + +- Fixed info command not working anymore with optional section argument + +## v.2.5.0 - 15 Mar, 2016 + +Same changelog as the pre-release + +## v.2.5.0-1 - 07 Mar, 2016 + +This is a big release with some substantial underlining changes. Therefor this is released as a pre-release and I encourage anyone who's able to, to test this out. + +It took way to long to release this one and the next release cycles will be shorter again. + +This release is also going to deprecate a couple things to prepare for a future v.3 (it'll still take a while to v.3). + +Features + +- The parsers moved into the [redis-parser](https://github.com/NodeRedis/node-redis-parser) module and will be maintained in there from now on + - Improve js parser speed significantly for big SUNION/SINTER/LRANGE/ZRANGE +- Improve redis-url parsing to also accept the database-number and options as query parameters as suggested in [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis) +- Added a `retry_unfulfilled_commands` option + - Setting this to 'true' results in retrying all commands that were not fulfilled on a connection loss after the reconnect. Use with caution +- Added a `db` option to select the database while connecting (this is [not recommended](https://groups.google.com/forum/#!topic/redis-db/vS5wX8X4Cjg)) +- Added a `password` option as alias for auth_pass +- The client.server_info is from now on updated while using the info command +- Gracefuly handle redis protocol errors from now on +- Added a `warning` emitter that receives node_redis warnings like auth not required and deprecation messages +- Added a `retry_strategy` option that replaces all reconnect options +- The reconnecting event from now on also receives: + - The error message why the reconnect happened (params.error) + - The amount of times the client was connected (params.times_connected) + - The total reconnecting time since the last time connected (params.total_retry_time) +- Always respect the command execution order no matter if the reply could be returned sync or not (former exceptions: [#937](https://github.com/NodeRedis/node_redis/issues/937#issuecomment-167525939)) +- redis.createClient is now checking input values stricter and detects more faulty input +- Started refactoring internals into individual modules +- Pipelining speed improvements + +Bugfixes + +- Fixed explicit undefined as a command callback in a multi context +- Fixed hmset failing to detect the first key as buffer or date if the key is of that type +- Fixed do not run toString on an array argument and throw a "invalid data" error instead + - This is not considered as breaking change, as this is likely a error in your code and if you want to have such a behavior you should handle this beforehand + - The same applies to Map / Set and individual Object types +- Fixed redis url not accepting the protocol being omitted or protocols other than the redis protocol for convenience +- Fixed parsing the db keyspace even if the first database does not begin with a zero +- Fixed handling of errors occurring while receiving pub sub messages +- Fixed huge string pipelines crashing NodeJS (Pipeline size above 256mb) +- Fixed rename_commands and prefix option not working together +- Fixed ready being emitted to early in case a slave is still syncing / master down + +Deprecations + +- Using any command with a argument being set to null or undefined is deprecated + - From v.3.0.0 on using a command with such an argument will return an error instead + - If you want to keep the old behavior please use a precheck in your code that converts the arguments to a string. + - Using SET or SETEX with a undefined or null value will from now on also result in converting the value to "null" / "undefined" to have a consistent behavior. This is not considered as breaking change, as it returned an error earlier. +- Using .end(flush) without the flush parameter is deprecated and the flush parameter should explicitly be used + - From v.3.0.0 on using .end without flush will result in an error + - Using .end without flush means that any command that did not yet return is going to silently fail. Therefor this is considered harmful and you should explicitly silence such errors if you are sure you want this +- Depending on the return value of a command to detect the backpressure is deprecated + - From version 3.0.0 on node_redis might not return true / false as a return value anymore. Please rely on client.should_buffer instead +- The `socket_nodelay` option is deprecated and will be removed in v.3.0.0 + - If you want to buffer commands you should use [.batch or .multi](./README.md) instead. This is necessary to reduce the amount of different options and this is very likely reducing your throughput if set to false. + - If you are sure you want to activate the NAGLE algorithm you can still activate it by using client.stream.setNoDelay(false) +- The `max_attempts` option is deprecated and will be removed in v.3.0.0. Please use the `retry_strategy` instead +- The `retry_max_delay` option is deprecated and will be removed in v.3.0.0. Please use the `retry_strategy` instead +- The drain event is deprecated and will be removed in v.3.0.0. Please listen to the stream drain event instead +- The idle event is deprecated and will likely be removed in v.3.0.0. If you rely on this feature please open a new ticket in node_redis with your use case +- Redis < v. 2.6 is not officially supported anymore and might not work in all cases. Please update to a newer redis version as it is not possible to test for these old versions +- Removed non documented command syntax (adding the callback to an arguments array instead of passing it as individual argument) + +## v.2.4.2 - 27 Nov, 2015 + +Bugfixes + +- Fixed not emitting ready after reconnect with disable_resubscribing ([@maxgalbu](https://github.com/maxgalbu)) + +## v.2.4.1 - 25 Nov, 2015 + +Bugfixes + +- Fixed a js parser regression introduced in 2.4.0 ([@BridgeAR](https://github.com/BridgeAR)) + +## v.2.4.0 - 25 Nov, 2015 + +Features + +- Added `tls` option to initiate a connection to a redis server behind a TLS proxy. Thanks ([@paddybyers](https://github.com/paddybyers)) +- Added `prefix` option to auto key prefix any command with the provided prefix ([@luin](https://github.com/luin) & [@BridgeAR](https://github.com/BridgeAR)) +- Added `url` option to pass the connection url with the options object ([@BridgeAR](https://github.com/BridgeAR)) +- Added `client.duplicate([options])` to duplicate the current client and return a new one with the same options ([@BridgeAR](https://github.com/BridgeAR)) +- Improve performance by up to 20% on almost all use cases ([@BridgeAR](https://github.com/BridgeAR)) + +Bugfixes + +- Fixed js parser handling big values slow ([@BridgeAR](https://github.com/BridgeAR)) + - The speed is now on par with the hiredis parser. + +## v.2.3.1 - 18 Nov, 2015 + +Bugfixes + +- Fixed saving buffers with charsets other than utf-8 while using multi ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed js parser handling big values very slow ([@BridgeAR](https://github.com/BridgeAR)) + - The speed is up to ~500% faster than before but still up to ~50% slower than the hiredis parser. + +## v.2.3.0 - 30 Oct, 2015 + +Features + +- Improve speed further for: ([@BridgeAR](https://github.com/BridgeAR)) + - saving big strings (up to +300%) + - using .multi / .batch (up to +50% / on Node.js 0.10.x +300%) + - saving small buffers +- Increased coverage to 99% ([@BridgeAR](https://github.com/BridgeAR)) +- Refactored manual backpressure control ([@BridgeAR](https://github.com/BridgeAR)) + - Removed the high water mark and low water mark. Such a mechanism should be implemented by a user instead + - The `drain` event is from now on only emitted if the stream really had to buffer +- Reduced the default connect_timeout to be one hour instead of 24h ([@BridgeAR](https://github.com/BridgeAR)) +- Added .path to redis.createClient(options); ([@BridgeAR](https://github.com/BridgeAR)) +- Ignore info command, if not available on server ([@ivanB1975](https://github.com/ivanB1975)) + +Bugfixes + +- Fixed a js parser error that could result in a timeout ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed .multi / .batch used with Node.js 0.10.x not working properly after a reconnect ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed fired but not yet returned commands not being rejected after a connection loss ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed connect_timeout not respected if no connection has ever been established ([@gagle](https://github.com/gagle) & [@benjie](https://github.com/benjie)) +- Fixed return_buffers in pub sub mode ([@komachi](https://github.com/komachi)) + +## v.2.2.5 - 18 Oct, 2015 + +Bugfixes + +- Fixed undefined options passed to a new instance not accepted (possible with individual .createClient functions) ([@BridgeAR](https://github.com/BridgeAR)) + +## v.2.2.4 - 17 Oct, 2015 + +Bugfixes + +- Fixed unspecific error message for unresolvable commands ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed not allowed command error in pubsub mode not being returned in a provided callback ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed to many commands forbidden in pub sub mode ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed mutation of the arguments array passed to .multi / .batch constructor ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed mutation of the options object passed to createClient ([@BridgeAR](https://github.com/BridgeAR)) +- Fixed error callback in .multi not called if connection in broken mode ([@BridgeAR](https://github.com/BridgeAR)) + +## v.2.2.3 - 14 Oct, 2015 + +Bugfixes + +- Fixed multi not being executed on Node 0.10.x if node_redis not yet ready ([@BridgeAR](https://github.com/BridgeAR)) + +## v.2.2.2 - 14 Oct, 2015 + +Bugfixes + +- Fixed regular commands not being executed after a .multi until .exec was called ([@BridgeAR](https://github.com/BridgeAR)) + +## v.2.2.1 - 12 Oct, 2015 + +No code change + +## v.2.2.0 - 12 Oct, 2015 - The peregrino falcon + +The peregrino falcon is the fasted bird on earth and this is what this release is all about: Increased performance for heavy usage by up to **400%** [sic!] and increased overall performance for any command as well. Please check the benchmarks in the [README.md](README.md) for further details. + +Features + +- Added rename_commands options to handle renamed commands from the redis config ([@digmxl](https://github.com/digmxl) & [@BridgeAR](https://github.com/BridgeAR)) +- Added disable_resubscribing option to prevent a client from resubscribing after reconnecting ([@BridgeAR](https://github.com/BridgeAR)) +- Increased performance ([@BridgeAR](https://github.com/BridgeAR)) + - exchanging built in queue with [@petkaantonov](https://github.com/petkaantonov)'s [double-ended queue](https://github.com/petkaantonov/deque) + - prevent polymorphism + - optimize statements +- Added *.batch* command, similar to .multi but without transaction ([@BridgeAR](https://github.com/BridgeAR)) +- Improved pipelining to minimize the [RTT](http://redis.io/topics/pipelining) further ([@BridgeAR](https://github.com/BridgeAR)) + +Bugfixes + +- Fixed a javascript parser regression introduced in 2.0 that could result in timeouts on high load. ([@BridgeAR](https://github.com/BridgeAR)) + - I was not able to write a regression test for this, since the error seems to only occur under heavy load with special conditions. So please have a look for timeouts with the js parser, if you use it and report all issues and switch to the hiredis parser in the meanwhile. If you're able to come up with a reproducable test case, this would be even better :) +- Fixed should_buffer boolean for .exec, .select and .auth commands not being returned and fix a couple special conditions ([@BridgeAR](https://github.com/BridgeAR)) + +If you do not rely on transactions but want to reduce the RTT you can use .batch from now on. It'll behave just the same as .multi but it does not have any transaction and therefor won't roll back any failed commands.
        +Both .multi and .batch are from now on going to cache the commands and release them while calling .exec. + +Please consider using .batch instead of looping through a lot of commands one by one. This will significantly improve your performance. + +Here are some stats compared to ioredis 1.9.1 (Lenovo T450s i7-5600U): + + simple set + 82,496 op/s » ioredis + 112,617 op/s » node_redis + + simple get + 82,015 op/s » ioredis + 105,701 op/s » node_redis + + simple get with pipeline + 10,233 op/s » ioredis + 26,541 op/s » node_redis (using .batch) + + lrange 100 + 7,321 op/s » ioredis + 26,155 op/s » node_redis + + publish + 90,524 op/s » ioredis + 112,823 op/s » node_redis + + subscribe + 43,783 op/s » ioredis + 61,889 op/s » node_redis + +To conclude: we can proudly say that node_redis is very likely outperforming any other node redis client. + +Known issues + +- The pub sub system has some flaws and those will be addressed in the next minor release + +## v2.1.0 - Oct 02, 2015 + +Features: + +- Addded optional flush parameter to `.end`. If set to true, commands fired after using .end are going to be rejected instead of being ignored. (@crispy1989) +- Addded: host and port can now be provided in a single options object. E.g. redis.createClient({ host: 'localhost', port: 1337, max_attempts: 5 }); (@BridgeAR) +- Speedup common cases (@BridgeAR) + +Bugfixes: + +- Fix argument mutation while using the array notation with the multi constructor (@BridgeAR) +- Fix multi.hmset key not being type converted if used with an object and key not being a string (@BridgeAR) +- Fix parser errors not being catched properly (@BridgeAR) +- Fix a crash that could occur if a redis server does not return the info command as usual #541 (@BridgeAR) +- Explicitly passing undefined as a callback statement will work again. E.g. client.publish('channel', 'message', undefined); (@BridgeAR) + +## v2.0.1 - Sep 24, 2015 + +Bugfixes: + +- Fix argument mutation while using the array notation in combination with keys / callbacks ([#866](.)). (@BridgeAR) + +## v2.0.0 - Sep 21, 2015 + +This is the biggest release that node_redis had since it was released in 2010. A long list of outstanding bugs has been fixed, so we are very happy to present you redis 2.0 and we highly recommend updating as soon as possible. + +# What's new in 2.0 + +- Implemented a "connection is broken" mode if no connection could be established +- node_redis no longer throws under any circumstances, preventing it from terminating applications. +- Multi error handling is now working properly +- Consistent command behavior including multi +- Windows support +- Improved performance +- A lot of code cleanup +- Many bug fixes +- Better user support! + +## Features: + +- Added a "redis connection is broken" mode after reaching max connection attempts / exceeding connection timeout. (@BridgeAR) +- Added NODE_DEBUG=redis env to activate the debug_mode (@BridgeAR) +- Added a default connection timeout of 24h instead of never timing out as a default (@BridgeAR) +- Added: Network errors and other stream errors will from now on include the error code as `err.code` property (@BridgeAR) +- Added: Errors thrown by redis will now include the redis error code as `err.code` property. (@skeggse & @BridgeAR) +- Added: Errors thrown by node_redis will now include a `err.command` property for the command used (@BridgeAR) +- Added new commands and drop support for deprecated *substr* (@BridgeAR) +- Added new possibilities how to provide the command arguments (@BridgeAR) +- The entries in the keyspace of the server_info is now an object instead of a string. (@SinisterLight & @BridgeAR) +- Small speedup here and there (e.g. by not using .toLowerCase() anymore) (@BridgeAR) +- Full windows support (@bcoe) +- Increased coverage by 10% and add a lot of tests to make sure everything works as it should. We now reached 97% :-) (@BridgeAR) +- Remove dead code, clean up and refactor very old chunks (@BridgeAR) +- Don't flush the offline queue if reconnecting (@BridgeAR) +- Emit all errors insteaf of throwing sometimes and sometimes emitting them (@BridgeAR) +- *auth_pass* passwords are now checked to be a valid password (@jcppman & @BridgeAR) + +## Bug fixes: + +- Don't kill the app anymore by randomly throwing errors sync instead of emitting them (@BridgeAR) +- Don't catch user errors anymore occuring in callbacks (no try callback anymore & more fixes for the parser) (@BridgeAR) +- Early garbage collection of queued items (@dohse) +- Fix js parser returning errors as strings (@BridgeAR) +- Do not wrap errors into other errors (@BridgeAR) +- Authentication failures are now returned in the callback instead of being emitted (@BridgeAR) +- Fix a memory leak on reconnect (@rahar) +- Using `send_command` directly may now also be called without the args as stated in the [README.md](./README.md) (@BridgeAR) +- Fix the multi.exec error handling (@BridgeAR) +- Fix commands being inconsistent and behaving wrong (@BridgeAR) +- Channel names with spaces are now properly resubscribed after a reconnection (@pbihler) +- Do not try to reconnect after the connection timeout has been exceeded (@BridgeAR) +- Ensure the execution order is observed if using .eval (@BridgeAR) +- Fix commands not being rejected after calling .quit (@BridgeAR) +- Fix .auth calling the callback twice if already connected (@BridgeAR) +- Fix detect_buffers not working in pub sub mode and while monitoring (@BridgeAR) +- Fix channel names always being strings instead of buffers while return_buffers is true (@BridgeAR) +- Don't print any debug statements if not asked for (@BridgeAR) +- Fix a couple small other bugs + +## Breaking changes: + +1. redis.send_command commands have to be lower case from now on. This does only apply if you use `.send_command` directly instead of the convenient methods like `redis.command`. +2. Error messages have changed quite a bit. If you depend on a specific wording please check your application carfully. +3. Errors are from now on always either returned if a callback is present or emitted. They won't be thrown (neither sync, nor async). +4. The Multi error handling has changed a lot! + - All errors are from now on errors instead of strings (this only applied to the js parser). + - If an error occurs while queueing the commands an EXECABORT error will be returned including the failed commands as `.errors` property instead of an array with errors. + - If an error occurs while executing the commands and that command has a callback it'll return the error as first parameter (`err, undefined` instead of `null, undefined`). + - All the errors occuring while executing the commands will stay in the result value as error instance (if you used the js parser before they would have been strings). Be aware that the transaction won't be aborted if those error occurr! + - If `multi.exec` does not have a callback and an EXECABORT error occurrs, it'll emit that error instead. +5. If redis can't connect to your redis server it'll give up after a certain point of failures (either max connection attempts or connection timeout exceeded). If that is the case it'll emit an CONNECTION_BROKEN error. You'll have to initiate a new client to try again afterwards. +6. The offline queue is not flushed anymore on a reconnect. It'll stay until node_redis gives up trying to reach the server or until you close the connection. +7. Before this release node_redis catched user errors and threw them async back. This is not the case anymore! No user behavior of what so ever will be tracked or catched. +8. The keyspace of `redis.server_info` (db0...) is from now on an object instead of an string. + +NodeRedis also thanks @qdb, @tobek, @cvibhagool, @frewsxcv, @davidbanham, @serv, @vitaliylag, @chrishamant, @GamingCoder and all other contributors that I may have missed for their contributions! + +From now on we'll push new releases more frequently out and fix further long outstanding things and implement new features. + +
        + +## v1.0.0 - Aug 30, 2015 + +* Huge issue and pull-request cleanup. Thanks Blain! (@blainsmith) +* [#658](https://github.com/NodeRedis/node_redis/pull/658) Client now parses URL-format connection strings (e.g., redis://foo:pass@127.0.0.1:8080) (@kuwabarahiroshi) +* [#749](https://github.com/NodeRedis/node_redis/pull/749) Fix reconnection bug when client is in monitoring mode (@danielbprice) +* [#786](https://github.com/NodeRedis/node_redis/pull/786) Refactor createClient. Fixes #651 (@BridgeAR) +* [#793](https://github.com/NodeRedis/node_redis/pull/793) Refactor tests and improve test coverage (@erinspice, @bcoe) +* [#733](https://github.com/NodeRedis/node_redis/pull/733) Fixes detect_buffers functionality in the context of exec. Fixes #732, #263 (@raydog) +* [#785](https://github.com/NodeRedis/node_redis/pull/785) Tiny speedup by using 'use strict' (@BridgeAR) +* Fix extraneous error output due to pubsub tests (Mikael Kohlmyr) + +## v0.12.1 - Aug 10, 2014 +* Fix IPv6/IPv4 family selection in node 0.11+ (Various) + +## v0.12.0 - Aug 9, 2014 +* Fix unix socket support (Jack Tang) +* Improve createClient argument handling (Jack Tang) + +## v0.11.0 - Jul 10, 2014 + +* IPv6 Support. (Yann Stephan) +* Revert error emitting and go back to throwing errors. (Bryce Baril) +* Set socket_keepalive to prevent long-lived client timeouts. (mohit) +* Correctly reset retry timer. (ouotuo) +* Domains protection from bad user exit. (Jake Verbaten) +* Fix reconnection socket logic to prevent misqueued entries. (Iain Proctor) + +## v0.10.3 - May 22, 2014 + +* Update command list to match Redis 2.8.9 (Charles Feng) + +## v0.10.2 - May 18, 2014 + +* Better binary key handling for HGETALL. (Nick Apperson) +* Fix test not resetting `error` handler. (CrypticSwarm) +* Fix SELECT error semantics. (Bryan English) + +## v0.10.1 - February 17, 2014 + +* Skip plucking redis version from the INFO stream if INFO results weren't provided. (Robert Sköld) + +## v0.10.0 - December 21, 2013 + +* Instead of throwing errors asynchronously, emit errors on client. (Bryce Baril) + +## v0.9.2 - December 15, 2013 + +* Regenerate commands for new 2.8.x Redis commands. (Marek Ventur) +* Correctly time reconnect counts when using 'auth'. (William Hockey) + +## v0.9.1 - November 23, 2013 + +* Allow hmset to accept numeric keys. (Alex Stokes) +* Fix TypeError for multiple MULTI/EXEC errors. (Kwangsu Kim) + +## v0.9.0 - October 17, 2013 + +* Domains support. (Forrest L Norvell) + +## v0.8.6 - October 2, 2013 + +* If error is already an Error, don't wrap it in another Error. (Mathieu M-Gosselin) +* Fix retry delay logic (Ian Babrou) +* Return Errors instead of strings where Errors are expected (Ian Babrou) +* Add experimental `.unref()` method to RedisClient (Bryce Baril / Olivier Lalonde) +* Strengthen checking of reply to prevent conflating "message" or "pmessage" fields with pub_sub replies. (Bryce Baril) + +## v0.8.5 - September 26, 2013 + +* Add `auth_pass` option to connect and immediately authenticate (Henrik Peinar) + +## v0.8.4 - June 24, 2013 + +Many contributed features and fixes, including: +* Ignore password set if not needed. (jbergknoff) +* Improved compatibility with 0.10.X for tests and client.end() (Bryce Baril) +* Protect connection retries from application exceptions. (Amos Barreto) +* Better exception handling for Multi/Exec (Thanasis Polychronakis) +* Renamed pubsub mode to subscriber mode (Luke Plaster) +* Treat SREM like SADD when passed an array (Martin Ciparelli) +* Fix empty unsub/punsub TypeError (Jeff Barczewski) +* Only attempt to run a callback if it one was provided (jifeng) + +## v0.8.3 - April 09, 2013 + +Many contributed features and fixes, including: +* Fix some tests for Node.js version 0.9.x+ changes (Roman Ivanilov) +* Fix error when commands submitted after idle event handler (roamm) +* Bypass Redis for no-op SET/SETEX commands (jifeng) +* Fix HMGET + detect_buffers (Joffrey F) +* Fix CLIENT LOAD functionality (Jonas Dohse) +* Add percentage outputs to diff_multi_bench_output.js (Bryce Baril) +* Add retry_max_delay option (Tomasz Durka) +* Fix parser off-by-one errors with nested multi-bulk replies (Bryce Baril) +* Prevent parser from sinking application-side exceptions (Bryce Baril) +* Fix parser incorrect buffer skip when parsing multi-bulk errors (Bryce Baril) +* Reverted previous change with throwing on non-string values with HMSET (David Trejo) +* Fix command queue sync issue when using pubsub (Tom Leach) +* Fix compatibility with two-word Redis commands (Jonas Dohse) +* Add EVAL with array syntax (dmoena) +* Fix tests due to Redis reply order changes in 2.6.5+ (Bryce Baril) +* Added a test for the SLOWLOG command (Nitesh Sinha) +* Fix SMEMBERS order dependency in test broken by Redis changes (Garrett Johnson) +* Update commands for new Redis commands (David Trejo) +* Prevent exception from SELECT on subscriber reconnection (roamm) + + +## v0.8.2 - November 11, 2012 + +Another version bump because 0.8.1 didn't get applied properly for some mysterious reason. +Sorry about that. + +Changed name of "faster" parser to "javascript". + +## v0.8.1 - September 11, 2012 + +Important bug fix for null responses (Jerry Sievert) + +## v0.8.0 - September 10, 2012 + +Many contributed features and fixes, including: + +* Pure JavaScript reply parser that is usually faster than hiredis (Jerry Sievert) +* Remove hiredis as optionalDependency from package.json. It still works if you want it. +* Restore client state on reconnect, including select, subscribe, and monitor. (Ignacio Burgueño) +* Fix idle event (Trae Robrock) +* Many documentation improvements and bug fixes (David Trejo) + +## v0.7.2 - April 29, 2012 + +Many contributed fixes. Thank you, contributors. + +* [GH-190] - pub/sub mode fix (Brian Noguchi) +* [GH-165] - parser selection fix (TEHEK) +* numerous documentation and examples updates +* auth errors emit Errors instead of Strings (David Trejo) + +## v0.7.1 - November 15, 2011 + +Fix regression in reconnect logic. + +Very much need automated tests for reconnection and queue logic. + +## v0.7.0 - November 14, 2011 + +Many contributed fixes. Thanks everybody. + +* [GH-127] - properly re-initialize parser on reconnect +* [GH-136] - handle passing undefined as callback (Ian Babrou) +* [GH-139] - properly handle exceptions thrown in pub/sub event handlers (Felix Geisendörfer) +* [GH-141] - detect closing state on stream error (Felix Geisendörfer) +* [GH-142] - re-select database on reconnection (Jean-Hugues Pinson) +* [GH-146] - add sort example (Maksim Lin) + +Some more goodies: + +* Fix bugs with node 0.6 +* Performance improvements +* New version of `multi_bench.js` that tests more realistic scenarios +* [GH-140] - support optional callback for subscribe commands +* Properly flush and error out command queue when connection fails +* Initial work on reconnection thresholds + +## v0.6.7 - July 30, 2011 + +(accidentally skipped v0.6.6) + +Fix and test for [GH-123] + +Passing an Array as as the last argument should expand as users +expect. The old behavior was to coerce the arguments into Strings, +which did surprising things with Arrays. + +## v0.6.5 - July 6, 2011 + +Contributed changes: + +* Support SlowBuffers (Umair Siddique) +* Add Multi to exports (Louis-Philippe Perron) +* Fix for drain event calculation (Vladimir Dronnikov) + +Thanks! + +## v0.6.4 - June 30, 2011 + +Fix bug with optional callbacks for hmset. + +## v0.6.2 - June 30, 2011 + +Bugs fixed: + +* authentication retry while server is loading db (danmaz74) [GH-101] +* command arguments processing issue with arrays + +New features: + +* Auto update of new commands from redis.io (Dave Hoover) +* Performance improvements and backpressure controls. +* Commands now return the true/false value from the underlying socket write(s). +* Implement command_queue high water and low water for more better control of queueing. + +See `examples/backpressure_drain.js` for more information. + +## v0.6.1 - June 29, 2011 + +Add support and tests for Redis scripting through EXEC command. + +Bug fix for monitor mode. (forddg) + +Auto update of new commands from redis.io (Dave Hoover) + +## v0.6.0 - April 21, 2011 + +Lots of bugs fixed. + +* connection error did not properly trigger reconnection logic [GH-85] +* client.hmget(key, [val1, val2]) was not expanding properly [GH-66] +* client.quit() while in pub/sub mode would throw an error [GH-87] +* client.multi(['hmset', 'key', {foo: 'bar'}]) fails [GH-92] +* unsubscribe before subscribe would make things very confused [GH-88] +* Add BRPOPLPUSH [GH-79] + +## v0.5.11 - April 7, 2011 + +Added DISCARD + +I originally didn't think DISCARD would do anything here because of the clever MULTI interface, but somebody +pointed out to me that DISCARD can be used to flush the WATCH set. + +## v0.5.10 - April 6, 2011 + +Added HVALS + +## v0.5.9 - March 14, 2011 + +Fix bug with empty Array arguments - Andy Ray + +## v0.5.8 - March 14, 2011 + +Add `MONITOR` command and special monitor command reply parsing. + +## v0.5.7 - February 27, 2011 + +Add magical auth command. + +Authentication is now remembered by the client and will be automatically sent to the server +on every connection, including any reconnections. + +## v0.5.6 - February 22, 2011 + +Fix bug in ready check with `return_buffers` set to `true`. + +Thanks to Dean Mao and Austin Chau. + +## v0.5.5 - February 16, 2011 + +Add probe for server readiness. + +When a Redis server starts up, it might take a while to load the dataset into memory. +During this time, the server will accept connections, but will return errors for all non-INFO +commands. Now node_redis will send an INFO command whenever it connects to a server. +If the info command indicates that the server is not ready, the client will keep trying until +the server is ready. Once it is ready, the client will emit a "ready" event as well as the +"connect" event. The client will queue up all commands sent before the server is ready, just +like it did before. When the server is ready, all offline/non-ready commands will be replayed. +This should be backward compatible with previous versions. + +To disable this ready check behavior, set `options.no_ready_check` when creating the client. + +As a side effect of this change, the key/val params from the info command are available as +`client.server_options`. Further, the version string is decomposed into individual elements +in `client.server_options.versions`. + +## v0.5.4 - February 11, 2011 + +Fix excess memory consumption from Queue backing store. + +Thanks to Gustaf Sjöberg. + +## v0.5.3 - February 5, 2011 + +Fix multi/exec error reply callback logic. + +Thanks to Stella Laurenzo. + +## v0.5.2 - January 18, 2011 + +Fix bug where unhandled error replies confuse the parser. + +## v0.5.1 - January 18, 2011 + +Fix bug where subscribe commands would not handle redis-server startup error properly. + +## v0.5.0 - December 29, 2010 + +Some bug fixes: + +* An important bug fix in reconnection logic. Previously, reply callbacks would be invoked twice after + a reconnect. +* Changed error callback argument to be an actual Error object. + +New feature: + +* Add friendly syntax for HMSET using an object. + +## v0.4.1 - December 8, 2010 + +Remove warning about missing hiredis. You probably do want it though. + +## v0.4.0 - December 5, 2010 + +Support for multiple response parsers and hiredis C library from Pieter Noordhuis. +Return Strings instead of Buffers by default. +Empty nested mb reply bug fix. + +## v0.3.9 - November 30, 2010 + +Fix parser bug on failed EXECs. + +## v0.3.8 - November 10, 2010 + +Fix for null MULTI response when WATCH condition fails. + +## v0.3.7 - November 9, 2010 + +Add "drain" and "idle" events. + +## v0.3.6 - November 3, 2010 + +Add all known Redis commands from Redis master, even ones that are coming in 2.2 and beyond. + +Send a friendlier "error" event message on stream errors like connection refused / reset. + +## v0.3.5 - October 21, 2010 + +A few bug fixes. + +* Fixed bug with `nil` multi-bulk reply lengths that showed up with `BLPOP` timeouts. +* Only emit `end` once when connection goes away. +* Fixed bug in `test.js` where driver finished before all tests completed. + +## unversioned wasteland + +See the git history for what happened before. diff --git a/nodejs/node_modules/redis/index.js b/nodejs/node_modules/redis/index.js new file mode 100755 index 0000000..58fcf84 --- /dev/null +++ b/nodejs/node_modules/redis/index.js @@ -0,0 +1,1105 @@ +'use strict'; + +var net = require('net'); +var tls = require('tls'); +var util = require('util'); +var utils = require('./lib/utils'); +var Command = require('./lib/command'); +var Queue = require('double-ended-queue'); +var errorClasses = require('./lib/customErrors'); +var EventEmitter = require('events'); +var Parser = require('redis-parser'); +var commands = require('redis-commands'); +var debug = require('./lib/debug'); +var unifyOptions = require('./lib/createClient'); +var SUBSCRIBE_COMMANDS = { + subscribe: true, + unsubscribe: true, + psubscribe: true, + punsubscribe: true +}; + +// Newer Node.js versions > 0.10 return the EventEmitter right away and using .EventEmitter was deprecated +if (typeof EventEmitter !== 'function') { + EventEmitter = EventEmitter.EventEmitter; +} + +function noop () {} + +function handle_detect_buffers_reply (reply, command, buffer_args) { + if (buffer_args === false || this.message_buffers) { + // If detect_buffers option was specified, then the reply from the parser will be a buffer. + // If this command did not use Buffer arguments, then convert the reply to Strings here. + reply = utils.reply_to_strings(reply); + } + + if (command === 'hgetall') { + reply = utils.reply_to_object(reply); + } + return reply; +} + +exports.debug_mode = /\bredis\b/i.test(process.env.NODE_DEBUG); + +// Attention: The second parameter might be removed at will and is not officially supported. +// Do not rely on this +function RedisClient (options, stream) { + // Copy the options so they are not mutated + options = utils.clone(options); + EventEmitter.call(this); + var cnx_options = {}; + var self = this; + /* istanbul ignore next: travis does not work with stunnel atm. Therefore the tls tests are skipped on travis */ + for (var tls_option in options.tls) { + cnx_options[tls_option] = options.tls[tls_option]; + // Copy the tls options into the general options to make sure the address is set right + if (tls_option === 'port' || tls_option === 'host' || tls_option === 'path' || tls_option === 'family') { + options[tls_option] = options.tls[tls_option]; + } + } + if (stream) { + // The stream from the outside is used so no connection from this side is triggered but from the server this client should talk to + // Reconnect etc won't work with this. This requires monkey patching to work, so it is not officially supported + options.stream = stream; + this.address = '"Private stream"'; + } else if (options.path) { + cnx_options.path = options.path; + this.address = options.path; + } else { + cnx_options.port = +options.port || 6379; + cnx_options.host = options.host || '127.0.0.1'; + cnx_options.family = (!options.family && net.isIP(cnx_options.host)) || (options.family === 'IPv6' ? 6 : 4); + this.address = cnx_options.host + ':' + cnx_options.port; + } + // Warn on misusing deprecated functions + if (typeof options.retry_strategy === 'function') { + if ('max_attempts' in options) { + self.warn('WARNING: You activated the retry_strategy and max_attempts at the same time. This is not possible and max_attempts will be ignored.'); + // Do not print deprecation warnings twice + delete options.max_attempts; + } + if ('retry_max_delay' in options) { + self.warn('WARNING: You activated the retry_strategy and retry_max_delay at the same time. This is not possible and retry_max_delay will be ignored.'); + // Do not print deprecation warnings twice + delete options.retry_max_delay; + } + } + + this.connection_options = cnx_options; + this.connection_id = RedisClient.connection_id++; + this.connected = false; + this.ready = false; + if (options.socket_nodelay === undefined) { + options.socket_nodelay = true; + } else if (!options.socket_nodelay) { // Only warn users with this set to false + self.warn( + 'socket_nodelay is deprecated and will be removed in v.3.0.0.\n' + + 'Setting socket_nodelay to false likely results in a reduced throughput. Please use .batch for pipelining instead.\n' + + 'If you are sure you rely on the NAGLE-algorithm you can activate it by calling client.stream.setNoDelay(false) instead.' + ); + } + if (options.socket_keepalive === undefined) { + options.socket_keepalive = true; + } + for (var command in options.rename_commands) { + options.rename_commands[command.toLowerCase()] = options.rename_commands[command]; + } + options.return_buffers = !!options.return_buffers; + options.detect_buffers = !!options.detect_buffers; + // Override the detect_buffers setting if return_buffers is active and print a warning + if (options.return_buffers && options.detect_buffers) { + self.warn('WARNING: You activated return_buffers and detect_buffers at the same time. The return value is always going to be a buffer.'); + options.detect_buffers = false; + } + if (options.detect_buffers) { + // We only need to look at the arguments if we do not know what we have to return + this.handle_reply = handle_detect_buffers_reply; + } + this.should_buffer = false; + this.max_attempts = options.max_attempts | 0; + if ('max_attempts' in options) { + self.warn( + 'max_attempts is deprecated and will be removed in v.3.0.0.\n' + + 'To reduce the number of options and to improve the reconnection handling please use the new `retry_strategy` option instead.\n' + + 'This replaces the max_attempts and retry_max_delay option.' + ); + } + this.command_queue = new Queue(); // Holds sent commands to de-pipeline them + this.offline_queue = new Queue(); // Holds commands issued but not able to be sent + this.pipeline_queue = new Queue(); // Holds all pipelined commands + // ATTENTION: connect_timeout should change in v.3.0 so it does not count towards ending reconnection attempts after x seconds + // This should be done by the retry_strategy. Instead it should only be the timeout for connecting to redis + this.connect_timeout = +options.connect_timeout || 3600000; // 60 * 60 * 1000 ms + this.enable_offline_queue = options.enable_offline_queue === false ? false : true; + this.retry_max_delay = +options.retry_max_delay || null; + if ('retry_max_delay' in options) { + self.warn( + 'retry_max_delay is deprecated and will be removed in v.3.0.0.\n' + + 'To reduce the amount of options and the improve the reconnection handling please use the new `retry_strategy` option instead.\n' + + 'This replaces the max_attempts and retry_max_delay option.' + ); + } + this.initialize_retry_vars(); + this.pub_sub_mode = 0; + this.subscription_set = {}; + this.monitoring = false; + this.message_buffers = false; + this.closing = false; + this.server_info = {}; + this.auth_pass = options.auth_pass || options.password; + this.selected_db = options.db; // Save the selected db here, used when reconnecting + this.old_state = null; + this.fire_strings = true; // Determine if strings or buffers should be written to the stream + this.pipeline = false; + this.sub_commands_left = 0; + this.times_connected = 0; + this.buffers = options.return_buffers || options.detect_buffers; + this.options = options; + this.reply = 'ON'; // Returning replies is the default + this.create_stream(); + // The listeners will not be attached right away, so let's print the deprecation message while the listener is attached + this.on('newListener', function (event) { + if (event === 'idle') { + this.warn( + 'The idle event listener is deprecated and will likely be removed in v.3.0.0.\n' + + 'If you rely on this feature please open a new ticket in node_redis with your use case' + ); + } else if (event === 'drain') { + this.warn( + 'The drain event listener is deprecated and will be removed in v.3.0.0.\n' + + 'If you want to keep on listening to this event please listen to the stream drain event directly.' + ); + } else if ((event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer') && !this.buffers && !this.message_buffers) { + if (this.reply_parser.name !== 'javascript') { + return this.warn( + 'You attached the "' + event + '" listener without the returnBuffers option set to true.\n' + + 'Please use the JavaScript parser or set the returnBuffers option to true to return buffers.' + ); + } + this.reply_parser.optionReturnBuffers = true; + this.message_buffers = true; + this.handle_reply = handle_detect_buffers_reply; + } + }); +} +util.inherits(RedisClient, EventEmitter); + +RedisClient.connection_id = 0; + +function create_parser (self) { + return new Parser({ + returnReply: function (data) { + self.return_reply(data); + }, + returnError: function (err) { + // Return a ReplyError to indicate Redis returned an error + self.return_error(err); + }, + returnFatalError: function (err) { + // Error out all fired commands. Otherwise they might rely on faulty data. We have to reconnect to get in a working state again + // Note: the execution order is important. First flush and emit, then create the stream + err.message += '. Please report this.'; + self.ready = false; + self.flush_and_error({ + message: 'Fatal error encountert. Command aborted.', + code: 'NR_FATAL' + }, { + error: err, + queues: ['command_queue'] + }); + self.emit('error', err); + self.create_stream(); + }, + returnBuffers: self.buffers || self.message_buffers, + name: self.options.parser || 'javascript', + stringNumbers: self.options.string_numbers || false + }); +} + +/****************************************************************************** + + All functions in here are internal besides the RedisClient constructor + and the exported functions. Don't rely on them as they will be private + functions in node_redis v.3 + +******************************************************************************/ + +// Attention: the function name "create_stream" should not be changed, as other libraries need this to mock the stream (e.g. fakeredis) +RedisClient.prototype.create_stream = function () { + var self = this; + + // Init parser + this.reply_parser = create_parser(this); + + if (this.options.stream) { + // Only add the listeners once in case of a reconnect try (that won't work) + if (this.stream) { + return; + } + this.stream = this.options.stream; + } else { + // On a reconnect destroy the former stream and retry + if (this.stream) { + this.stream.removeAllListeners(); + this.stream.destroy(); + } + + /* istanbul ignore if: travis does not work with stunnel atm. Therefore the tls tests are skipped on travis */ + if (this.options.tls) { + this.stream = tls.connect(this.connection_options); + } else { + this.stream = net.createConnection(this.connection_options); + } + } + + if (this.options.connect_timeout) { + this.stream.setTimeout(this.connect_timeout, function () { + // Note: This is only tested if a internet connection is established + self.retry_totaltime = self.connect_timeout; + self.connection_gone('timeout'); + }); + } + + /* istanbul ignore next: travis does not work with stunnel atm. Therefore the tls tests are skipped on travis */ + var connect_event = this.options.tls ? 'secureConnect' : 'connect'; + this.stream.once(connect_event, function () { + this.removeAllListeners('timeout'); + self.times_connected++; + self.on_connect(); + }); + + this.stream.on('data', function (buffer_from_socket) { + // The buffer_from_socket.toString() has a significant impact on big chunks and therefore this should only be used if necessary + debug('Net read ' + self.address + ' id ' + self.connection_id); // + ': ' + buffer_from_socket.toString()); + self.reply_parser.execute(buffer_from_socket); + self.emit_idle(); + }); + + this.stream.on('error', function (err) { + self.on_error(err); + }); + + /* istanbul ignore next: difficult to test and not important as long as we keep this listener */ + this.stream.on('clientError', function (err) { + debug('clientError occured'); + self.on_error(err); + }); + + this.stream.once('close', function (hadError) { + self.connection_gone('close'); + }); + + this.stream.once('end', function () { + self.connection_gone('end'); + }); + + this.stream.on('drain', function () { + self.drain(); + }); + + if (this.options.socket_nodelay) { + this.stream.setNoDelay(); + } + + // Fire the command before redis is connected to be sure it's the first fired command + if (this.auth_pass !== undefined) { + this.ready = true; + // Fail silently as we might not be able to connect + this.auth(this.auth_pass, function (err) { + if (err && err.code !== 'UNCERTAIN_STATE') { + self.emit('error', err); + } + }); + this.ready = false; + } +}; + +RedisClient.prototype.handle_reply = function (reply, command) { + if (command === 'hgetall') { + reply = utils.reply_to_object(reply); + } + return reply; +}; + +RedisClient.prototype.cork = noop; +RedisClient.prototype.uncork = noop; + +RedisClient.prototype.initialize_retry_vars = function () { + this.retry_timer = null; + this.retry_totaltime = 0; + this.retry_delay = 200; + this.retry_backoff = 1.7; + this.attempts = 1; +}; + +RedisClient.prototype.warn = function (msg) { + var self = this; + // Warn on the next tick. Otherwise no event listener can be added + // for warnings that are emitted in the redis client constructor + process.nextTick(function () { + if (self.listeners('warning').length !== 0) { + self.emit('warning', msg); + } else { + console.warn('node_redis:', msg); + } + }); +}; + +// Flush provided queues, erroring any items with a callback first +RedisClient.prototype.flush_and_error = function (error_attributes, options) { + options = options || {}; + var aggregated_errors = []; + var queue_names = options.queues || ['command_queue', 'offline_queue']; // Flush the command_queue first to keep the order intakt + for (var i = 0; i < queue_names.length; i++) { + // If the command was fired it might have been processed so far + if (queue_names[i] === 'command_queue') { + error_attributes.message += ' It might have been processed.'; + } else { // As the command_queue is flushed first, remove this for the offline queue + error_attributes.message = error_attributes.message.replace(' It might have been processed.', ''); + } + // Don't flush everything from the queue + for (var command_obj = this[queue_names[i]].shift(); command_obj; command_obj = this[queue_names[i]].shift()) { + var err = new errorClasses.AbortError(error_attributes); + if (command_obj.error) { + err.stack = err.stack + command_obj.error.stack.replace(/^Error.*?\n/, '\n'); + } + err.command = command_obj.command.toUpperCase(); + if (command_obj.args && command_obj.args.length) { + err.args = command_obj.args; + } + if (options.error) { + err.origin = options.error; + } + if (typeof command_obj.callback === 'function') { + command_obj.callback(err); + } else { + aggregated_errors.push(err); + } + } + } + // Currently this would be a breaking change, therefore it's only emitted in debug_mode + if (exports.debug_mode && aggregated_errors.length) { + var error; + if (aggregated_errors.length === 1) { + error = aggregated_errors[0]; + } else { + error_attributes.message = error_attributes.message.replace('It', 'They').replace(/command/i, '$&s'); + error = new errorClasses.AggregateError(error_attributes); + error.errors = aggregated_errors; + } + this.emit('error', error); + } +}; + +RedisClient.prototype.on_error = function (err) { + if (this.closing) { + return; + } + + err.message = 'Redis connection to ' + this.address + ' failed - ' + err.message; + debug(err.message); + this.connected = false; + this.ready = false; + + // Only emit the error if the retry_stategy option is not set + if (!this.options.retry_strategy) { + this.emit('error', err); + } + // 'error' events get turned into exceptions if they aren't listened for. If the user handled this error + // then we should try to reconnect. + this.connection_gone('error', err); +}; + +RedisClient.prototype.on_connect = function () { + debug('Stream connected ' + this.address + ' id ' + this.connection_id); + + this.connected = true; + this.ready = false; + this.emitted_end = false; + this.stream.setKeepAlive(this.options.socket_keepalive); + this.stream.setTimeout(0); + + this.emit('connect'); + this.initialize_retry_vars(); + + if (this.options.no_ready_check) { + this.on_ready(); + } else { + this.ready_check(); + } +}; + +RedisClient.prototype.on_ready = function () { + var self = this; + + debug('on_ready called ' + this.address + ' id ' + this.connection_id); + this.ready = true; + + this.cork = function () { + self.pipeline = true; + if (self.stream.cork) { + self.stream.cork(); + } + }; + this.uncork = function () { + if (self.fire_strings) { + self.write_strings(); + } else { + self.write_buffers(); + } + self.pipeline = false; + self.fire_strings = true; + if (self.stream.uncork) { + // TODO: Consider using next tick here. See https://github.com/NodeRedis/node_redis/issues/1033 + self.stream.uncork(); + } + }; + + // Restore modal commands from previous connection. The order of the commands is important + if (this.selected_db !== undefined) { + this.internal_send_command(new Command('select', [this.selected_db])); + } + if (this.monitoring) { // Monitor has to be fired before pub sub commands + this.internal_send_command(new Command('monitor', [])); + } + var callback_count = Object.keys(this.subscription_set).length; + if (!this.options.disable_resubscribing && callback_count) { + // only emit 'ready' when all subscriptions were made again + // TODO: Remove the countdown for ready here. This is not coherent with all other modes and should therefore not be handled special + // We know we are ready as soon as all commands were fired + var callback = function () { + callback_count--; + if (callback_count === 0) { + self.emit('ready'); + } + }; + debug('Sending pub/sub on_ready commands'); + for (var key in this.subscription_set) { + var command = key.slice(0, key.indexOf('_')); + var args = this.subscription_set[key]; + this[command]([args], callback); + } + this.send_offline_queue(); + return; + } + this.send_offline_queue(); + this.emit('ready'); +}; + +RedisClient.prototype.on_info_cmd = function (err, res) { + if (err) { + if (err.message === "ERR unknown command 'info'") { + this.on_ready(); + return; + } + err.message = 'Ready check failed: ' + err.message; + this.emit('error', err); + return; + } + + /* istanbul ignore if: some servers might not respond with any info data. This is just a safety check that is difficult to test */ + if (!res) { + debug('The info command returned without any data.'); + this.on_ready(); + return; + } + + if (!this.server_info.loading || this.server_info.loading === '0') { + // If the master_link_status exists but the link is not up, try again after 50 ms + if (this.server_info.master_link_status && this.server_info.master_link_status !== 'up') { + this.server_info.loading_eta_seconds = 0.05; + } else { + // Eta loading should change + debug('Redis server ready.'); + this.on_ready(); + return; + } + } + + var retry_time = +this.server_info.loading_eta_seconds * 1000; + if (retry_time > 1000) { + retry_time = 1000; + } + debug('Redis server still loading, trying again in ' + retry_time); + setTimeout(function (self) { + self.ready_check(); + }, retry_time, this); +}; + +RedisClient.prototype.ready_check = function () { + var self = this; + debug('Checking server ready state...'); + // Always fire this info command as first command even if other commands are already queued up + this.ready = true; + this.info(function (err, res) { + self.on_info_cmd(err, res); + }); + this.ready = false; +}; + +RedisClient.prototype.send_offline_queue = function () { + for (var command_obj = this.offline_queue.shift(); command_obj; command_obj = this.offline_queue.shift()) { + debug('Sending offline command: ' + command_obj.command); + this.internal_send_command(command_obj); + } + this.drain(); +}; + +var retry_connection = function (self, error) { + debug('Retrying connection...'); + + var reconnect_params = { + delay: self.retry_delay, + attempt: self.attempts, + error: error + }; + if (self.options.camel_case) { + reconnect_params.totalRetryTime = self.retry_totaltime; + reconnect_params.timesConnected = self.times_connected; + } else { + reconnect_params.total_retry_time = self.retry_totaltime; + reconnect_params.times_connected = self.times_connected; + } + self.emit('reconnecting', reconnect_params); + + self.retry_totaltime += self.retry_delay; + self.attempts += 1; + self.retry_delay = Math.round(self.retry_delay * self.retry_backoff); + self.create_stream(); + self.retry_timer = null; +}; + +RedisClient.prototype.connection_gone = function (why, error) { + // If a retry is already in progress, just let that happen + if (this.retry_timer) { + return; + } + error = error || null; + + debug('Redis connection is gone from ' + why + ' event.'); + this.connected = false; + this.ready = false; + // Deactivate cork to work with the offline queue + this.cork = noop; + this.uncork = noop; + this.pipeline = false; + this.pub_sub_mode = 0; + + // since we are collapsing end and close, users don't expect to be called twice + if (!this.emitted_end) { + this.emit('end'); + this.emitted_end = true; + } + + // If this is a requested shutdown, then don't retry + if (this.closing) { + debug('Connection ended by quit / end command, not retrying.'); + this.flush_and_error({ + message: 'Stream connection ended and command aborted.', + code: 'NR_CLOSED' + }, { + error: error + }); + return; + } + + if (typeof this.options.retry_strategy === 'function') { + var retry_params = { + attempt: this.attempts, + error: error + }; + if (this.options.camel_case) { + retry_params.totalRetryTime = this.retry_totaltime; + retry_params.timesConnected = this.times_connected; + } else { + retry_params.total_retry_time = this.retry_totaltime; + retry_params.times_connected = this.times_connected; + } + this.retry_delay = this.options.retry_strategy(retry_params); + if (typeof this.retry_delay !== 'number') { + // Pass individual error through + if (this.retry_delay instanceof Error) { + error = this.retry_delay; + } + this.flush_and_error({ + message: 'Stream connection ended and command aborted.', + code: 'NR_CLOSED' + }, { + error: error + }); + this.end(false); + return; + } + } + + if (this.max_attempts !== 0 && this.attempts >= this.max_attempts || this.retry_totaltime >= this.connect_timeout) { + var message = 'Redis connection in broken state: '; + if (this.retry_totaltime >= this.connect_timeout) { + message += 'connection timeout exceeded.'; + } else { + message += 'maximum connection attempts exceeded.'; + } + + this.flush_and_error({ + message: message, + code: 'CONNECTION_BROKEN', + }, { + error: error + }); + var err = new Error(message); + err.code = 'CONNECTION_BROKEN'; + if (error) { + err.origin = error; + } + this.emit('error', err); + this.end(false); + return; + } + + // Retry commands after a reconnect instead of throwing an error. Use this with caution + if (this.options.retry_unfulfilled_commands) { + this.offline_queue.unshift.apply(this.offline_queue, this.command_queue.toArray()); + this.command_queue.clear(); + } else if (this.command_queue.length !== 0) { + this.flush_and_error({ + message: 'Redis connection lost and command aborted.', + code: 'UNCERTAIN_STATE' + }, { + error: error, + queues: ['command_queue'] + }); + } + + if (this.retry_max_delay !== null && this.retry_delay > this.retry_max_delay) { + this.retry_delay = this.retry_max_delay; + } else if (this.retry_totaltime + this.retry_delay > this.connect_timeout) { + // Do not exceed the maximum + this.retry_delay = this.connect_timeout - this.retry_totaltime; + } + + debug('Retry connection in ' + this.retry_delay + ' ms'); + + this.retry_timer = setTimeout(retry_connection, this.retry_delay, this, error); +}; + +RedisClient.prototype.return_error = function (err) { + var command_obj = this.command_queue.shift(); + if (command_obj.error) { + err.stack = command_obj.error.stack.replace(/^Error.*?\n/, 'ReplyError: ' + err.message + '\n'); + } + err.command = command_obj.command.toUpperCase(); + if (command_obj.args && command_obj.args.length) { + err.args = command_obj.args; + } + + // Count down pub sub mode if in entering modus + if (this.pub_sub_mode > 1) { + this.pub_sub_mode--; + } + + var match = err.message.match(utils.err_code); + // LUA script could return user errors that don't behave like all other errors! + if (match) { + err.code = match[1]; + } + + utils.callback_or_emit(this, command_obj.callback, err); +}; + +RedisClient.prototype.drain = function () { + this.emit('drain'); + this.should_buffer = false; +}; + +RedisClient.prototype.emit_idle = function () { + if (this.command_queue.length === 0 && this.pub_sub_mode === 0) { + this.emit('idle'); + } +}; + +function normal_reply (self, reply) { + var command_obj = self.command_queue.shift(); + if (typeof command_obj.callback === 'function') { + if (command_obj.command !== 'exec') { + reply = self.handle_reply(reply, command_obj.command, command_obj.buffer_args); + } + command_obj.callback(null, reply); + } else { + debug('No callback for reply'); + } +} + +function subscribe_unsubscribe (self, reply, type) { + // Subscribe commands take an optional callback and also emit an event, but only the _last_ response is included in the callback + // The pub sub commands return each argument in a separate return value and have to be handled that way + var command_obj = self.command_queue.get(0); + var buffer = self.options.return_buffers || self.options.detect_buffers && command_obj.buffer_args; + var channel = (buffer || reply[1] === null) ? reply[1] : reply[1].toString(); + var count = +reply[2]; // Return the channel counter as number no matter if `string_numbers` is activated or not + debug(type, channel); + + // Emit first, then return the callback + if (channel !== null) { // Do not emit or "unsubscribe" something if there was no channel to unsubscribe from + self.emit(type, channel, count); + if (type === 'subscribe' || type === 'psubscribe') { + self.subscription_set[type + '_' + channel] = channel; + } else { + type = type === 'unsubscribe' ? 'subscribe' : 'psubscribe'; // Make types consistent + delete self.subscription_set[type + '_' + channel]; + } + } + + if (command_obj.args.length === 1 || self.sub_commands_left === 1 || command_obj.args.length === 0 && (count === 0 || channel === null)) { + if (count === 0) { // unsubscribed from all channels + var running_command; + var i = 1; + self.pub_sub_mode = 0; // Deactivating pub sub mode + // This should be a rare case and therefore handling it this way should be good performance wise for the general case + while (running_command = self.command_queue.get(i)) { + if (SUBSCRIBE_COMMANDS[running_command.command]) { + self.pub_sub_mode = i; // Entering pub sub mode again + break; + } + i++; + } + } + self.command_queue.shift(); + if (typeof command_obj.callback === 'function') { + // TODO: The current return value is pretty useless. + // Evaluate to change this in v.3 to return all subscribed / unsubscribed channels in an array including the number of channels subscribed too + command_obj.callback(null, channel); + } + self.sub_commands_left = 0; + } else { + if (self.sub_commands_left !== 0) { + self.sub_commands_left--; + } else { + self.sub_commands_left = command_obj.args.length ? command_obj.args.length - 1 : count; + } + } +} + +function return_pub_sub (self, reply) { + var type = reply[0].toString(); + if (type === 'message') { // channel, message + if (!self.options.return_buffers || self.message_buffers) { // backwards compatible. Refactor this in v.3 to always return a string on the normal emitter + self.emit('message', reply[1].toString(), reply[2].toString()); + self.emit('message_buffer', reply[1], reply[2]); + self.emit('messageBuffer', reply[1], reply[2]); + } else { + self.emit('message', reply[1], reply[2]); + } + } else if (type === 'pmessage') { // pattern, channel, message + if (!self.options.return_buffers || self.message_buffers) { // backwards compatible. Refactor this in v.3 to always return a string on the normal emitter + self.emit('pmessage', reply[1].toString(), reply[2].toString(), reply[3].toString()); + self.emit('pmessage_buffer', reply[1], reply[2], reply[3]); + self.emit('pmessageBuffer', reply[1], reply[2], reply[3]); + } else { + self.emit('pmessage', reply[1], reply[2], reply[3]); + } + } else { + subscribe_unsubscribe(self, reply, type); + } +} + +RedisClient.prototype.return_reply = function (reply) { + if (this.monitoring) { + var replyStr; + if (this.buffers && Buffer.isBuffer(reply)) { + replyStr = reply.toString(); + } else { + replyStr = reply; + } + // If in monitor mode, all normal commands are still working and we only want to emit the streamlined commands + if (typeof replyStr === 'string' && utils.monitor_regex.test(replyStr)) { + var timestamp = replyStr.slice(0, replyStr.indexOf(' ')); + var args = replyStr.slice(replyStr.indexOf('"') + 1, -1).split('" "').map(function (elem) { + return elem.replace(/\\"/g, '"'); + }); + this.emit('monitor', timestamp, args, replyStr); + return; + } + } + if (this.pub_sub_mode === 0) { + normal_reply(this, reply); + } else if (this.pub_sub_mode !== 1) { + this.pub_sub_mode--; + normal_reply(this, reply); + } else if (!(reply instanceof Array) || reply.length <= 2) { + // Only PING and QUIT are allowed in this context besides the pub sub commands + // Ping replies with ['pong', null|value] and quit with 'OK' + normal_reply(this, reply); + } else { + return_pub_sub(this, reply); + } +}; + +function handle_offline_command (self, command_obj) { + var command = command_obj.command; + var err, msg; + if (self.closing || !self.enable_offline_queue) { + command = command.toUpperCase(); + if (!self.closing) { + if (self.stream.writable) { + msg = 'The connection is not yet established and the offline queue is deactivated.'; + } else { + msg = 'Stream not writeable.'; + } + } else { + msg = 'The connection is already closed.'; + } + err = new errorClasses.AbortError({ + message: command + " can't be processed. " + msg, + code: 'NR_CLOSED', + command: command + }); + if (command_obj.args.length) { + err.args = command_obj.args; + } + utils.reply_in_order(self, command_obj.callback, err); + } else { + debug('Queueing ' + command + ' for next server connection.'); + self.offline_queue.push(command_obj); + } + self.should_buffer = true; +} + +// Do not call internal_send_command directly, if you are not absolutly certain it handles everything properly +// e.g. monitor / info does not work with internal_send_command only +RedisClient.prototype.internal_send_command = function (command_obj) { + var arg, prefix_keys; + var i = 0; + var command_str = ''; + var args = command_obj.args; + var command = command_obj.command; + var len = args.length; + var big_data = false; + var args_copy = new Array(len); + + if (process.domain && command_obj.callback) { + command_obj.callback = process.domain.bind(command_obj.callback); + } + + if (this.ready === false || this.stream.writable === false) { + // Handle offline commands right away + handle_offline_command(this, command_obj); + return false; // Indicate buffering + } + + for (i = 0; i < len; i += 1) { + if (typeof args[i] === 'string') { + // 30000 seemed to be a good value to switch to buffers after testing and checking the pros and cons + if (args[i].length > 30000) { + big_data = true; + args_copy[i] = new Buffer(args[i], 'utf8'); + } else { + args_copy[i] = args[i]; + } + } else if (typeof args[i] === 'object') { // Checking for object instead of Buffer.isBuffer helps us finding data types that we can't handle properly + if (args[i] instanceof Date) { // Accept dates as valid input + args_copy[i] = args[i].toString(); + } else if (args[i] === null) { + this.warn( + 'Deprecated: The ' + command.toUpperCase() + ' command contains a "null" argument.\n' + + 'This is converted to a "null" string now and will return an error from v.3.0 on.\n' + + 'Please handle this in your code to make sure everything works as you intended it to.' + ); + args_copy[i] = 'null'; // Backwards compatible :/ + } else if (Buffer.isBuffer(args[i])) { + args_copy[i] = args[i]; + command_obj.buffer_args = true; + big_data = true; + } else { + this.warn( + 'Deprecated: The ' + command.toUpperCase() + ' command contains a argument of type ' + args[i].constructor.name + '.\n' + + 'This is converted to "' + args[i].toString() + '" by using .toString() now and will return an error from v.3.0 on.\n' + + 'Please handle this in your code to make sure everything works as you intended it to.' + ); + args_copy[i] = args[i].toString(); // Backwards compatible :/ + } + } else if (typeof args[i] === 'undefined') { + this.warn( + 'Deprecated: The ' + command.toUpperCase() + ' command contains a "undefined" argument.\n' + + 'This is converted to a "undefined" string now and will return an error from v.3.0 on.\n' + + 'Please handle this in your code to make sure everything works as you intended it to.' + ); + args_copy[i] = 'undefined'; // Backwards compatible :/ + } else { + // Seems like numbers are converted fast using string concatenation + args_copy[i] = '' + args[i]; + } + } + + if (this.options.prefix) { + prefix_keys = commands.getKeyIndexes(command, args_copy); + for (i = prefix_keys.pop(); i !== undefined; i = prefix_keys.pop()) { + args_copy[i] = this.options.prefix + args_copy[i]; + } + } + if (this.options.rename_commands && this.options.rename_commands[command]) { + command = this.options.rename_commands[command]; + } + // Always use 'Multi bulk commands', but if passed any Buffer args, then do multiple writes, one for each arg. + // This means that using Buffers in commands is going to be slower, so use Strings if you don't already have a Buffer. + command_str = '*' + (len + 1) + '\r\n$' + command.length + '\r\n' + command + '\r\n'; + + if (big_data === false) { // Build up a string and send entire command in one write + for (i = 0; i < len; i += 1) { + arg = args_copy[i]; + command_str += '$' + Buffer.byteLength(arg) + '\r\n' + arg + '\r\n'; + } + debug('Send ' + this.address + ' id ' + this.connection_id + ': ' + command_str); + this.write(command_str); + } else { + debug('Send command (' + command_str + ') has Buffer arguments'); + this.fire_strings = false; + this.write(command_str); + + for (i = 0; i < len; i += 1) { + arg = args_copy[i]; + if (typeof arg === 'string') { + this.write('$' + Buffer.byteLength(arg) + '\r\n' + arg + '\r\n'); + } else { // buffer + this.write('$' + arg.length + '\r\n'); + this.write(arg); + this.write('\r\n'); + } + debug('send_command: buffer send ' + arg.length + ' bytes'); + } + } + if (command_obj.call_on_write) { + command_obj.call_on_write(); + } + // Handle `CLIENT REPLY ON|OFF|SKIP` + // This has to be checked after call_on_write + /* istanbul ignore else: TODO: Remove this as soon as we test Redis 3.2 on travis */ + if (this.reply === 'ON') { + this.command_queue.push(command_obj); + } else { + // Do not expect a reply + // Does this work in combination with the pub sub mode? + if (command_obj.callback) { + utils.reply_in_order(this, command_obj.callback, null, undefined, this.command_queue); + } + if (this.reply === 'SKIP') { + this.reply = 'SKIP_ONE_MORE'; + } else if (this.reply === 'SKIP_ONE_MORE') { + this.reply = 'ON'; + } + } + return !this.should_buffer; +}; + +RedisClient.prototype.write_strings = function () { + var str = ''; + for (var command = this.pipeline_queue.shift(); command; command = this.pipeline_queue.shift()) { + // Write to stream if the string is bigger than 4mb. The biggest string may be Math.pow(2, 28) - 15 chars long + if (str.length + command.length > 4 * 1024 * 1024) { + this.should_buffer = !this.stream.write(str); + str = ''; + } + str += command; + } + if (str !== '') { + this.should_buffer = !this.stream.write(str); + } +}; + +RedisClient.prototype.write_buffers = function () { + for (var command = this.pipeline_queue.shift(); command; command = this.pipeline_queue.shift()) { + this.should_buffer = !this.stream.write(command); + } +}; + +RedisClient.prototype.write = function (data) { + if (this.pipeline === false) { + this.should_buffer = !this.stream.write(data); + return; + } + this.pipeline_queue.push(data); +}; + +Object.defineProperty(exports, 'debugMode', { + get: function () { + return this.debug_mode; + }, + set: function (val) { + this.debug_mode = val; + } +}); + +// Don't officially expose the command_queue directly but only the length as read only variable +Object.defineProperty(RedisClient.prototype, 'command_queue_length', { + get: function () { + return this.command_queue.length; + } +}); + +Object.defineProperty(RedisClient.prototype, 'offline_queue_length', { + get: function () { + return this.offline_queue.length; + } +}); + +// Add support for camelCase by adding read only properties to the client +// All known exposed snake_case variables are added here +Object.defineProperty(RedisClient.prototype, 'retryDelay', { + get: function () { + return this.retry_delay; + } +}); + +Object.defineProperty(RedisClient.prototype, 'retryBackoff', { + get: function () { + return this.retry_backoff; + } +}); + +Object.defineProperty(RedisClient.prototype, 'commandQueueLength', { + get: function () { + return this.command_queue.length; + } +}); + +Object.defineProperty(RedisClient.prototype, 'offlineQueueLength', { + get: function () { + return this.offline_queue.length; + } +}); + +Object.defineProperty(RedisClient.prototype, 'shouldBuffer', { + get: function () { + return this.should_buffer; + } +}); + +Object.defineProperty(RedisClient.prototype, 'connectionId', { + get: function () { + return this.connection_id; + } +}); + +Object.defineProperty(RedisClient.prototype, 'serverInfo', { + get: function () { + return this.server_info; + } +}); + +exports.createClient = function () { + return new RedisClient(unifyOptions.apply(null, arguments)); +}; +exports.RedisClient = RedisClient; +exports.print = utils.print; +exports.Multi = require('./lib/multi'); +exports.AbortError = errorClasses.AbortError; +exports.RedisError = Parser.RedisError; +exports.ParserError = Parser.ParserError; +exports.ReplyError = Parser.ReplyError; +exports.AggregateError = errorClasses.AggregateError; + +// Add all redis commands / node_redis api to the client +require('./lib/individualCommands'); +require('./lib/extendedApi'); + +//enables adding new commands (for modules and new commands) +exports.addCommand = exports.add_command = require('./lib/commands'); \ No newline at end of file diff --git a/nodejs/node_modules/redis/lib/command.js b/nodejs/node_modules/redis/lib/command.js new file mode 100755 index 0000000..717115c --- /dev/null +++ b/nodejs/node_modules/redis/lib/command.js @@ -0,0 +1,16 @@ +'use strict'; + +var betterStackTraces = /development/i.test(process.env.NODE_ENV) || /\bredis\b/i.test(process.env.NODE_DEBUG); + +function Command (command, args, callback, call_on_write) { + this.command = command; + this.args = args; + this.buffer_args = false; + this.callback = callback; + this.call_on_write = call_on_write; + if (betterStackTraces) { + this.error = new Error(); + } +} + +module.exports = Command; diff --git a/nodejs/node_modules/redis/lib/commands.js b/nodejs/node_modules/redis/lib/commands.js new file mode 100755 index 0000000..6275ec8 --- /dev/null +++ b/nodejs/node_modules/redis/lib/commands.js @@ -0,0 +1,121 @@ +'use strict'; + +var commands = require('redis-commands'); +var Multi = require('./multi'); +var RedisClient = require('../').RedisClient; +var Command = require('./command'); +// Feature detect if a function may change it's name +var changeFunctionName = (function () { + var fn = function abc () {}; + try { + Object.defineProperty(fn, 'name', { + value: 'foobar' + }); + return true; + } catch (e) { + return false; + } +}()); + +var addCommand = function (command) { + // Some rare Redis commands use special characters in their command name + // Convert those to a underscore to prevent using invalid function names + var commandName = command.replace(/(?:^([0-9])|[^a-zA-Z0-9_$])/g, '_$1'); + + // Do not override existing functions + if (!RedisClient.prototype[command]) { + RedisClient.prototype[command.toUpperCase()] = RedisClient.prototype[command] = function () { + var arr; + var len = arguments.length; + var callback; + var i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0]; + if (len === 2) { + callback = arguments[1]; + } + } else if (len > 1 && Array.isArray(arguments[1])) { + if (len === 3) { + callback = arguments[2]; + } + len = arguments[1].length; + arr = new Array(len + 1); + arr[0] = arguments[0]; + for (; i < len; i += 1) { + arr[i + 1] = arguments[1][i]; + } + } else { + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + return this.internal_send_command(new Command(command, arr, callback)); + }; + // Alias special function names (e.g. NR.RUN becomes NR_RUN and nr_run) + if (commandName !== command) { + RedisClient.prototype[commandName.toUpperCase()] = RedisClient.prototype[commandName] = RedisClient.prototype[command]; + } + if (changeFunctionName) { + Object.defineProperty(RedisClient.prototype[command], 'name', { + value: commandName + }); + } + } + + // Do not override existing functions + if (!Multi.prototype[command]) { + Multi.prototype[command.toUpperCase()] = Multi.prototype[command] = function () { + var arr; + var len = arguments.length; + var callback; + var i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0]; + if (len === 2) { + callback = arguments[1]; + } + } else if (len > 1 && Array.isArray(arguments[1])) { + if (len === 3) { + callback = arguments[2]; + } + len = arguments[1].length; + arr = new Array(len + 1); + arr[0] = arguments[0]; + for (; i < len; i += 1) { + arr[i + 1] = arguments[1][i]; + } + } else { + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + this.queue.push(new Command(command, arr, callback)); + return this; + }; + // Alias special function names (e.g. NR.RUN becomes NR_RUN and nr_run) + if (commandName !== command) { + Multi.prototype[commandName.toUpperCase()] = Multi.prototype[commandName] = Multi.prototype[command]; + } + if (changeFunctionName) { + Object.defineProperty(Multi.prototype[command], 'name', { + value: commandName + }); + } + } +}; + +commands.list.forEach(addCommand); + +module.exports = addCommand; diff --git a/nodejs/node_modules/redis/lib/createClient.js b/nodejs/node_modules/redis/lib/createClient.js new file mode 100755 index 0000000..2f3b09f --- /dev/null +++ b/nodejs/node_modules/redis/lib/createClient.js @@ -0,0 +1,80 @@ +'use strict'; + +var utils = require('./utils'); +var URL = require('url'); + +module.exports = function createClient (port_arg, host_arg, options) { + + if (typeof port_arg === 'number' || typeof port_arg === 'string' && /^\d+$/.test(port_arg)) { + + var host; + if (typeof host_arg === 'string') { + host = host_arg; + } else { + if (options && host_arg) { + throw new TypeError('Unknown type of connection in createClient()'); + } + options = options || host_arg; + } + options = utils.clone(options); + options.host = host || options.host; + options.port = port_arg; + + } else if (typeof port_arg === 'string' || port_arg && port_arg.url) { + + options = utils.clone(port_arg.url ? port_arg : host_arg || options); + var url = port_arg.url || port_arg; + var parsed = URL.parse(url, true, true); + + // [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]] + if (parsed.slashes) { // We require slashes + if (parsed.auth) { + options.password = parsed.auth.split(':')[1]; + } + if (parsed.protocol && parsed.protocol !== 'redis:') { + console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!'); + } + if (parsed.pathname && parsed.pathname !== '/') { + options.db = parsed.pathname.substr(1); + } + if (parsed.hostname) { + options.host = parsed.hostname; + } + if (parsed.port) { + options.port = parsed.port; + } + if (parsed.search !== '') { + var elem; + for (elem in parsed.query) { + // If options are passed twice, only the parsed options will be used + if (elem in options) { + if (options[elem] === parsed.query[elem]) { + console.warn('node_redis: WARNING: You passed the ' + elem + ' option twice!'); + } else { + throw new RangeError('The ' + elem + ' option is added twice and does not match'); + } + } + options[elem] = parsed.query[elem]; + } + } + } else if (parsed.hostname) { + throw new RangeError('The redis url must begin with slashes "//" or contain slashes after the redis protocol'); + } else { + options.path = url; + } + + } else if (typeof port_arg === 'object' || port_arg === undefined) { + options = utils.clone(port_arg || options); + options.host = options.host || host_arg; + + if (port_arg && arguments.length !== 1) { + throw new TypeError('To many arguments passed to createClient. Please only pass the options object'); + } + } + + if (!options) { + throw new TypeError('Unknown type of connection in createClient()'); + } + + return options; +}; diff --git a/nodejs/node_modules/redis/lib/customErrors.js b/nodejs/node_modules/redis/lib/customErrors.js new file mode 100755 index 0000000..d9b3442 --- /dev/null +++ b/nodejs/node_modules/redis/lib/customErrors.js @@ -0,0 +1,59 @@ +'use strict'; + +var util = require('util'); +var assert = require('assert'); +var RedisError = require('redis-parser').RedisError; +var ADD_STACKTRACE = false; + +function AbortError (obj, stack) { + assert(obj, 'The options argument is required'); + assert.strictEqual(typeof obj, 'object', 'The options argument has to be of type object'); + + RedisError.call(this, obj.message, ADD_STACKTRACE); + Object.defineProperty(this, 'message', { + value: obj.message || '', + configurable: true, + writable: true + }); + if (stack || stack === undefined) { + Error.captureStackTrace(this, AbortError); + } + for (var keys = Object.keys(obj), key = keys.pop(); key; key = keys.pop()) { + this[key] = obj[key]; + } +} + +function AggregateError (obj) { + assert(obj, 'The options argument is required'); + assert.strictEqual(typeof obj, 'object', 'The options argument has to be of type object'); + + AbortError.call(this, obj, ADD_STACKTRACE); + Object.defineProperty(this, 'message', { + value: obj.message || '', + configurable: true, + writable: true + }); + Error.captureStackTrace(this, AggregateError); + for (var keys = Object.keys(obj), key = keys.pop(); key; key = keys.pop()) { + this[key] = obj[key]; + } +} + +util.inherits(AbortError, RedisError); +util.inherits(AggregateError, AbortError); + +Object.defineProperty(AbortError.prototype, 'name', { + value: 'AbortError', + configurable: true, + writable: true +}); +Object.defineProperty(AggregateError.prototype, 'name', { + value: 'AggregateError', + configurable: true, + writable: true +}); + +module.exports = { + AbortError: AbortError, + AggregateError: AggregateError +}; diff --git a/nodejs/node_modules/redis/lib/debug.js b/nodejs/node_modules/redis/lib/debug.js new file mode 100755 index 0000000..0e6333f --- /dev/null +++ b/nodejs/node_modules/redis/lib/debug.js @@ -0,0 +1,11 @@ +'use strict'; + +var index = require('../'); + +function debug () { + if (index.debug_mode) { + console.error.apply(null, arguments); + } +} + +module.exports = debug; diff --git a/nodejs/node_modules/redis/lib/extendedApi.js b/nodejs/node_modules/redis/lib/extendedApi.js new file mode 100755 index 0000000..bac3691 --- /dev/null +++ b/nodejs/node_modules/redis/lib/extendedApi.js @@ -0,0 +1,113 @@ +'use strict'; + +var utils = require('./utils'); +var debug = require('./debug'); +var RedisClient = require('../').RedisClient; +var Command = require('./command'); +var noop = function () {}; + +/********************************************** +All documented and exposed API belongs in here +**********************************************/ + +// Redirect calls to the appropriate function and use to send arbitrary / not supported commands +RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = function (command, args, callback) { + // Throw to fail early instead of relying in order in this case + if (typeof command !== 'string') { + throw new TypeError('Wrong input type "' + (command !== null && command !== undefined ? command.constructor.name : command) + '" for command name'); + } + command = command.toLowerCase(); + if (!Array.isArray(args)) { + if (args === undefined || args === null) { + args = []; + } else if (typeof args === 'function' && callback === undefined) { + callback = args; + args = []; + } else { + throw new TypeError('Wrong input type "' + args.constructor.name + '" for args'); + } + } + if (typeof callback !== 'function' && callback !== undefined) { + throw new TypeError('Wrong input type "' + (callback !== null ? callback.constructor.name : 'null') + '" for callback function'); + } + + // Using the raw multi command is only possible with this function + // If the command is not yet added to the client, the internal function should be called right away + // Otherwise we need to redirect the calls to make sure the internal functions don't get skipped + // The internal functions could actually be used for any non hooked function + // but this might change from time to time and at the moment there's no good way to distinguish them + // from each other, so let's just do it do it this way for the time being + if (command === 'multi' || typeof this[command] !== 'function') { + return this.internal_send_command(new Command(command, args, callback)); + } + if (typeof callback === 'function') { + args = args.concat([callback]); // Prevent manipulating the input array + } + return this[command].apply(this, args); +}; + +RedisClient.prototype.end = function (flush) { + // Flush queue if wanted + if (flush) { + this.flush_and_error({ + message: 'Connection forcefully ended and command aborted.', + code: 'NR_CLOSED' + }); + } else if (arguments.length === 0) { + this.warn( + 'Using .end() without the flush parameter is deprecated and throws from v.3.0.0 on.\n' + + 'Please check the doku (https://github.com/NodeRedis/node_redis) and explictly use flush.' + ); + } + // Clear retry_timer + if (this.retry_timer) { + clearTimeout(this.retry_timer); + this.retry_timer = null; + } + this.stream.removeAllListeners(); + this.stream.on('error', noop); + this.connected = false; + this.ready = false; + this.closing = true; + return this.stream.destroySoon(); +}; + +RedisClient.prototype.unref = function () { + if (this.connected) { + debug("Unref'ing the socket connection"); + this.stream.unref(); + } else { + debug('Not connected yet, will unref later'); + this.once('connect', function () { + this.unref(); + }); + } +}; + +RedisClient.prototype.duplicate = function (options, callback) { + if (typeof options === 'function') { + callback = options; + options = null; + } + var existing_options = utils.clone(this.options); + options = utils.clone(options); + for (var elem in options) { + existing_options[elem] = options[elem]; + } + var client = new RedisClient(existing_options); + client.selected_db = this.selected_db; + if (typeof callback === 'function') { + var ready_listener = function () { + callback(null, client); + client.removeAllListeners(error_listener); + }; + var error_listener = function (err) { + callback(err); + client.end(true); + }; + client.once('ready', ready_listener); + client.once('error', error_listener); + return; + } + return client; +}; diff --git a/nodejs/node_modules/redis/lib/individualCommands.js b/nodejs/node_modules/redis/lib/individualCommands.js new file mode 100755 index 0000000..d366b64 --- /dev/null +++ b/nodejs/node_modules/redis/lib/individualCommands.js @@ -0,0 +1,617 @@ +'use strict'; + +var utils = require('./utils'); +var debug = require('./debug'); +var Multi = require('./multi'); +var Command = require('./command'); +var no_password_is_set = /no password is set/; +var loading = /LOADING/; +var RedisClient = require('../').RedisClient; + +/******************************************************************************************** + Replace built-in redis functions + + The callback may be hooked as needed. The same does not apply to the rest of the function. + State should not be set outside of the callback if not absolutly necessary. + This is important to make sure it works the same as single command or in a multi context. + To make sure everything works with the offline queue use the "call_on_write" function. + This is going to be executed while writing to the stream. + + TODO: Implement individal command generation as soon as possible to prevent divergent code + on single and multi calls! +********************************************************************************************/ + +RedisClient.prototype.multi = RedisClient.prototype.MULTI = function multi (args) { + var multi = new Multi(this, args); + multi.exec = multi.EXEC = multi.exec_transaction; + return multi; +}; + +// ATTENTION: This is not a native function but is still handled as a individual command as it behaves just the same as multi +RedisClient.prototype.batch = RedisClient.prototype.BATCH = function batch (args) { + return new Multi(this, args); +}; + +function select_callback (self, db, callback) { + return function (err, res) { + if (err === null) { + // Store db in this.select_db to restore it on reconnect + self.selected_db = db; + } + utils.callback_or_emit(self, callback, err, res); + }; +} + +RedisClient.prototype.select = RedisClient.prototype.SELECT = function select (db, callback) { + return this.internal_send_command(new Command('select', [db], select_callback(this, db, callback))); +}; + +Multi.prototype.select = Multi.prototype.SELECT = function select (db, callback) { + this.queue.push(new Command('select', [db], select_callback(this._client, db, callback))); + return this; +}; + +RedisClient.prototype.monitor = RedisClient.prototype.MONITOR = function monitor (callback) { + // Use a individual command, as this is a special case that does not has to be checked for any other command + var self = this; + var call_on_write = function () { + // Activating monitor mode has to happen before Redis returned the callback. The monitor result is returned first. + // Therefore we expect the command to be properly processed. If this is not the case, it's not an issue either. + self.monitoring = true; + }; + return this.internal_send_command(new Command('monitor', [], callback, call_on_write)); +}; + +// Only works with batch, not in a transaction +Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback) { + // Use a individual command, as this is a special case that does not has to be checked for any other command + if (this.exec !== this.exec_transaction) { + var self = this; + var call_on_write = function () { + self._client.monitoring = true; + }; + this.queue.push(new Command('monitor', [], callback, call_on_write)); + return this; + } + // Set multi monitoring to indicate the exec that it should abort + // Remove this "hack" as soon as Redis might fix this + this.monitoring = true; + return this; +}; + +function quit_callback (self, callback) { + return function (err, res) { + if (err && err.code === 'NR_CLOSED') { + // Pretent the quit command worked properly in this case. + // Either the quit landed in the offline queue and was flushed at the reconnect + // or the offline queue is deactivated and the command was rejected right away + // or the stream is not writable + // or while sending the quit, the connection ended / closed + err = null; + res = 'OK'; + } + utils.callback_or_emit(self, callback, err, res); + if (self.stream.writable) { + // If the socket is still alive, kill it. This could happen if quit got a NR_CLOSED error code + self.stream.destroy(); + } + }; +} + +RedisClient.prototype.QUIT = RedisClient.prototype.quit = function quit (callback) { + // TODO: Consider this for v.3 + // Allow the quit command to be fired as soon as possible to prevent it landing in the offline queue. + // this.ready = this.offline_queue.length === 0; + var backpressure_indicator = this.internal_send_command(new Command('quit', [], quit_callback(this, callback))); + // Calling quit should always end the connection, no matter if there's a connection or not + this.closing = true; + this.ready = false; + return backpressure_indicator; +}; + +// Only works with batch, not in a transaction +Multi.prototype.QUIT = Multi.prototype.quit = function quit (callback) { + var self = this._client; + var call_on_write = function () { + // If called in a multi context, we expect redis is available + self.closing = true; + self.ready = false; + }; + this.queue.push(new Command('quit', [], quit_callback(self, callback), call_on_write)); + return this; +}; + +function info_callback (self, callback) { + return function (err, res) { + if (res) { + var obj = {}; + var lines = res.toString().split('\r\n'); + var line, parts, sub_parts; + + for (var i = 0; i < lines.length; i++) { + parts = lines[i].split(':'); + if (parts[1]) { + if (parts[0].indexOf('db') === 0) { + sub_parts = parts[1].split(','); + obj[parts[0]] = {}; + while (line = sub_parts.pop()) { + line = line.split('='); + obj[parts[0]][line[0]] = +line[1]; + } + } else { + obj[parts[0]] = parts[1]; + } + } + } + obj.versions = []; + if (obj.redis_version) { + obj.redis_version.split('.').forEach(function (num) { + obj.versions.push(+num); + }); + } + // Expose info key/vals to users + self.server_info = obj; + } else { + self.server_info = {}; + } + utils.callback_or_emit(self, callback, err, res); + }; +} + +// Store info in this.server_info after each call +RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section, callback) { + var args = []; + if (typeof section === 'function') { + callback = section; + } else if (section !== undefined) { + args = Array.isArray(section) ? section : [section]; + } + return this.internal_send_command(new Command('info', args, info_callback(this, callback))); +}; + +Multi.prototype.info = Multi.prototype.INFO = function info (section, callback) { + var args = []; + if (typeof section === 'function') { + callback = section; + } else if (section !== undefined) { + args = Array.isArray(section) ? section : [section]; + } + this.queue.push(new Command('info', args, info_callback(this._client, callback))); + return this; +}; + +function auth_callback (self, pass, callback) { + return function (err, res) { + if (err) { + if (no_password_is_set.test(err.message)) { + self.warn('Warning: Redis server does not require a password, but a password was supplied.'); + err = null; + res = 'OK'; + } else if (loading.test(err.message)) { + // If redis is still loading the db, it will not authenticate and everything else will fail + debug('Redis still loading, trying to authenticate later'); + setTimeout(function () { + self.auth(pass, callback); + }, 100); + return; + } + } + utils.callback_or_emit(self, callback, err, res); + }; +} + +RedisClient.prototype.auth = RedisClient.prototype.AUTH = function auth (pass, callback) { + debug('Sending auth to ' + this.address + ' id ' + this.connection_id); + + // Stash auth for connect and reconnect. + this.auth_pass = pass; + var ready = this.ready; + this.ready = ready || this.offline_queue.length === 0; + var tmp = this.internal_send_command(new Command('auth', [pass], auth_callback(this, pass, callback))); + this.ready = ready; + return tmp; +}; + +// Only works with batch, not in a transaction +Multi.prototype.auth = Multi.prototype.AUTH = function auth (pass, callback) { + debug('Sending auth to ' + this.address + ' id ' + this.connection_id); + + // Stash auth for connect and reconnect. + this.auth_pass = pass; + this.queue.push(new Command('auth', [pass], auth_callback(this._client, callback))); + return this; +}; + +RedisClient.prototype.client = RedisClient.prototype.CLIENT = function client () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0]; + callback = arguments[1]; + } else if (Array.isArray(arguments[1])) { + if (len === 3) { + callback = arguments[2]; + } + len = arguments[1].length; + arr = new Array(len + 1); + arr[0] = arguments[0]; + for (; i < len; i += 1) { + arr[i + 1] = arguments[1][i]; + } + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this; + var call_on_write = undefined; + // CLIENT REPLY ON|OFF|SKIP + /* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */ + if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') { + var reply_on_off = arr[1].toString().toUpperCase(); + if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') { + call_on_write = function () { + self.reply = reply_on_off; + }; + } + } + return this.internal_send_command(new Command('client', arr, callback, call_on_write)); +}; + +Multi.prototype.client = Multi.prototype.CLIENT = function client () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0]; + callback = arguments[1]; + } else if (Array.isArray(arguments[1])) { + if (len === 3) { + callback = arguments[2]; + } + len = arguments[1].length; + arr = new Array(len + 1); + arr[0] = arguments[0]; + for (; i < len; i += 1) { + arr[i + 1] = arguments[1][i]; + } + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this._client; + var call_on_write = undefined; + // CLIENT REPLY ON|OFF|SKIP + /* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */ + if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') { + var reply_on_off = arr[1].toString().toUpperCase(); + if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') { + call_on_write = function () { + self.reply = reply_on_off; + }; + } + } + this.queue.push(new Command('client', arr, callback, call_on_write)); + return this; +}; + +RedisClient.prototype.hmset = RedisClient.prototype.HMSET = function hmset () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0]; + callback = arguments[1]; + } else if (Array.isArray(arguments[1])) { + if (len === 3) { + callback = arguments[2]; + } + len = arguments[1].length; + arr = new Array(len + 1); + arr[0] = arguments[0]; + for (; i < len; i += 1) { + arr[i + 1] = arguments[1][i]; + } + } else if (typeof arguments[1] === 'object' && (arguments.length === 2 || arguments.length === 3 && (typeof arguments[2] === 'function' || typeof arguments[2] === 'undefined'))) { + arr = [arguments[0]]; + for (var field in arguments[1]) { + arr.push(field, arguments[1][field]); + } + callback = arguments[2]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + return this.internal_send_command(new Command('hmset', arr, callback)); +}; + +Multi.prototype.hmset = Multi.prototype.HMSET = function hmset () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0]; + callback = arguments[1]; + } else if (Array.isArray(arguments[1])) { + if (len === 3) { + callback = arguments[2]; + } + len = arguments[1].length; + arr = new Array(len + 1); + arr[0] = arguments[0]; + for (; i < len; i += 1) { + arr[i + 1] = arguments[1][i]; + } + } else if (typeof arguments[1] === 'object' && (arguments.length === 2 || arguments.length === 3 && (typeof arguments[2] === 'function' || typeof arguments[2] === 'undefined'))) { + arr = [arguments[0]]; + for (var field in arguments[1]) { + arr.push(field, arguments[1][field]); + } + callback = arguments[2]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + this.queue.push(new Command('hmset', arr, callback)); + return this; +}; + +RedisClient.prototype.subscribe = RedisClient.prototype.SUBSCRIBE = function subscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this; + var call_on_write = function () { + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + return this.internal_send_command(new Command('subscribe', arr, callback, call_on_write)); +}; + +Multi.prototype.subscribe = Multi.prototype.SUBSCRIBE = function subscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this._client; + var call_on_write = function () { + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + this.queue.push(new Command('subscribe', arr, callback, call_on_write)); + return this; +}; + +RedisClient.prototype.unsubscribe = RedisClient.prototype.UNSUBSCRIBE = function unsubscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this; + var call_on_write = function () { + // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + return this.internal_send_command(new Command('unsubscribe', arr, callback, call_on_write)); +}; + +Multi.prototype.unsubscribe = Multi.prototype.UNSUBSCRIBE = function unsubscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this._client; + var call_on_write = function () { + // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + this.queue.push(new Command('unsubscribe', arr, callback, call_on_write)); + return this; +}; + +RedisClient.prototype.psubscribe = RedisClient.prototype.PSUBSCRIBE = function psubscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this; + var call_on_write = function () { + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + return this.internal_send_command(new Command('psubscribe', arr, callback, call_on_write)); +}; + +Multi.prototype.psubscribe = Multi.prototype.PSUBSCRIBE = function psubscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this._client; + var call_on_write = function () { + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + this.queue.push(new Command('psubscribe', arr, callback, call_on_write)); + return this; +}; + +RedisClient.prototype.punsubscribe = RedisClient.prototype.PUNSUBSCRIBE = function punsubscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this; + var call_on_write = function () { + // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + return this.internal_send_command(new Command('punsubscribe', arr, callback, call_on_write)); +}; + +Multi.prototype.punsubscribe = Multi.prototype.PUNSUBSCRIBE = function punsubscribe () { + var arr, + len = arguments.length, + callback, + i = 0; + if (Array.isArray(arguments[0])) { + arr = arguments[0].slice(0); + callback = arguments[1]; + } else { + len = arguments.length; + // The later should not be the average use case + if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) { + len--; + callback = arguments[len]; + } + arr = new Array(len); + for (; i < len; i += 1) { + arr[i] = arguments[i]; + } + } + var self = this._client; + var call_on_write = function () { + // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback + self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; + }; + this.queue.push(new Command('punsubscribe', arr, callback, call_on_write)); + return this; +}; diff --git a/nodejs/node_modules/redis/lib/multi.js b/nodejs/node_modules/redis/lib/multi.js new file mode 100755 index 0000000..63f5d21 --- /dev/null +++ b/nodejs/node_modules/redis/lib/multi.js @@ -0,0 +1,187 @@ +'use strict'; + +var Queue = require('double-ended-queue'); +var utils = require('./utils'); +var Command = require('./command'); + +function Multi (client, args) { + this._client = client; + this.queue = new Queue(); + var command, tmp_args; + if (args) { // Either undefined or an array. Fail hard if it's not an array + for (var i = 0; i < args.length; i++) { + command = args[i][0]; + tmp_args = args[i].slice(1); + if (Array.isArray(command)) { + this[command[0]].apply(this, command.slice(1).concat(tmp_args)); + } else { + this[command].apply(this, tmp_args); + } + } + } +} + +function pipeline_transaction_command (self, command_obj, index) { + // Queueing is done first, then the commands are executed + var tmp = command_obj.callback; + command_obj.callback = function (err, reply) { + // Ignore the multi command. This is applied by node_redis and the user does not benefit by it + if (err && index !== -1) { + if (tmp) { + tmp(err); + } + err.position = index; + self.errors.push(err); + } + // Keep track of who wants buffer responses: + // By the time the callback is called the command_obj got the buffer_args attribute attached + self.wants_buffers[index] = command_obj.buffer_args; + command_obj.callback = tmp; + }; + self._client.internal_send_command(command_obj); +} + +Multi.prototype.exec_atomic = Multi.prototype.EXEC_ATOMIC = Multi.prototype.execAtomic = function exec_atomic (callback) { + if (this.queue.length < 2) { + return this.exec_batch(callback); + } + return this.exec(callback); +}; + +function multi_callback (self, err, replies) { + var i = 0, command_obj; + + if (err) { + err.errors = self.errors; + if (self.callback) { + self.callback(err); + // Exclude connection errors so that those errors won't be emitted twice + } else if (err.code !== 'CONNECTION_BROKEN') { + self._client.emit('error', err); + } + return; + } + + if (replies) { + while (command_obj = self.queue.shift()) { + if (replies[i] instanceof Error) { + var match = replies[i].message.match(utils.err_code); + // LUA script could return user errors that don't behave like all other errors! + if (match) { + replies[i].code = match[1]; + } + replies[i].command = command_obj.command.toUpperCase(); + if (typeof command_obj.callback === 'function') { + command_obj.callback(replies[i]); + } + } else { + // If we asked for strings, even in detect_buffers mode, then return strings: + replies[i] = self._client.handle_reply(replies[i], command_obj.command, self.wants_buffers[i]); + if (typeof command_obj.callback === 'function') { + command_obj.callback(null, replies[i]); + } + } + i++; + } + } + + if (self.callback) { + self.callback(null, replies); + } +} + +Multi.prototype.exec_transaction = function exec_transaction (callback) { + if (this.monitoring || this._client.monitoring) { + var err = new RangeError( + 'Using transaction with a client that is in monitor mode does not work due to faulty return values of Redis.' + ); + err.command = 'EXEC'; + err.code = 'EXECABORT'; + return utils.reply_in_order(this._client, callback, err); + } + var self = this; + var len = self.queue.length; + self.errors = []; + self.callback = callback; + self._client.cork(); + self.wants_buffers = new Array(len); + pipeline_transaction_command(self, new Command('multi', []), -1); + // Drain queue, callback will catch 'QUEUED' or error + for (var index = 0; index < len; index++) { + // The commands may not be shifted off, since they are needed in the result handler + pipeline_transaction_command(self, self.queue.get(index), index); + } + + self._client.internal_send_command(new Command('exec', [], function (err, replies) { + multi_callback(self, err, replies); + })); + self._client.uncork(); + return !self._client.should_buffer; +}; + +function batch_callback (self, cb, i) { + return function batch_callback (err, res) { + if (err) { + self.results[i] = err; + // Add the position to the error + self.results[i].position = i; + } else { + self.results[i] = res; + } + cb(err, res); + }; +} + +Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = function exec_batch (callback) { + var self = this; + var len = self.queue.length; + var index = 0; + var command_obj; + if (len === 0) { + utils.reply_in_order(self._client, callback, null, []); + return !self._client.should_buffer; + } + self._client.cork(); + if (!callback) { + while (command_obj = self.queue.shift()) { + self._client.internal_send_command(command_obj); + } + self._client.uncork(); + return !self._client.should_buffer; + } + var callback_without_own_cb = function (err, res) { + if (err) { + self.results.push(err); + // Add the position to the error + var i = self.results.length - 1; + self.results[i].position = i; + } else { + self.results.push(res); + } + // Do not emit an error here. Otherwise each error would result in one emit. + // The errors will be returned in the result anyway + }; + var last_callback = function (cb) { + return function (err, res) { + cb(err, res); + callback(null, self.results); + }; + }; + self.results = []; + while (command_obj = self.queue.shift()) { + if (typeof command_obj.callback === 'function') { + command_obj.callback = batch_callback(self, command_obj.callback, index); + } else { + command_obj.callback = callback_without_own_cb; + } + if (typeof callback === 'function' && index === len - 1) { + command_obj.callback = last_callback(command_obj.callback); + } + this._client.internal_send_command(command_obj); + index++; + } + self._client.uncork(); + return !self._client.should_buffer; +}; + +module.exports = Multi; diff --git a/nodejs/node_modules/redis/lib/utils.js b/nodejs/node_modules/redis/lib/utils.js new file mode 100755 index 0000000..52e58ec --- /dev/null +++ b/nodejs/node_modules/redis/lib/utils.js @@ -0,0 +1,134 @@ +'use strict'; + +// hgetall converts its replies to an Object. If the reply is empty, null is returned. +// These function are only called with internal data and have therefore always the same instanceof X +function replyToObject (reply) { + // The reply might be a string or a buffer if this is called in a transaction (multi) + if (reply.length === 0 || !(reply instanceof Array)) { + return null; + } + var obj = {}; + for (var i = 0; i < reply.length; i += 2) { + obj[reply[i].toString('binary')] = reply[i + 1]; + } + return obj; +} + +function replyToStrings (reply) { + if (reply instanceof Buffer) { + return reply.toString(); + } + if (reply instanceof Array) { + var res = new Array(reply.length); + for (var i = 0; i < reply.length; i++) { + // Recusivly call the function as slowlog returns deep nested replies + res[i] = replyToStrings(reply[i]); + } + return res; + } + + return reply; +} + +function print (err, reply) { + if (err) { + // A error always begins with Error: + console.log(err.toString()); + } else { + console.log('Reply: ' + reply); + } +} + +var camelCase; +// Deep clone arbitrary objects with arrays. Can't handle cyclic structures (results in a range error) +// Any attribute with a non primitive value besides object and array will be passed by reference (e.g. Buffers, Maps, Functions) +// All capital letters are going to be replaced with a lower case letter and a underscore infront of it +function clone (obj) { + var copy; + if (Array.isArray(obj)) { + copy = new Array(obj.length); + for (var i = 0; i < obj.length; i++) { + copy[i] = clone(obj[i]); + } + return copy; + } + if (Object.prototype.toString.call(obj) === '[object Object]') { + copy = {}; + var elems = Object.keys(obj); + var elem; + while (elem = elems.pop()) { + if (elem === 'tls') { // special handle tls + copy[elem] = obj[elem]; + continue; + } + // Accept camelCase options and convert them to snake_case + var snake_case = elem.replace(/[A-Z][^A-Z]/g, '_$&').toLowerCase(); + // If camelCase is detected, pass it to the client, so all variables are going to be camelCased + // There are no deep nested options objects yet, but let's handle this future proof + if (snake_case !== elem.toLowerCase()) { + camelCase = true; + } + copy[snake_case] = clone(obj[elem]); + } + return copy; + } + return obj; +} + +function convenienceClone (obj) { + camelCase = false; + obj = clone(obj) || {}; + if (camelCase) { + obj.camel_case = true; + } + return obj; +} + +function callbackOrEmit (self, callback, err, res) { + if (callback) { + callback(err, res); + } else if (err) { + self.emit('error', err); + } +} + +function replyInOrder (self, callback, err, res, queue) { + // If the queue is explicitly passed, use that, otherwise fall back to the offline queue first, + // as there might be commands in both queues at the same time + var command_obj; + /* istanbul ignore if: TODO: Remove this as soon as we test Redis 3.2 on travis */ + if (queue) { + command_obj = queue.peekBack(); + } else { + command_obj = self.offline_queue.peekBack() || self.command_queue.peekBack(); + } + if (!command_obj) { + process.nextTick(function () { + callbackOrEmit(self, callback, err, res); + }); + } else { + var tmp = command_obj.callback; + command_obj.callback = tmp ? + function (e, r) { + tmp(e, r); + callbackOrEmit(self, callback, err, res); + } : + function (e, r) { + if (e) { + self.emit('error', e); + } + callbackOrEmit(self, callback, err, res); + }; + } +} + +module.exports = { + reply_to_strings: replyToStrings, + reply_to_object: replyToObject, + print: print, + err_code: /^([A-Z]+)\s+(.+)$/, + monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\]( ".+?")+$/, + clone: convenienceClone, + callback_or_emit: callbackOrEmit, + reply_in_order: replyInOrder +}; diff --git a/nodejs/node_modules/redis/package.json b/nodejs/node_modules/redis/package.json new file mode 100755 index 0000000..12f9991 --- /dev/null +++ b/nodejs/node_modules/redis/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + "redis@2.8.0", + "/www/wwwroot/Adminx.cc/nodejs" + ] + ], + "_from": "redis@2.8.0", + "_id": "redis@2.8.0", + "_inBundle": false, + "_integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "_location": "/redis", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "redis@2.8.0", + "name": "redis", + "escapedName": "redis", + "rawSpec": "2.8.0", + "saveSpec": null, + "fetchSpec": "2.8.0" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "_spec": "2.8.0", + "_where": "/www/wwwroot/Adminx.cc/nodejs", + "author": { + "name": "Matt Ranney", + "email": "mjr@ranney.com" + }, + "bugs": { + "url": "https://github.com/NodeRedis/node_redis/issues" + }, + "dependencies": { + "double-ended-queue": "^2.1.0-0", + "redis-commands": "^1.2.0", + "redis-parser": "^2.6.0" + }, + "description": "Redis client library", + "devDependencies": { + "bluebird": "^3.0.2", + "coveralls": "^2.11.2", + "eslint": "^4.2.0", + "intercept-stdout": "~0.1.2", + "metrics": "^0.1.9", + "mocha": "^3.1.2", + "nyc": "^10.0.0", + "tcp-port-used": "^0.1.2", + "uuid": "^2.0.1", + "win-spawn": "^2.0.0" + }, + "directories": { + "example": "examples", + "test": "test" + }, + "engines": { + "node": ">=0.10.0" + }, + "homepage": "https://github.com/NodeRedis/node_redis", + "keywords": [ + "database", + "redis", + "transaction", + "pipelining", + "performance", + "queue", + "nodejs", + "pubsub", + "backpressure" + ], + "license": "MIT", + "main": "./index.js", + "name": "redis", + "repository": { + "type": "git", + "url": "git://github.com/NodeRedis/node_redis.git" + }, + "scripts": { + "benchmark": "node benchmarks/multi_bench.js", + "compare": "node benchmarks/diff_multi_bench_output.js beforeBench.txt afterBench.txt", + "coverage": "nyc report --reporter=html", + "coveralls": "nyc report --reporter=text-lcov | coveralls", + "lint": "eslint . --fix && npm run coverage", + "test": "nyc --cache mocha ./test/*.js ./test/commands/*.js --timeout=8000" + }, + "version": "2.8.0" +} diff --git a/nodejs/node_modules/sorted-array-functions/.travis.yml b/nodejs/node_modules/sorted-array-functions/.travis.yml new file mode 100755 index 0000000..1fc99b1 --- /dev/null +++ b/nodejs/node_modules/sorted-array-functions/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - '0.10' + - '0.12' + - '4' + - '6' diff --git a/nodejs/node_modules/sorted-array-functions/LICENSE b/nodejs/node_modules/sorted-array-functions/LICENSE new file mode 100755 index 0000000..bae9da7 --- /dev/null +++ b/nodejs/node_modules/sorted-array-functions/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Mathias Buus + +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/nodejs/node_modules/sorted-array-functions/README.md b/nodejs/node_modules/sorted-array-functions/README.md new file mode 100755 index 0000000..4cafc3a --- /dev/null +++ b/nodejs/node_modules/sorted-array-functions/README.md @@ -0,0 +1,71 @@ +# sorted-array-functions + +Maintain and search through a sorted array using some low level functions + +``` +npm install sorted-array-functions +``` + +[![build status](http://img.shields.io/travis/mafintosh/sorted-array-functions.svg?style=flat)](http://travis-ci.org/mafintosh/sorted-array-functions) + +## Usage + +``` js +var sorted = require('sorted-array-functions') +var list = [] + +sorted.add(list, 1) +sorted.add(list, 4) +sorted.add(list, 2) + +console.log(list) // prints out [1, 2, 4] +console.log(sorted.has(list, 2)) // returns true +console.log(sorted.has(list, 3)) // returns false +console.log(sorted.eq(list, 2)) // returns 1 (the index) +console.log(sorted.gt(list, 2)) // returns 2 +console.log(sorted.gt(list, 4)) // returns -1 +``` + +## API + +#### `sorted.add(list, value, [compare])` + +Insert a new value into the list sorted. +Optionally you can use a custom compare function that returns, `compare(a, b)` that returns 1 if `a > b`, 0 if `a === b` and -1 if `a < b`. + +#### `var bool = sorted.remove(list, value, [compare])` + +Remove a value. Returns true if the value was in the list. + +#### `var bool = sorted.has(list, value, [compare])` + +Check if a value is in the list. + +#### `var index = sorted.eq(list, value, [compare])` + +Get the index of a value in the list (uses binary search). +If the value could not be found -1 is returned. + +#### `var index = sorted.gte(list, value, [compare])` + +Get the index of the first value that is `>=`. +If the value could not be found -1 is returned. + +#### `var index = sorted.gt(list, value, [compare])` + +Get the index of the first value that is `>`. +If the value could not be found -1 is returned. + +#### `var index = sorted.lte(list, value, [compare])` + +Get the index of the first value that is `<=`. +If the value could not be found -1 is returned. + +#### `var index = sorted.lt(list, value, [compare])` + +Get the index of the first value that is `<`. +If the value could not be found -1 is returned. + +## License + +MIT diff --git a/nodejs/node_modules/sorted-array-functions/example.js b/nodejs/node_modules/sorted-array-functions/example.js new file mode 100755 index 0000000..c06b733 --- /dev/null +++ b/nodejs/node_modules/sorted-array-functions/example.js @@ -0,0 +1,13 @@ +var sorted = require('./') +var list = [] + +sorted.add(list, 1) +sorted.add(list, 4) +sorted.add(list, 2) + +console.log(list) // prints out [1, 2, 4] +console.log(sorted.has(list, 2)) // returns true +console.log(sorted.has(list, 3)) // returns false +console.log(sorted.eq(list, 2)) // returns 1 (the index) +console.log(sorted.gt(list, 2)) // returns 2 +console.log(sorted.gt(list, 4)) // returns -1 diff --git a/nodejs/node_modules/sorted-array-functions/index.js b/nodejs/node_modules/sorted-array-functions/index.js new file mode 100755 index 0000000..3a0dc06 --- /dev/null +++ b/nodejs/node_modules/sorted-array-functions/index.js @@ -0,0 +1,160 @@ +exports.add = add +exports.remove = remove +exports.has = has +exports.eq = eq +exports.lte = lte +exports.lt = lt +exports.gte = gte +exports.gt = gt +exports.nearest = nearest + +function defaultCmp (a, b) { + if (a === b) return 0 + return a > b ? 1 : -1 +} + +function add (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var top = list.push(value) - 1 + + while (top) { + if (cmp(list[top - 1], value) < 0) return + list[top] = list[top - 1] + list[top - 1] = value + top-- + } +} + +function lte (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var i = indexOf(list, value, cmp) + if (i === -1) return -1 + + for (; i >= 0; i--) { + var c = cmp(list[i], value) + if (c <= 0) return i + } + + return -1 +} + +function lt (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var i = indexOf(list, value, cmp) + if (i === -1) return -1 + + for (; i >= 0; i--) { + var c = cmp(list[i], value) + if (c < 0) return i + } + + return -1 +} + +function gte (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var i = indexOf(list, value, cmp) + if (i === -1) return -1 + + for (; i < list.length; i++) { + var c = cmp(list[i], value) + if (c >= 0) return i + } + + return -1 +} + +function gt (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var i = indexOf(list, value, cmp) + if (i === -1) return -1 + + for (; i < list.length; i++) { + var c = cmp(list[i], value) + if (c > 0) return i + } + + return -1 +} + +function eq (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var i = indexOf(list, value, cmp) + if (i === -1) return -1 + return cmp(list[i], value) === 0 ? i : -1 +} + +function nearest (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var len = list.length + var top = len - 1 + var btm = 0 + var mid = -1 + var trending = 1 // 0 = down, 2 = up + + while (top >= btm && btm >= 0 && top < len) { + mid = Math.floor((top + btm) / 2) + + var c = cmp(list[mid], value) + if (c === 0) return mid + + if (c >= 0) { + if (trending === 1) trending = 0 + else if (trending === 2) { + if (Math.abs(list[mid] - value) > Math.abs(list[mid - 1] - value)) return mid - 1 + return mid + } + + top = mid - 1 + } else { + if (trending === 1) trending = 2 + else if (trending === 0) return mid + + btm = mid + 1 + } + } + + return mid +} + +function indexOf (list, value, cmp) { + if (!cmp) cmp = defaultCmp + + var len = list.length + var top = len - 1 + var btm = 0 + var mid = -1 + + while (top >= btm && btm >= 0 && top < len) { + mid = Math.floor((top + btm) / 2) + + var c = cmp(list[mid], value) + if (c === 0) return mid + + if (c >= 0) { + top = mid - 1 + } else { + btm = mid + 1 + } + } + + return mid +} + +function has (list, value, cmp) { + return eq(list, value, cmp) > -1 +} + +function remove (list, value, cmp) { + var i = eq(list, value, cmp) + if (i === -1) return false + list.splice(i, 1) + return true +} diff --git a/nodejs/node_modules/sorted-array-functions/package.json b/nodejs/node_modules/sorted-array-functions/package.json new file mode 100755 index 0000000..2276cb4 --- /dev/null +++ b/nodejs/node_modules/sorted-array-functions/package.json @@ -0,0 +1,55 @@ +{ + "_args": [ + [ + "sorted-array-functions@1.2.0", + "/www/wwwroot/Adminx.cc/nodejs" + ] + ], + "_from": "sorted-array-functions@1.2.0", + "_id": "sorted-array-functions@1.2.0", + "_inBundle": false, + "_integrity": "sha512-sWpjPhIZJtqO77GN+LD8dDsDKcWZ9GCOJNqKzi1tvtjGIzwfoyuRH8S0psunmc6Z5P+qfDqztSbwYR5X/e1UTg==", + "_location": "/sorted-array-functions", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "sorted-array-functions@1.2.0", + "name": "sorted-array-functions", + "escapedName": "sorted-array-functions", + "rawSpec": "1.2.0", + "saveSpec": null, + "fetchSpec": "1.2.0" + }, + "_requiredBy": [ + "/node-schedule" + ], + "_resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.2.0.tgz", + "_spec": "1.2.0", + "_where": "/www/wwwroot/Adminx.cc/nodejs", + "author": { + "name": "Mathias Buus", + "url": "@mafintosh" + }, + "bugs": { + "url": "https://github.com/mafintosh/sorted-array-functions/issues" + }, + "dependencies": {}, + "description": "Maintain and search through a sorted array using some low level functions", + "devDependencies": { + "standard": "^8.4.0", + "tape": "^4.6.2" + }, + "homepage": "https://github.com/mafintosh/sorted-array-functions", + "license": "MIT", + "main": "index.js", + "name": "sorted-array-functions", + "repository": { + "type": "git", + "url": "git+https://github.com/mafintosh/sorted-array-functions.git" + }, + "scripts": { + "test": "standard && tape test.js" + }, + "version": "1.2.0" +} diff --git a/nodejs/node_modules/sorted-array-functions/test.js b/nodejs/node_modules/sorted-array-functions/test.js new file mode 100755 index 0000000..0125aa0 --- /dev/null +++ b/nodejs/node_modules/sorted-array-functions/test.js @@ -0,0 +1,366 @@ +var tape = require('tape') +var sorted = require('./') + +tape('add', function (t) { + var list = [] + + sorted.add(list, 3) + sorted.add(list, 4) + sorted.add(list, 3) + sorted.add(list, 9) + sorted.add(list, 0) + sorted.add(list, 5) + sorted.add(list, 8) + + t.same(list, [0, 3, 3, 4, 5, 8, 9]) + t.end() +}) + +tape('remove', function (t) { + var list = [] + + sorted.add(list, 3) + sorted.add(list, 4) + sorted.add(list, 3) + sorted.add(list, 9) + sorted.add(list, 0) + sorted.add(list, 5) + sorted.add(list, 8) + + sorted.remove(list, 3) + sorted.remove(list, 5) + sorted.remove(list, 6) + + t.same(list, [0, 3, 4, 8, 9]) + t.end() +}) + +tape('has', function (t) { + var list = [] + + sorted.add(list, 3) + t.same(sorted.has(list, 3), true) + t.same(sorted.has(list, 2), false) + + sorted.add(list, 5) + t.same(sorted.has(list, 5), true) + t.same(sorted.has(list, 3), true) + t.same(sorted.has(list, 2), false) + + sorted.add(list, 1) + t.same(sorted.has(list, 1), true) + t.same(sorted.has(list, 5), true) + t.same(sorted.has(list, 3), true) + t.same(sorted.has(list, 2), false) + t.same(sorted.has(list, 8), false) + + t.end() +}) + +tape('eq', function (t) { + var list = [] + + sorted.add(list, 3) + t.same(sorted.eq(list, 3), 0) + t.same(sorted.eq(list, 2), -1) + + sorted.add(list, 5) + t.same(sorted.eq(list, 5), 1) + t.same(sorted.eq(list, 3), 0) + t.same(sorted.eq(list, 2), -1) + + sorted.add(list, 1) + t.same(sorted.eq(list, 1), 0) + t.same(sorted.eq(list, 5), 2) + t.same(sorted.eq(list, 3), 1) + t.same(sorted.eq(list, 2), -1) + t.same(sorted.eq(list, 8), -1) + + t.end() +}) + +tape('gte', function (t) { + var list = [] + + sorted.add(list, 3) + t.same(sorted.gte(list, 3), 0) + t.same(sorted.gte(list, 2), 0) + + sorted.add(list, 5) + t.same(sorted.gte(list, 5), 1) + t.same(sorted.gte(list, 3), 0) + t.same(sorted.gte(list, 2), 0) + + sorted.add(list, 1) + t.same(sorted.gte(list, 1), 0) + t.same(sorted.gte(list, 5), 2) + t.same(sorted.gte(list, 3), 1) + t.same(sorted.gte(list, 2), 1) + t.same(sorted.gte(list, 8), -1) + + t.end() +}) + +tape('gt', function (t) { + var list = [] + + sorted.add(list, 3) + t.same(sorted.gt(list, 3), -1) + t.same(sorted.gt(list, 2), 0) + + sorted.add(list, 5) + t.same(sorted.gt(list, 5), -1) + t.same(sorted.gt(list, 3), 1) + t.same(sorted.gt(list, 2), 0) + + sorted.add(list, 1) + t.same(sorted.gt(list, 1), 1) + t.same(sorted.gt(list, 5), -1) + t.same(sorted.gt(list, 3), 2) + t.same(sorted.gt(list, 2), 1) + t.same(sorted.gt(list, 8), -1) + + t.end() +}) + +tape('lte', function (t) { + var list = [] + + sorted.add(list, 3) + t.same(sorted.lte(list, 3), 0) + t.same(sorted.lte(list, 2), -1) + + sorted.add(list, 5) + t.same(sorted.lte(list, 6), 1) + t.same(sorted.lte(list, 5), 1) + t.same(sorted.lte(list, 3), 0) + t.same(sorted.lte(list, 2), -1) + + sorted.add(list, 1) + t.same(sorted.lte(list, 1), 0) + t.same(sorted.lte(list, 5), 2) + t.same(sorted.lte(list, 3), 1) + t.same(sorted.lte(list, 2), 0) + t.same(sorted.lte(list, 8), 2) + + t.end() +}) + +tape('lt', function (t) { + var list = [] + + sorted.add(list, 3) + t.same(sorted.lt(list, 3), -1) + t.same(sorted.lt(list, 2), -1) + t.same(sorted.lt(list, 4), 0) + + sorted.add(list, 5) + t.same(sorted.lt(list, 6), 1) + t.same(sorted.lt(list, 5), 0) + t.same(sorted.lt(list, 3), -1) + t.same(sorted.lt(list, 2), -1) + + sorted.add(list, 1) + t.same(sorted.lt(list, 1), -1) + t.same(sorted.lt(list, 5), 1) + t.same(sorted.lt(list, 3), 0) + t.same(sorted.lt(list, 2), 0) + t.same(sorted.lt(list, 8), 2) + + t.end() +}) + +tape('custom compare add', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + sorted.add(list, {foo: 4}, cmp) + sorted.add(list, {foo: 3}, cmp) + sorted.add(list, {foo: 9}, cmp) + sorted.add(list, {foo: 0}, cmp) + sorted.add(list, {foo: 5}, cmp) + sorted.add(list, {foo: 8}, cmp) + + t.same(list, [{foo: 0}, {foo: 3}, {foo: 3}, {foo: 4}, {foo: 5}, {foo: 8}, {foo: 9}]) + t.end() +}) + +tape('custom compare remove', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + sorted.add(list, {foo: 4}, cmp) + sorted.add(list, {foo: 3}, cmp) + sorted.add(list, {foo: 9}, cmp) + sorted.add(list, {foo: 0}, cmp) + sorted.add(list, {foo: 5}, cmp) + sorted.add(list, {foo: 8}, cmp) + + sorted.remove(list, {foo: 3}, cmp) + sorted.remove(list, {foo: 5}, cmp) + sorted.remove(list, {foo: 6}, cmp) + + t.same(list, [{foo: 0}, {foo: 3}, {foo: 4}, {foo: 8}, {foo: 9}]) + t.end() +}) + +tape('custom compare has', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + t.same(sorted.has(list, {foo: 3}, cmp), true) + t.same(sorted.has(list, {foo: 2}, cmp), false) + + sorted.add(list, {foo: 5}, cmp) + t.same(sorted.has(list, {foo: 5}, cmp), true) + t.same(sorted.has(list, {foo: 3}, cmp), true) + t.same(sorted.has(list, {foo: 2}, cmp), false) + + sorted.add(list, {foo: 1}, cmp) + t.same(sorted.has(list, {foo: 1}, cmp), true) + t.same(sorted.has(list, {foo: 5}, cmp), true) + t.same(sorted.has(list, {foo: 3}, cmp), true) + t.same(sorted.has(list, {foo: 2}, cmp), false) + t.same(sorted.has(list, {foo: 8}, cmp), false) + + t.end() +}) + +tape('custom compare eq', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + t.same(sorted.eq(list, {foo: 3}, cmp), 0) + t.same(sorted.eq(list, {foo: 2}, cmp), -1) + + sorted.add(list, {foo: 5}, cmp) + t.same(sorted.eq(list, {foo: 5}, cmp), 1) + t.same(sorted.eq(list, {foo: 3}, cmp), 0) + t.same(sorted.eq(list, {foo: 2}, cmp), -1) + + sorted.add(list, {foo: 1}, cmp) + t.same(sorted.eq(list, {foo: 1}, cmp), 0) + t.same(sorted.eq(list, {foo: 5}, cmp), 2) + t.same(sorted.eq(list, {foo: 3}, cmp), 1) + t.same(sorted.eq(list, {foo: 2}, cmp), -1) + t.same(sorted.eq(list, {foo: 8}, cmp), -1) + + t.end() +}) + +tape('custom compare gte', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + t.same(sorted.gte(list, {foo: 3}, cmp), 0) + t.same(sorted.gte(list, {foo: 2}, cmp), 0) + + sorted.add(list, {foo: 5}, cmp) + t.same(sorted.gte(list, {foo: 5}, cmp), 1) + t.same(sorted.gte(list, {foo: 3}, cmp), 0) + t.same(sorted.gte(list, {foo: 2}, cmp), 0) + + sorted.add(list, {foo: 1}, cmp) + t.same(sorted.gte(list, {foo: 1}, cmp), 0) + t.same(sorted.gte(list, {foo: 5}, cmp), 2) + t.same(sorted.gte(list, {foo: 3}, cmp), 1) + t.same(sorted.gte(list, {foo: 2}, cmp), 1) + t.same(sorted.gte(list, {foo: 8}, cmp), -1) + + t.end() +}) + +tape('custom compare gt', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + t.same(sorted.gt(list, {foo: 3}, cmp), -1) + t.same(sorted.gt(list, {foo: 2}, cmp), 0) + + sorted.add(list, {foo: 5}, cmp) + t.same(sorted.gt(list, {foo: 5}, cmp), -1) + t.same(sorted.gt(list, {foo: 3}, cmp), 1) + t.same(sorted.gt(list, {foo: 2}, cmp), 0) + + sorted.add(list, {foo: 1}, cmp) + t.same(sorted.gt(list, {foo: 1}, cmp), 1) + t.same(sorted.gt(list, {foo: 5}, cmp), -1) + t.same(sorted.gt(list, {foo: 3}, cmp), 2) + t.same(sorted.gt(list, {foo: 2}, cmp), 1) + t.same(sorted.gt(list, {foo: 8}, cmp), -1) + + t.end() +}) + +tape('custom compare lte', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + t.same(sorted.lte(list, {foo: 3}, cmp), 0) + t.same(sorted.lte(list, {foo: 2}, cmp), -1) + + sorted.add(list, {foo: 5}, cmp) + t.same(sorted.lte(list, {foo: 6}, cmp), 1) + t.same(sorted.lte(list, {foo: 5}, cmp), 1) + t.same(sorted.lte(list, {foo: 3}, cmp), 0) + t.same(sorted.lte(list, {foo: 2}, cmp), -1) + + sorted.add(list, {foo: 1}, cmp) + t.same(sorted.lte(list, {foo: 1}, cmp), 0) + t.same(sorted.lte(list, {foo: 5}, cmp), 2) + t.same(sorted.lte(list, {foo: 3}, cmp), 1) + t.same(sorted.lte(list, {foo: 2}, cmp), 0) + t.same(sorted.lte(list, {foo: 8}, cmp), 2) + + t.end() +}) + +tape('custom compare lt', function (t) { + var list = [] + + sorted.add(list, {foo: 3}, cmp) + t.same(sorted.lt(list, {foo: 3}, cmp), -1) + t.same(sorted.lt(list, {foo: 2}, cmp), -1) + t.same(sorted.lt(list, {foo: 4}, cmp), 0) + + sorted.add(list, {foo: 5}, cmp) + t.same(sorted.lt(list, {foo: 6}, cmp), 1) + t.same(sorted.lt(list, {foo: 5}, cmp), 0) + t.same(sorted.lt(list, {foo: 3}, cmp), -1) + t.same(sorted.lt(list, {foo: 2}, cmp), -1) + + sorted.add(list, {foo: 1}, cmp) + t.same(sorted.lt(list, {foo: 1}, cmp), -1) + t.same(sorted.lt(list, {foo: 5}, cmp), 1) + t.same(sorted.lt(list, {foo: 3}, cmp), 0) + t.same(sorted.lt(list, {foo: 2}, cmp), 0) + t.same(sorted.lt(list, {foo: 8}, cmp), 2) + + t.end() +}) + +tape('find nearest value', function (t) { + var list = [] + + sorted.add(list, 0.001) + sorted.add(list, 10) + sorted.add(list, 20) + sorted.add(list, 30) + sorted.add(list, 40) + sorted.add(list, 50) + sorted.add(list, 70) + + t.equal(sorted.nearest(list, 66), 6) + t.equal(sorted.nearest(list, 51), 5) + t.equal(sorted.nearest(list, 1), 0) + t.equal(sorted.nearest(list, 0), 0) + t.equal(sorted.nearest(list, 69.999), 6) + t.equal(sorted.nearest(list, 72), 6) + + t.end() +}) + +function cmp (a, b) { + return a.foo - b.foo +} + diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json new file mode 100755 index 0000000..1e92bd0 --- /dev/null +++ b/nodejs/package-lock.json @@ -0,0 +1,94 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "cron-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-2.6.0.tgz", + "integrity": "sha512-KGfDDTjBIx85MnVYcdhLccoJH/7jcYW+5Z/t3Wsg2QlJhmmjf+97z+9sQftS71lopOYYapjEKEvmWaCsym5Z4g==", + "requires": { + "is-nan": "^1.2.1", + "moment-timezone": "^0.5.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, + "is-nan": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.2.1.tgz", + "integrity": "sha1-n69ltvttskt/XAYoR16nH5iEAeI=", + "requires": { + "define-properties": "^1.1.1" + } + }, + "long-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=" + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + }, + "moment-timezone": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.23.tgz", + "integrity": "sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "node-schedule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-1.3.0.tgz", + "integrity": "sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A==", + "requires": { + "cron-parser": "^2.4.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.0.0" + } + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" + }, + "redis": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "requires": { + "double-ended-queue": "^2.1.0-0", + "redis-commands": "^1.2.0", + "redis-parser": "^2.6.0" + } + }, + "redis-commands": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.4.0.tgz", + "integrity": "sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==" + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" + }, + "sorted-array-functions": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.2.0.tgz", + "integrity": "sha512-sWpjPhIZJtqO77GN+LD8dDsDKcWZ9GCOJNqKzi1tvtjGIzwfoyuRH8S0psunmc6Z5P+qfDqztSbwYR5X/e1UTg==" + } + } +} diff --git a/nodejs/package.json b/nodejs/package.json new file mode 100755 index 0000000..43fa1c6 --- /dev/null +++ b/nodejs/package.json @@ -0,0 +1,87 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "async": { + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + }, + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "version": "2.6.1" + }, + "bignumber.js": { + "integrity": "sha1-8725mtUmihX8HwvtL7AY4mk/4jY=", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-3.1.2.tgz", + "version": "3.1.2" + }, + "core-util-is": { + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "version": "1.0.2" + }, + "double-ended-queue": { + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "version": "2.1.0-0" + }, + "inherits": { + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "version": "2.0.3" + }, + "isarray": { + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "version": "0.0.1" + }, + "lodash": { + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "version": "4.17.11" + }, + "mysql": { + "integrity": "sha1-mY8fjKRuLj3XFJzpgkE2U5hqrkc=", + "requires": { + "bignumber.js": "3.1.2", + "readable-stream": "1.1.14", + "sqlstring": "2.2.0" + }, + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.13.0.tgz", + "version": "2.13.0" + }, + "node-schedule": "^1.3.0", + "readable-stream": { + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "version": "1.1.14" + }, + "redis": "^2.8.0", + "redis-commands": { + "integrity": "sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.4.0.tgz", + "version": "1.4.0" + }, + "redis-parser": { + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "version": "2.6.0" + }, + "sqlstring": { + "integrity": "sha1-wxNcTqirzX5+50GklmqJHYak8ZE=", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.2.0.tgz", + "version": "2.2.0" + }, + "string_decoder": { + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "version": "0.10.31" + } + } +} diff --git a/public/.gitignore b/public/.gitignore new file mode 100644 index 0000000..0f076f9 --- /dev/null +++ b/public/.gitignore @@ -0,0 +1,2 @@ +.well-known +.user.ini \ No newline at end of file diff --git a/public/adminer.php b/public/adminer.php new file mode 100644 index 0000000..312dfe2 --- /dev/null +++ b/public/adminer.php @@ -0,0 +1,874 @@ +$W){unset($kf[$z][$od]);if(is_array($W)){$kf[$z][stripslashes($od)]=$W;$kf[]=&$kf[$z][stripslashes($od)];}else$kf[$z][stripslashes($od)]=($wc?$W:stripslashes($W));}}}}function +bracket_escape($v,$_a=false){static$Sg=array(':'=>':1',']'=>':2','['=>':3','"'=>':4');return +strtr($v,($_a?array_flip($Sg):$Sg));}function +min_version($uh,$Id="",$h=null){global$g;if(!$h)$h=$g;$Sf=$h->server_info;if($Id&&preg_match('~([\d.]+)-MariaDB~',$Sf,$C)){$Sf=$C[1];$uh=$Id;}return(version_compare($Sf,$uh)>=0);}function +charset($g){return(min_version("5.5.3",0,$g)?"utf8mb4":"utf8");}function +script($bg,$Rg="\n"){return"$bg$Rg";}function +script_src($kh){return"\n";}function +nonce(){return' nonce="'.get_nonce().'"';}function +target_blank(){return' target="_blank" rel="noreferrer noopener"';}function +h($lg){return +str_replace("\0","�",htmlspecialchars($lg,ENT_QUOTES,'utf-8'));}function +nl_br($lg){return +str_replace("\n","
        ",$lg);}function +checkbox($E,$Y,$Na,$sd="",$te="",$Ra="",$td=""){$K="".($te?script("qsl('input').onclick = function () { $te };",""):"");return($sd!=""||$Ra?"$K".h($sd)."":$K);}function +optionlist($xe,$Nf=null,$oh=false){$K="";foreach($xe +as$od=>$W){$ye=array($od=>$W);if(is_array($W)){$K.='';$ye=$W;}foreach($ye +as$z=>$X)$K.=''.h($X);if(is_array($W))$K.='';}return$K;}function +html_select($E,$xe,$Y="",$se=true,$td=""){if($se)return"".(is_string($se)?script("qsl('select').onchange = function () { $se };",""):"");$K="";foreach($xe +as$z=>$X)$K.="";return$K;}function +select_input($wa,$xe,$Y="",$se="",$Xe=""){$_g=($xe?"select":"input");return"<$_g$wa".($xe?">