diff --git a/application/app/controller/Card.php b/application/app/controller/Card.php index e9a0ef2..05c0261 100644 --- a/application/app/controller/Card.php +++ b/application/app/controller/Card.php @@ -88,7 +88,7 @@ class Card extends Base{ // 详细卡片信息 // $data = ['id'=>'2'] - public function card_data_detailed($data=['aud_id'=>'144']){ + public function card_data_detailed($data=['aud_id'=>'61']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -543,7 +543,9 @@ class Card extends Base{ "list"=>[], "key_name"=>"weight", "desc"=>"反映和衡量一个人健康状况的重要标志之一", - "offset"=>"0" + "offset"=>"0", + "standard_val"=>"", + "difference_val"=>"", ], [ "name"=>"身高", @@ -554,7 +556,9 @@ class Card extends Base{ "list"=>[], "key_name"=>"height", "desc"=>"人体纵向部分的长度,源于人体的纵向生长,受遗传因素的影响较大", - "offset"=>"0" + "offset"=>"0", + "standard_val"=>"", + "difference_val"=>"", ], [ "name"=>"BMI", @@ -565,7 +569,9 @@ class Card extends Base{ "list"=>[], "key_name"=>"bmi", "desc"=>"BMI是身体质量指数,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。", - "offset"=>"0" + "offset"=>"0", + "standard_val"=>"", + "difference_val"=>"", ], ], 'bottom_list' => [], @@ -660,12 +666,13 @@ class Card extends Base{ // 加入曲线板块底部的减肥计划数据end // 添加头围数据(如果有的话)start if($head_circumference !== false && $this->calculate_age($result[0]['birthday']) < 3){ + if($head_circumference['level'] == '异常' || $head_circumference['value'] == 0){ $offset = 0; }else{ $offset = $cardparts->calculate_landing_point($head_circumference['list2'],$head_circumference['value'],$head_circumference['level']); } - array_push($result_end['top_list'],[ + $touwei_array = [ 'name'=>'头围', 'value'=>$head_circumference['value'], 'unit'=>'CM', @@ -675,9 +682,56 @@ class Card extends Base{ 'key_name'=>'head_circumference', 'desc'=>'头围是指绕头部一周的最大长度,头围的大小与脑的发育密切相关', 'offset'=>$offset - ]); + ]; + $touwei_data = $this->touwei_temporary_use($result[0]['birthday'],$result[0]['gender']); + if(count($touwei_data)){ + $touwei_array['standard_val'] = $touwei_data['middle']; + $touwei_array['difference_val'] = bcsub($touwei_array['value'],$touwei_data['middle'],2); + }else{ + $touwei_array['standard_val'] = ''; + $touwei_array['difference_val'] = ''; + } + array_push($result_end['top_list'],$touwei_array); + } // 添加头围数据(如果有的话)end + + // 这段业务处理可以删除,是做的临时的,假的start + + $biaozhun_val = $this->body_temporary_use($result[0]['birthday'],$result[0]['gender']); + // dump($biaozhun_val); + // $biaozhun_val_weight = 50; + // $biaozhun_val_height = 170; + // $biaozhun_val_bmi = 22; + foreach ($result_end['top_list'] as $key => $value) { + if($value['key_name'] == 'weight'){ + if($biaozhun_val['weight'] == ''){ + $result_end['top_list'][$key]['standard_val'] = ''; + $result_end['top_list'][$key]['difference_val'] = ''; + }else{ + $result_end['top_list'][$key]['standard_val'] = $biaozhun_val['weight']; + $result_end['top_list'][$key]['difference_val'] = bcsub($value['value'],$biaozhun_val['weight'],2); + } + }else if($value['key_name'] == 'height'){ + if($biaozhun_val['height'] == ''){ + $result_end['top_list'][$key]['standard_val'] = ''; + $result_end['top_list'][$key]['difference_val'] = ''; + }else{ + $result_end['top_list'][$key]['standard_val'] = $biaozhun_val['height']; + $result_end['top_list'][$key]['difference_val'] = bcsub($value['value'],$biaozhun_val['height'],2); + } + }else if($value['key_name'] == 'bmi'){ + if($biaozhun_val['bmi'] == ''){ + $result_end['top_list'][$key]['standard_val'] = ''; + $result_end['top_list'][$key]['difference_val'] = ''; + }else{ + $result_end['top_list'][$key]['standard_val'] = $biaozhun_val['bmi']; + $result_end['top_list'][$key]['difference_val'] = bcsub($value['value'],$biaozhun_val['bmi'],2); + } + } + + } + // 这段业务处理可以删除,是做的临时的,假的end return $this->msg($result_end); } @@ -1253,6 +1307,174 @@ class Card extends Base{ ################################################################其他接口################################################################ ################################################################其他接口################################################################ + public function body_temporary_use($age,$gender){ + $return_data = [ + 'height'=>'', + 'weight'=>'', + 'bmi'=>'', + ]; + if(!in_array($gender,['1','2'])){ + return $return_data; + } + $age_m = $this->calculateAgeInMonthsWithPrecision($age); + if($age_m < 228){//月龄小于19岁 + // dump($age_m); + // $height_date = Db::table('ws_height')->where("age <= $age_m and gender = '$gender'")->order('age desc')->limit(1)->field('middle')->select(); + $height_date = Db::query("select * from ws_height where age <= $age_m and gender = '$gender' order by age desc"); + // $weight_date = Db::table('ws_weight')->where("age <= $month_num and Sex = '$gender'")->order('age desc')->limit(1)->field('middle')->select(); + $weight_date = Db::query("select * from ws_weight where age <= $age_m and gender = '$gender' order by age desc"); + // $bmi_date = Db::table('ws_bmi')->where("age <= $month_num and Sex = '$gender'")->order('age desc')->limit(1)->field('middle')->select(); + $bmi_date = Db::query("select * from ws_bmi where age <= $age_m and gender = '$gender' order by age desc"); + $return_data = array( + 'height' => $height_date[0]['middle'], + 'weight' => $weight_date[0]['middle'], + 'bmi' => $bmi_date[0]['middle'], + ); + }else{ + $bmi_data = [ + '1' => [ // 男性 + [ + 'age' => ['min' => 216, 'max' => 299], // 18-24岁(216-299月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '20.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '20.5', 'max_val' => '23.9', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.0', 'max_val' => '27.9', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.0', 'max_val' => '31.9', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.0', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 300, 'max' => 419], // 25-34岁(300-419月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '20.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.0', 'max_val' => '24.4', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.5', 'max_val' => '28.4', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.5', 'max_val' => '32.4', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.5', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 420, 'max' => 539], // 35-44岁(420-539月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '21.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.5', 'max_val' => '25.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '25.1', 'max_val' => '29.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '29.1', 'max_val' => '33.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '33.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 540, 'max' => 719], // 45-59岁(540-719月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '21.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '22.0', 'max_val' => '25.5', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '25.6', 'max_val' => '29.5', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '29.6', 'max_val' => '33.5', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '33.6', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 720, 'max' => '99999'], // ≥60岁(720+月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '22.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '22.5', 'max_val' => '26.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '26.1', 'max_val' => '29.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '29.1', 'max_val' => '33.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '33.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ] + ], + '2' => [ // 女性 + [ + 'age' => ['min' => 216, 'max' => 299], // 18-24岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '19.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '20.0', 'max_val' => '22.9', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '23.0', 'max_val' => '26.9', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '27.0', 'max_val' => '30.9', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '31.0', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 300, 'max' => 419], // 25-34岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '20.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '20.5', 'max_val' => '23.4', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '23.5', 'max_val' => '27.4', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '27.5', 'max_val' => '31.4', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '31.5', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 420, 'max' => 539], // 35-44岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '20.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.0', 'max_val' => '24.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.1', 'max_val' => '28.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.1', 'max_val' => '32.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 540, 'max' => 719], // 45-59岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '21.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.5', 'max_val' => '24.5', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.6', 'max_val' => '28.5', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.6', 'max_val' => '32.5', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.6', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 720, 'max' => 99999], // ≥60岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '21.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '22.0', 'max_val' => '25.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '25.1', 'max_val' => '28.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.1', 'max_val' => '32.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ] + ] + ]; + + foreach ($bmi_data[$gender] as $group) { + if ($age_m >= $group['age']['min'] && $age_m <= $group['age']['max']) { + $return_data['bmi'] = bcdiv(bcadd($group['list'][2]['min_val'],$group['list'][2]['max_val'],20),2,1); + } + } + + } + return $return_data; + } + public function touwei_temporary_use($age,$gender){ + $return_data = [ + + ]; + if(!in_array($gender,['1','2'])){ + return $return_data; + } + + $age_m = $this->calculateAgeInMonthsWithPrecision($age); + + if($age_m <= 36){ + // $touwei_date = Db::table('ws_touwei')->where("age <= $age_m and gender = '$gender'")->order('age desc')->limit(1)->field('middle')->fetchSql(true)->select(); + $touwei_date = Db::query("select * from ws_touwei where age <= $age_m and gender = '$gender' order by age desc"); + $return_data = $touwei_date[0]; + } + return $return_data; + } + diff --git a/application/app/controller/Index.php b/application/app/controller/Index.php index d501106..ef067d3 100644 --- a/application/app/controller/Index.php +++ b/application/app/controller/Index.php @@ -103,7 +103,7 @@ class Index extends Base{ // 检测版本及判断是否登录失效 public function login_invalid_version($data = ['token'=>'2d4ea9b3f44b169ddf64b2f3d2725ceb']){ - try { + // try { // 获取客户端IP $ip = request()->ip(); // 调用IP识别方法 @@ -150,25 +150,25 @@ class Index extends Base{ $language_data = $this->pd_language($user_token_state['language'],$isSupportedLanguage,$language); if($user_token_state['state'] === false){ - return $this->msg(-1,'未登录',['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->language_country]); + return $this->msg(-1,'未登录',['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->process_Language()]); }else{ - return $this->msg(['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->language_country]); + return $this->msg(['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->process_Language()]); } - } catch (\Exception $e) { - // 捕获异常 - $logContent["flie"] = $e->getFile(); - $logContent["line"] = $e->getLine(); - $logContent['all_content'] = "异常信息:\n"; - $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; - $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; - $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; - $logContent['all_content'] .= "方法: " . __METHOD__ . "\n"; - $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; - $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; - $this->record_api_log($data, $logContent, null); - return $this->msg(99999); - } + // } catch (\Exception $e) { + // // 捕获异常 + // $logContent["flie"] = $e->getFile(); + // $logContent["line"] = $e->getLine(); + // $logContent['all_content'] = "异常信息:\n"; + // $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; + // $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; + // $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; + // $logContent['all_content'] .= "方法: " . __METHOD__ . "\n"; + // $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; + // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // $this->record_api_log($data, $logContent, null); + // return $this->msg(99999); + // } } // 添加IP信息获取方法 @@ -185,7 +185,7 @@ class Index extends Base{ } } - public function set_language_country($data = ['token'=>'caadd1be045a65f30b92aa805f1de54a','language'=>'zh']){ + public function set_language_country($data = ['token'=>'caadd1be045a65f30b92aa805f1de54a','language'=>'zh-Hans']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -1155,6 +1155,16 @@ class Index extends Base{ return $result; } + // 处理返回的语言数组 + public function process_Language(){ + $temporary_arr = []; + foreach ($this->language_country as $key => $value) { + array_push($temporary_arr,['key'=>$key,'value'=>$value]); + } + return $temporary_arr; + } + + diff --git a/application/app/controller/Login.php b/application/app/controller/Login.php index cd8f044..da24dca 100644 --- a/application/app/controller/Login.php +++ b/application/app/controller/Login.php @@ -413,6 +413,7 @@ class Login extends Base{ * $type(验证类型,是注册用,还是其他用途) 字符串 默认register(注册)(register、login、reset_password) * $road(是手机还是邮箱还是其他) 字符串 默认tel或email */ + //18736019909 public function send_phone_email_code($data = ['data'=>'18736019909']){ if(count(input('post.')) > 0){ @@ -428,8 +429,12 @@ class Login extends Base{ $num = mt_rand(100000,999999); if (preg_match('/^\d{11}$/', $data['data'])) { + // 本公司短信 $result = $this->send_tel_code($data['data'],$num); - // return $this->msg($result); + // 阿里云短信 + // $sms_all = new Smsaliyun; + // $result = $sms_all->send_sms($data['data'],$num); + // dump($result); $road = 'tel'; }else{ $result = $this->send_email_code([$data['data']],['title'=>'体测APP验证码','from_user_name'=>'体测APP','content'=>$num]); @@ -473,7 +478,6 @@ class Login extends Base{ // 'content' => '【小白秤】您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' // 'content' => '【品传科技】您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' // 'content' => '【巨天】您好,欢迎使用巨天,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略!' - ); $postData = json_encode($postData); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); @@ -481,6 +485,7 @@ class Login extends Base{ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 发送请求并获取响应 $response = curl_exec($ch); + // dump($response); // 检查是否有错误发生 if (curl_errno($ch)) { $error_message = curl_error($ch); @@ -489,7 +494,7 @@ class Login extends Base{ // 关闭cURL会话 curl_close($ch); // 处理响应 - + // dump(json_decode($response,true)); if ($response) { return json_decode($response,true); } else { diff --git a/application/app/controller/Pagingcontrast.php b/application/app/controller/Pagingcontrast.php index 29a543a..d59e749 100644 --- a/application/app/controller/Pagingcontrast.php +++ b/application/app/controller/Pagingcontrast.php @@ -112,7 +112,7 @@ class Pagingcontrast extends Base{ } // 获取详细历史数据信息(包含身体、跳绳、肺活量) - public function get_all_record_detailed_information($data = ['id'=>'36','type'=>'8','token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ + public function get_all_record_detailed_information($data = ['id'=>'3802','type'=>'2','aan_id'=>'1841','token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -458,6 +458,8 @@ class Pagingcontrast extends Base{ // $for_data_arr = ['height'=>['身高','cm'],'weight'=>['体重','kg'],'age'=>['年龄','岁'],'bmi'=>['BMI','']]; // } $result_data = []; + // dump($result); + // dump($for_data_arr); foreach ($for_data_arr as $key => $value) { $temporary_arr['key_name'] = $key; $temporary_arr['name'] = $value[0]; @@ -471,10 +473,16 @@ class Pagingcontrast extends Base{ $temporary_arr['value'] = explode(',',$result[$key])[0]; } }else{ + if($key == 'un_fat_w_weight'){ $temporary_arr['value'] = bcsub(explode(',',$result['weight'])[0],explode(',',$result['fat_w'])[0],2); }else{ - $temporary_arr['value'] = explode(',',$result[$key])[0]; + // dump($key); + // dump($result[$key]); + if(array_key_exists($key,$result)){ + $temporary_arr['value'] = explode(',',$result[$key])[0]; + } + } } diff --git a/application/app/controller/Smsaliyun.php b/application/app/controller/Smsaliyun.php new file mode 100644 index 0000000..de38148 --- /dev/null +++ b/application/app/controller/Smsaliyun.php @@ -0,0 +1,84 @@ + 'LTAI5tQCdWe9Epir3ydXWbzp', + 'accessKeySecret' => 'JKLzF0b5AXw2ajhwtem2fhPSUZVOZ5', + 'signName' => '郑州巨天信息', + 'templateCode' => 'SMS_484085215', + 'regionId' => 'cn-hangzhou' + ]; + + /** + * 发送短信接口 + * @param string $phone 手机号 + * @param string $code 验证码 + */ + public function send_sms($phone='18530934717', $code='0932') + { + try { + // 初始化阿里云客户端 + AlibabaCloud::accessKeyClient( + $this->smsConfig['accessKeyId'], + $this->smsConfig['accessKeySecret'] + ) + ->regionId($this->smsConfig['regionId']) + ->asDefaultClient(); + + // 发送短信请求 + $result = AlibabaCloud::rpc() + ->product('Dysmsapi') + ->version('2017-05-25') + ->action('SendSms') + ->method('POST') + ->host('dysmsapi.aliyuncs.com') + ->options([ + 'query' => [ + 'RegionId' => $this->smsConfig['regionId'], + 'PhoneNumbers' => $phone, + 'SignName' => $this->smsConfig['signName'], + 'TemplateCode' => $this->smsConfig['templateCode'], + 'TemplateParam' => json_encode(['code' => $code]), + ], + ]) + ->request(); + + $result = $result->toArray(); + + if ($result['Code'] == 'OK') { + return [ + 'code' => 0, + 'message' => '短信发送成功', + 'data' => $result + ]; + } else { + return [ + 'code' => 99999, + 'message' => $result['Message'], + 'error' => $result + ]; + } + } catch (ClientException $e) { + return [ + 'code' => 99998, + 'message' => '客户端异常: ' . $e->getErrorMessage(), + 'error' => $e->getMessage() + ]; + } catch (ServerException $e) { + return [ + 'code' => 99997, + 'message' => '服务端异常: ' . $e->getErrorMessage(), + 'error' => $e->getMessage() + ]; + } + } +} \ No newline at end of file diff --git a/application/testapp/controller/Base.php b/application/testapp/controller/Base.php index 7138526..f429140 100644 --- a/application/testapp/controller/Base.php +++ b/application/testapp/controller/Base.php @@ -1,6 +1,6 @@ 'app_data_log', - '2'=>'app_card_data', - '3'=>'app_user_data', - '4'=>'pc_vitalcapacity_standard', - '5'=>'admin_estimate', - '6'=>'app_account_number' + '1'=>'app_data_log_copy1', + '2'=>'app_card_data_copy1', + '3'=>'app_user_data_copy1', + '4'=>'pc_vitalcapacity_standard_copy1', + '5'=>'admin_estimate_copy1', + '6'=>'app_account_number_copy1' ]; protected $ceshiyong_token = ['57bd45e3a963b372ea2d873e4bd8d1f8','e0966788d02cc93290d9d674921d9715']; diff --git a/application/testapp/controller/Calculatebody.php b/application/testapp/controller/Calculatebody.php index ee9bb9b..3215a65 100644 --- a/application/testapp/controller/Calculatebody.php +++ b/application/testapp/controller/Calculatebody.php @@ -1,6 +1,6 @@ 'app_card_body_data', - '2'=>'app_user_data', - '3'=>'pc_bmistand', - '4'=>'pc_heightstand', - '5'=>'pc_weightstand', - '6'=>'pc_childrenprescription', - '7'=>'pc_childprescriptionbyage', - '8'=>'pc_heightstand', - '9'=>'pc_weightstand', - '10'=>'pc_bmistand', + '1'=>'app_card_body_data_copy1', + '2'=>'app_user_data_copy1', + '3'=>'pc_bmistand_copy1', + '4'=>'pc_heightstand_copy1', + '5'=>'pc_weightstand_copy1', + '6'=>'pc_childrenprescription_copy1', + '7'=>'pc_childprescriptionbyage_copy1', + '8'=>'pc_heightstand_copy1', + '9'=>'pc_weightstand_copy1', + '10'=>'pc_bmistand_copy1', + '11'=>'app_account_number_copy1', ]; protected $age_limit = 16; protected $unit_symbol = ['score'=>'分','height'=>'CM','weight'=>'公斤','bmi'=>'','fat_r'=>'%','fat_w'=>'kg','muscle'=>'%','muscleval'=>'kg','water'=>'kg','bone'=>'kg','protein'=>'%','proteinval'=>'kg','kcal'=>'kcal','visceral'=>'','sfr'=>'%',]; @@ -89,7 +90,7 @@ class Card extends Base{ // 详细卡片信息 // $data = ['id'=>'2'] public function card_data_detailed($data=['aud_id'=>'144']){ - try { + // try { // 你的业务逻辑 if(count(input('post.')) > 0){ $data = input('post.'); @@ -102,22 +103,21 @@ class Card extends Base{ } // $return_data; $return_data = $this->get_user_body_data($data); - // $language_data = new Language(); - // $return_data = $language_data->handling_languages_from_multiple_countries('en', $return_data->getData()); + return $return_data; - } catch (\Exception $e) { - // 捕获异常 - $logContent["flie"] = $e->getFile(); - $logContent["line"] = $e->getLine(); - $logContent['all_content'] = "异常信息:\n"; - $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; - $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; - $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; - $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; - $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; - $this->record_api_log($data, $logContent, null); - return $this->msg(99999); - } + // } catch (\Exception $e) { + // // 捕获异常 + // $logContent["flie"] = $e->getFile(); + // $logContent["line"] = $e->getLine(); + // $logContent['all_content'] = "异常信息:\n"; + // $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; + // $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; + // $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; + // $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; + // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // $this->record_api_log($data, $logContent, null); + // return $this->msg(99999); + // } } @@ -422,8 +422,8 @@ class Card extends Base{ } // BMI测评 - public function card_bmi_evaluation($cbe_data = ['height'=>'177','weight'=>'177','birthday'=>'2024-10-03','sex'=>'1'],$type = false){ - try { + public function card_bmi_evaluation($cbe_data = ['height'=>'177','weight'=>'177','birthday'=>'2024-10-03','sex'=>'1','token'=>'caadd1be045a65f30b92aa805f1de54a'],$type = false){ + // try { // 你的业务逻辑 if(count(input('post.')) > 0 && $type == false){ $cbe_data = input('post.'); @@ -431,9 +431,10 @@ class Card extends Base{ if(!is_array($cbe_data)){ return $this->msg(10005); } - if(!array_key_exists('height', $cbe_data) || !array_key_exists('weight', $cbe_data) || !array_key_exists('birthday', $cbe_data) || !array_key_exists('sex', $cbe_data)){ + if(!array_key_exists('height', $cbe_data) || !array_key_exists('token', $cbe_data) || !array_key_exists('weight', $cbe_data) || !array_key_exists('birthday', $cbe_data) || !array_key_exists('sex', $cbe_data)){ return $this->msg(10001); } + $token = $cbe_data['token']; unset($cbe_data['token']); if(!$this->verify_data_is_ok($cbe_data['birthday'],'datetime')){ return $this->msg(10005); @@ -459,23 +460,31 @@ class Card extends Base{ $request_result = $this->postRequest($url,$temporary_parameter,array('Content-Type:application/json','Origin:http://ybdevice.pcxbc.com')); // 直接开始业务,请求外部接口end + // 处理进度点 $request_result =$this->bmi_evaluation_action($request_result); - $this->record_api_log($cbe_data, null, $request_result); - return $request_result; - } catch (\Exception $e) { - // 捕获异常 - $logContent["flie"] = $e->getFile(); - $logContent["line"] = $e->getLine(); - $logContent['all_content'] = "异常信息:\n"; - $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; - $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; - $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; - $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; - $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; - $this->record_api_log($cbe_data, $logContent, null); - return $this->msg(99999); - } + + $language_str = Db::table($this->card_use_db_name['11'])->where(['token'=>$token])->field('language')->find(); + $language_data = new Language(); + if(!$language_str['language']){ + $language_str['language'] = 'zh-Hans'; + } + $request_result = $language_data->handling_languages_from_multiple_countries($language_str['language'], $request_result->getData()['data']); + // $this->record_api_log($cbe_data, null, $request_result); + return $this->msg($request_result); + // } catch (\Exception $e) { + // // 捕获异常 + // $logContent["flie"] = $e->getFile(); + // $logContent["line"] = $e->getLine(); + // $logContent['all_content'] = "异常信息:\n"; + // $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; + // $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; + // $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; + // $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; + // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // $this->record_api_log($cbe_data, $logContent, null); + // return $this->msg(99999); + // } } ################################################################业务接口################################################################ @@ -517,7 +526,7 @@ class Card extends Base{ acbd.bmi, acbd.body_age, acbd.head_circumference, - aud.birthday,aud.gender,aud.target_weight,aud.initial_weight,aud.initial_date + aud.birthday,aud.gender,aud.target_weight,aud.initial_weight,aud.initial_date,aud.aan_id from ".$this->card_use_db_name['1']." as acbd left join ".$this->card_use_db_name['2']." as aud on acbd.aud_id=aud.id where acbd.is_del=0 and acbd.aud_id='".$data['aud_id']."' @@ -543,7 +552,9 @@ class Card extends Base{ "list"=>[], "key_name"=>"weight", "desc"=>"反映和衡量一个人健康状况的重要标志之一", - "offset"=>"0" + "offset"=>"0", + "standard_val"=>"", + "difference_val"=>"", ], [ "name"=>"身高", @@ -554,7 +565,9 @@ class Card extends Base{ "list"=>[], "key_name"=>"height", "desc"=>"人体纵向部分的长度,源于人体的纵向生长,受遗传因素的影响较大", - "offset"=>"0" + "offset"=>"0", + "standard_val"=>"", + "difference_val"=>"", ], [ "name"=>"BMI", @@ -565,7 +578,9 @@ class Card extends Base{ "list"=>[], "key_name"=>"bmi", "desc"=>"BMI是身体质量指数,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。", - "offset"=>"0" + "offset"=>"0", + "standard_val"=>"", + "difference_val"=>"", ], ], 'bottom_list' => [], @@ -583,8 +598,11 @@ class Card extends Base{ 'cumulative_day'=>'0' ], ]; + $language_data = new Language(); + $result_return = $language_data->handling_languages_from_multiple_countries('zh-Hans', $result_return); return $this->msg($result_return); }else{ + // 存储头围数据 $head_circumference = $result[0]['head_circumference']?json_decode($result[0]['head_circumference'],true):false; unset($result[0]['head_circumference']); @@ -660,12 +678,13 @@ class Card extends Base{ // 加入曲线板块底部的减肥计划数据end // 添加头围数据(如果有的话)start if($head_circumference !== false && $this->calculate_age($result[0]['birthday']) < 3){ + if($head_circumference['level'] == '异常' || $head_circumference['value'] == 0){ $offset = 0; }else{ $offset = $cardparts->calculate_landing_point($head_circumference['list2'],$head_circumference['value'],$head_circumference['level']); } - array_push($result_end['top_list'],[ + $touwei_array = [ 'name'=>'头围', 'value'=>$head_circumference['value'], 'unit'=>'CM', @@ -675,10 +694,63 @@ class Card extends Base{ 'key_name'=>'head_circumference', 'desc'=>'头围是指绕头部一周的最大长度,头围的大小与脑的发育密切相关', 'offset'=>$offset - ]); + ]; + $touwei_data = $this->touwei_temporary_use($result[0]['birthday'],$result[0]['gender']); + if(count($touwei_data)){ + $touwei_array['standard_val'] = $touwei_data['middle']; + $touwei_array['difference_val'] = bcsub($touwei_array['value'],$touwei_data['middle'],2); + }else{ + $touwei_array['standard_val'] = ''; + $touwei_array['difference_val'] = ''; + } + array_push($result_end['top_list'],$touwei_array); + } // 添加头围数据(如果有的话)end + + // 这段业务处理可以删除,是做的临时的,假的start + $biaozhun_val = $this->body_temporary_use($result[0]['birthday'],$result[0]['gender']); + // dump($biaozhun_val); + // $biaozhun_val_weight = 50; + // $biaozhun_val_height = 170; + // $biaozhun_val_bmi = 22; + foreach ($result_end['top_list'] as $key => $value) { + if($value['key_name'] == 'weight'){ + if($biaozhun_val['weight'] == ''){ + $result_end['top_list'][$key]['standard_val'] = ''; + $result_end['top_list'][$key]['difference_val'] = ''; + }else{ + $result_end['top_list'][$key]['standard_val'] = $biaozhun_val['weight']; + $result_end['top_list'][$key]['difference_val'] = bcsub($value['value'],$biaozhun_val['weight'],2); + } + }else if($value['key_name'] == 'height'){ + if($biaozhun_val['height'] == ''){ + $result_end['top_list'][$key]['standard_val'] = ''; + $result_end['top_list'][$key]['difference_val'] = ''; + }else{ + $result_end['top_list'][$key]['standard_val'] = $biaozhun_val['height']; + $result_end['top_list'][$key]['difference_val'] = bcsub($value['value'],$biaozhun_val['height'],2); + } + }else if($value['key_name'] == 'bmi'){ + if($biaozhun_val['bmi'] == ''){ + $result_end['top_list'][$key]['standard_val'] = ''; + $result_end['top_list'][$key]['difference_val'] = ''; + }else{ + $result_end['top_list'][$key]['standard_val'] = $biaozhun_val['bmi']; + $result_end['top_list'][$key]['difference_val'] = bcsub($value['value'],$biaozhun_val['bmi'],2); + } + } + + } + // 这段业务处理可以删除,是做的临时的,假的end + // dump($result); + $language_str = Db::table($this->card_use_db_name['11'])->where(['id'=>$result[0]['aan_id']])->field('language')->find(); + $language_data = new Language(); + if(!$language_str['language']){ + $language_str['language'] = 'zh-Hans'; + } + $result_end = $language_data->handling_languages_from_multiple_countries($language_str['language'], $result_end); return $this->msg($result_end); } } @@ -1253,6 +1325,174 @@ class Card extends Base{ ################################################################其他接口################################################################ ################################################################其他接口################################################################ + public function body_temporary_use($age,$gender){ + $return_data = [ + 'height'=>'', + 'weight'=>'', + 'bmi'=>'', + ]; + if(!in_array($gender,['1','2'])){ + return $return_data; + } + $age_m = $this->calculateAgeInMonthsWithPrecision($age); + if($age_m < 228){//月龄小于19岁 + // dump($age_m); + // $height_date = Db::table('ws_height')->where("age <= $age_m and gender = '$gender'")->order('age desc')->limit(1)->field('middle')->select(); + $height_date = Db::query("select * from ws_height where age <= $age_m and gender = '$gender' order by age desc"); + // $weight_date = Db::table('ws_weight')->where("age <= $month_num and Sex = '$gender'")->order('age desc')->limit(1)->field('middle')->select(); + $weight_date = Db::query("select * from ws_weight where age <= $age_m and gender = '$gender' order by age desc"); + // $bmi_date = Db::table('ws_bmi')->where("age <= $month_num and Sex = '$gender'")->order('age desc')->limit(1)->field('middle')->select(); + $bmi_date = Db::query("select * from ws_bmi where age <= $age_m and gender = '$gender' order by age desc"); + $return_data = array( + 'height' => $height_date[0]['middle'], + 'weight' => $weight_date[0]['middle'], + 'bmi' => $bmi_date[0]['middle'], + ); + }else{ + $bmi_data = [ + '1' => [ // 男性 + [ + 'age' => ['min' => 216, 'max' => 299], // 18-24岁(216-299月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '20.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '20.5', 'max_val' => '23.9', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.0', 'max_val' => '27.9', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.0', 'max_val' => '31.9', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.0', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 300, 'max' => 419], // 25-34岁(300-419月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '20.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.0', 'max_val' => '24.4', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.5', 'max_val' => '28.4', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.5', 'max_val' => '32.4', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.5', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 420, 'max' => 539], // 35-44岁(420-539月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '21.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.5', 'max_val' => '25.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '25.1', 'max_val' => '29.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '29.1', 'max_val' => '33.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '33.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 540, 'max' => 719], // 45-59岁(540-719月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '21.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '22.0', 'max_val' => '25.5', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '25.6', 'max_val' => '29.5', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '29.6', 'max_val' => '33.5', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '33.6', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 720, 'max' => '99999'], // ≥60岁(720+月龄) + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.5', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.5', 'max_val' => '22.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '22.5', 'max_val' => '26.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '26.1', 'max_val' => '29.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '29.1', 'max_val' => '33.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '33.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ] + ], + '2' => [ // 女性 + [ + 'age' => ['min' => 216, 'max' => 299], // 18-24岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '19.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '20.0', 'max_val' => '22.9', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '23.0', 'max_val' => '26.9', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '27.0', 'max_val' => '30.9', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '31.0', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 300, 'max' => 419], // 25-34岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '20.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '20.5', 'max_val' => '23.4', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '23.5', 'max_val' => '27.4', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '27.5', 'max_val' => '31.4', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '31.5', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 420, 'max' => 539], // 35-44岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '20.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.0', 'max_val' => '24.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.1', 'max_val' => '28.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.1', 'max_val' => '32.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 540, 'max' => 719], // 45-59岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '21.4', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '21.5', 'max_val' => '24.5', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '24.6', 'max_val' => '28.5', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.6', 'max_val' => '32.5', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.6', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ], + [ + 'age' => ['min' => 720, 'max' => 99999], // ≥60岁 + 'list'=>[ + ['min_val' => '0', 'max_val' => '18.0', 'text' => '低体重', 'color' => '#8BC8FB'], + ['min_val' => '18.0', 'max_val' => '21.9', 'text' => '偏瘦', 'color' => '#B4E3FD'], + ['min_val' => '22.0', 'max_val' => '25.0', 'text' => '正常', 'color' => '#6CD86F'], + ['min_val' => '25.1', 'max_val' => '28.0', 'text' => '超重', 'color' => '#FFD166'], + ['min_val' => '28.1', 'max_val' => '32.0', 'text' => '肥胖', 'color' => '#FF9A5A'], + ['min_val' => '32.1', 'max_val' => '99999', 'text' => '重度肥胖', 'color' => '#FF6B6B'] + ] + ] + ] + ]; + + foreach ($bmi_data[$gender] as $group) { + if ($age_m >= $group['age']['min'] && $age_m <= $group['age']['max']) { + $return_data['bmi'] = bcdiv(bcadd($group['list'][2]['min_val'],$group['list'][2]['max_val'],20),2,1); + } + } + + } + return $return_data; + } + public function touwei_temporary_use($age,$gender){ + $return_data = [ + + ]; + if(!in_array($gender,['1','2'])){ + return $return_data; + } + + $age_m = $this->calculateAgeInMonthsWithPrecision($age); + + if($age_m <= 36){ + // $touwei_date = Db::table('ws_touwei')->where("age <= $age_m and gender = '$gender'")->order('age desc')->limit(1)->field('middle')->fetchSql(true)->select(); + $touwei_date = Db::query("select * from ws_touwei where age <= $age_m and gender = '$gender' order by age desc"); + $return_data = $touwei_date[0]; + } + return $return_data; + } + diff --git a/application/testapp/controller/Cardparts.php b/application/testapp/controller/Cardparts.php index bde25eb..d27aa9d 100644 --- a/application/testapp/controller/Cardparts.php +++ b/application/testapp/controller/Cardparts.php @@ -1,6 +1,6 @@ 'app_user_data', - '2'=>'app_card_data_sub_item', - '3'=>'app_card_data_sub_item_data', - '4'=>'admin_estimate', - '5'=>'app_card_data' + '1'=>'app_user_data_copy1', + '2'=>'app_card_data_sub_item_copy1', + '3'=>'app_card_data_sub_item_data_copy1', + '4'=>'admin_estimate_copy1', + '5'=>'app_card_data_copy1' ]; protected $curve_color = ['#f7b03e','#fb7b92','#ff9f40','#3fcba7',]; diff --git a/application/testapp/controller/Deepseek.php b/application/testapp/controller/Deepseek.php index bf4d722..73bb81c 100644 --- a/application/testapp/controller/Deepseek.php +++ b/application/testapp/controller/Deepseek.php @@ -1,6 +1,6 @@ 'admin_editor_text_content', - '2'=>'admin_editor_text_like_up_log', - '3'=>'admin_notice_banner', - '4'=>'admin_business_cooperation' + '1'=>'admin_editor_text_content_copy1', + '2'=>'admin_editor_text_like_up_log_copy1', + '3'=>'admin_notice_banner_copy1', + '4'=>'admin_business_cooperation_copy1' ]; protected $page_num = 10; // 加 bcadd(,,20) diff --git a/application/testapp/controller/Device.php b/application/testapp/controller/Device.php index 5f0b606..57a9e84 100644 --- a/application/testapp/controller/Device.php +++ b/application/testapp/controller/Device.php @@ -1,6 +1,6 @@ 'app_device_data', - '2'=>'app_account_number', - '3'=>'app_device_code_data', + '1'=>'app_device_data_copy1', + '2'=>'app_account_number_copy1', + '3'=>'app_device_code_data_copy1', ]; diff --git a/application/testapp/controller/Download.php b/application/testapp/controller/Download.php index 0d5efc2..e9b0188 100644 --- a/application/testapp/controller/Download.php +++ b/application/testapp/controller/Download.php @@ -1,6 +1,6 @@ 'app_card_body_data','6'=>'app_card_skip_data','8'=>'app_card_vitalcapacity_data','10'=>'app_card_data_sub_item_data']; + protected $db_name = ['2'=>'app_card_body_data_copy1','6'=>'app_card_skip_data_copy1','8'=>'app_card_vitalcapacity_data_copy1','10'=>'app_card_data_sub_item_data_copy1']; protected $index_use_db_name = [ - '1'=>'app_version_log', - '2'=>'app_user_data', - '3'=>'app_card_body_data', - '4'=>'app_device_code_data', - '5'=>'app_device_data', - '6'=>'app_card_data', - '7'=>'app_account_number', - '8'=>'app_card_data_sub_item', - '9'=>'app_card_data_sub_item_data', - '10'=>'admin_estimate' + '1'=>'app_version_log_copy1', + '2'=>'app_user_data_copy1', + '3'=>'app_card_body_data_copy1', + '4'=>'app_device_code_data_copy1', + '5'=>'app_device_data_copy1', + '6'=>'app_card_data_copy1', + '7'=>'app_account_number_copy1', + '8'=>'app_card_data_sub_item_copy1', + '9'=>'app_card_data_sub_item_data_copy1', + '10'=>'admin_estimate_copy1' ]; // protected $card_key = ['2'=>'body','6'=>'skip','8'=>'vitalcapacity']; protected $default_card = ['2','6','8']; @@ -65,7 +65,7 @@ class Index extends Base{ protected $language_country = [ 'en' => 'English', // 英语(通用)★ - 'zh' => '中文', // 中文(简体)★ + 'zh-Hans' => '中文', // 中文(简体)★ // 'es' => 'Español', // 西班牙语(西班牙)★ // 'fr' => 'Français', // 法语(法国)★ // 'pt' => 'Português', // 葡萄牙语(巴西)★ @@ -103,7 +103,7 @@ class Index extends Base{ // 检测版本及判断是否登录失效 public function login_invalid_version($data = ['token'=>'caadd1be045a65f30b92aa805f1de54a']){ - try { + // try { // 获取客户端IP $ip = request()->ip(); // 调用IP识别方法 @@ -147,33 +147,28 @@ class Index extends Base{ $url = ''; } $user_token_state = $this->token_time_validate($data['token']); - - $user_language_data = Db::table($this->index_use_db_name['7'])->where(['token'=>$data['token']])->field('language')->find(); - if($user_language_data != null){ - $language_data = $user_language_data['language']; - }else{ - $language_data = $this->pd_language($user_token_state['language'],$isSupportedLanguage,$language); - } + + $language_data = $this->pd_language($user_token_state['language'],$isSupportedLanguage,$language); if($user_token_state['state'] === false){ - return $this->msg(-1,'未登录',['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->language_country]); + return $this->msg(-1,'未登录',['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->process_Language()]); }else{ - return $this->msg(['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->language_country]); + return $this->msg(['version'=>$version,'url'=>$url,'language'=>$language_data,'language_arr'=>$this->process_Language()]); } - } catch (\Exception $e) { - // 捕获异常 - $logContent["flie"] = $e->getFile(); - $logContent["line"] = $e->getLine(); - $logContent['all_content'] = "异常信息:\n"; - $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; - $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; - $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; - $logContent['all_content'] .= "方法: " . __METHOD__ . "\n"; - $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; - $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; - $this->record_api_log($data, $logContent, null); - return $this->msg(99999); - } + // } catch (\Exception $e) { + // // 捕获异常 + // $logContent["flie"] = $e->getFile(); + // $logContent["line"] = $e->getLine(); + // $logContent['all_content'] = "异常信息:\n"; + // $logContent['all_content'] .= "消息: " . $e->getMessage() . "\n"; + // $logContent['all_content'] .= "代码: " . $e->getCode() . "\n"; + // $logContent['all_content'] .= "文件: " . $e->getFile() . "\n"; + // $logContent['all_content'] .= "方法: " . __METHOD__ . "\n"; + // $logContent['all_content'] .= "行号: " . $e->getLine() . "\n"; + // $logContent['all_content'] .= "跟踪信息:\n" . $e->getTraceAsString() . "\n"; + // $this->record_api_log($data, $logContent, null); + // return $this->msg(99999); + // } } // 添加IP信息获取方法 @@ -190,7 +185,7 @@ class Index extends Base{ } } - public function set_language_country($data = ['token'=>'caadd1be045a65f30b92aa805f1de54a','language'=>'zh']){ + public function set_language_country($data = ['token'=>'caadd1be045a65f30b92aa805f1de54a','language'=>'zh-Hans']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -358,7 +353,7 @@ class Index extends Base{ // 获取账号下用户列表 // $type 1获取列表,2获取详细信息 - public function get_user_card_list($data = ['aan_id'=>4,'type'=>2,'token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ + public function get_user_card_list($data = ['aan_id'=>87,'type'=>2,'token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -366,7 +361,6 @@ class Index extends Base{ } if(!array_key_exists('token', $data) || !array_key_exists('aan_id', $data) || !array_key_exists('type', $data)){ // 失败 - $this->record_api_log($data, null, ['code'=>10001,'msg'=>'',[]]); return $this->msg(10001); } if(!$this->verify_data_is_ok($data['aan_id'],'intnum')){ @@ -425,7 +419,7 @@ class Index extends Base{ } // 获取指定用户详细信息 - public function get_user_data_information($data = ['aud_id'=>61]){ + public function get_user_data_information($data = ['aud_id'=>144]){ // try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -1152,7 +1146,7 @@ class Index extends Base{ if($isSupportedLanguage){ $result = $language; }else{ - $result = 'en'; // 默认语言为中文 + $result = 'zh-Hans'; // 默认语言为中文 } }else{ $result = $user_language; @@ -1160,6 +1154,16 @@ class Index extends Base{ return $result; } + // 处理返回的语言数组 + public function process_Language(){ + $temporary_arr = []; + foreach ($this->language_country as $key => $value) { + array_push($temporary_arr,['key'=>$key,'value'=>$value]); + } + return $temporary_arr; + } + + diff --git a/application/testapp/controller/Language.php b/application/testapp/controller/Language.php index 141bcac..a4ee93c 100644 --- a/application/testapp/controller/Language.php +++ b/application/testapp/controller/Language.php @@ -1,6 +1,6 @@ 'German' ]; + // $language_data = new Language(); + // if(!$language_str['language']){ + // $language_str['language'] = 'zh-Hans'; + // } + // $result_end = $language_data->handling_languages_from_multiple_countries($language_str['language'], $result_end); + // 语言映射表 protected $languageMap = [ 'en' => [ @@ -74,19 +80,122 @@ class Language extends Base '肥胖等级' => "Obesity Level", '体重不足' => "Underweight", '肥胖的程度,表现实际体重与理想体重的差距。肥胖等级是判定肥胖症的一个指标。' => "Obesity level indicates the disparity between actual and ideal weight, serving as a diagnostic criterion for obesity.", + '孩子可能存在营养不良:对于处在生长发育期的孩子而言,蛋白质、碳水化合物、维生素和矿物质这四类营养素非常重要。建议补充足够的蛋白质、锌、钙、铁、维生素D、赖氨酸等营养。建议补充含鸡内金山楂膏健脾开胃类药食同源食物。' => "The child may be malnourished: For growing children, protein, carbohydrates, vitamins, and minerals are critical. Ensure adequate intake of protein, zinc, calcium, iron, vitamin D, lysine, etc. Consider herbal foods like chicken gizzard-hawthorn paste to improve digestion and appetite.", - '孩子可能存在营养不良:对于处在生长发育期的孩子而言,最有利于长高的营养素是蛋白质、碳水化合物、维生素和矿物质四类。建议补充足够的蛋白质、锌、铁、钙、维生素D、赖氨酸等营养。' => "The child may be malnourished: For children in their growth and development stage, the most beneficial nutrients for height growth are proteins, carbohydrates, vitamins, and minerals. It is recommended to ensure adequate intake of nutrients such as protein, zinc, iron, calcium, vitamin D, and lysine.", + '坚持适当、科学的跳跃运动能够科学地增加学生体重,能够改善学 生体重过低的情况;同时运动会消耗能量并加速胃肠蠕动,这会使孩子的食欲大开,再配合均衡的营养有利于孩子增重。' => "Moderate, scientifically designed jumping exercises can help underweight students gain weight by boosting energy expenditure and gastrointestinal motility, thereby increasing appetite. Combined with balanced nutrition, this supports healthy weight gain.", - '3-7岁的孩子:骑两轮车、拍踢球、打篮球、游泳、爬山,每天高强度运动不超过30分钟。' => "Ages 3–7: Bicycling, ball games, basketball, swimming, hiking. Limit high-intensity exercise to 30 minutes daily.", - '该年龄段睡眠时间建议:9-11小时' => "Recommended sleep duration for this age group: 9–11 hours.", - '孩子开始对于赞赏、鼓励、认同和肯定有需求,而且此阶段父亲在孩子的性格塑造、情绪控制以及责任感培养方面扮演着重要的角色,必须告诉孩子什么事应该做、什么事不应该做,并经常性地给孩子一些积极地暗示。例如,可以时常向孩子表达“我会一直在你身边,不要害怕””我对你的进步都看在眼里等类似的话语。' => "Children begin to crave praise, encouragement, and validation. Fathers play a key role in shaping character, emotional regulation, and responsibility during this phase. Clearly define boundaries while offering positive affirmations (e.g., 'I’m always here for you,' 'I see your progress').", + + '孩子开始对于赞赏、鼓励、认同和肯定有需求,而且此阶段父亲在孩子的性格塑造、情绪控制以及责任感培养方面扮演着重要的角色,必须告诉孩子什么事应该做、什么事不应该做,并经常性地给孩子一些积极地暗示。例如,可以时常向孩子表达“我会一直在你身边,不要害怕””我对你的进步都看在眼里等类似的话语。' => 'Children begin developing needs for praise, encouragement, recognition and affirmation. During this phase, fathers play a vital role in character formation, emotional regulation and responsibility cultivation. Clearly communicate appropriate behaviors while providing consistent positive reinforcement, such as saying: "I\'ll always be here for you" or "I see your progress."', + + '步入最佳学习期,除了文化课的学习更多的还有情绪调节、人际交往的学习,会模仿父母、老师同学。此阶段需要的不仅是尊重和信任,还需要更多自由选择的权利,变管制为引导。' => 'Entering the optimal learning period, children develop emotional regulation and social skills beyond academics, mimicking parents, teachers and peers. They require not just respect and trust, but also increased autonomy - transitioning from control to guidance.', + + '该年龄段睡眠时间建议:11-14小时' => 'Recommended sleep duration: 11-14 hours', + + '0-1岁的孩子:6个月之前多练习趴着、抬头、翻身等,6个月后练习爬行,8个月后可尝试坐着。充分的爬行运动有利于孩子协调性和平衡力的培养。' => '0-1 year olds: Practice tummy time, head lifting and rolling before 6 months; crawling after 6 months; attempt sitting at 8 months. Ample crawling enhances coordination and balance.', + + '3-7岁的孩子:骑两轮车、拍踢球、打篮球、游泳、爬山,每天高强度运动不超过30分钟。' => '3-7 year olds: Bicycle riding, ball games, basketball, swimming, mountain climbing. Limit high-intensity exercise to 30 minutes daily.', + + '正值青春期,生理的特点决定了情绪的跌宕起伏。当孩子出现情绪问题时,父母可以告诉孩子一些解决的办法,然后让他自行体悟和理解,教会孩子接纳情绪的方法而不是如何对抗情绪。' => 'Adolescents experience physiological mood fluctuations. When emotional issues arise, parents should teach coping strategies for self-discovery, emphasizing emotional acceptance over resistance.', + + '该年龄段睡眠时间建议:8-10小时' => 'Recommended sleep duration: 8-10 hours', + + '睡眠时间建议:晚上9点到凌晨1点、早上5点到7点是孩子生长激素分泌最多的时间段,此时进入深度睡眠,生长激素的分泌就会最大化,建议处在生长发育期的孩子尽量在9点前睡觉。' => 'Optimal sleep window: 9pm-1am and 5-7am when growth hormone peaks. Maximize secretion through deep sleep. Growing children should sleep before 9pm.', + + '1、情绪的不稳定影响了下丘脑及垂体系统的正常工作,进而使垂体生长激素分泌减少,长期的情绪障碍除了影响身高,同时还会造成孩子智力增长慢、多动、人际关系不协调等异常现象。' => '1. Emotional instability disrupts hypothalamic-pituitary function, reducing growth hormone secretion. Chronic emotional issues may impair height development, cognitive growth, and cause hyperactivity or social maladjustment.', + + '1-3岁的孩子:此年龄段实现了由走到跑的转变,神经系统也得到了发育。鼓励孩子有利于生长发育的活动即可:踩图案、绕障碍行走、学小动物走路(如青蛙跳、猴子跑、老虎匍匐前进等)、仰卧起坐等。' => '1-3 year olds: Transitioning from walking to running with developing nervous systems. Encourage developmental activities: pattern stepping, obstacle courses, animal walks (frog jumps, monkey runs, tiger crawls), and sit-ups.', + + '该年龄段睡眠时间建议:14-17小时' => 'Recommended sleep duration: 14-17 hours', + + '该年龄段睡眠时间建议:10-13小时' => 'Recommended sleep duration: 10-13 hours', + + '该年龄段睡眠时间建议:12-15小时' => 'Recommended sleep duration: 12-15 hours', + + '除了满足食物等生理需求,需要建立足够的安全感,充分陪伴、呵护。还要在排除一些安全隐患后适当满足孩子的探索需求。' => 'Beyond physiological needs like food, provide security through attentive care while enabling safe exploration after risk assessment.', + + '该年龄段睡眠时间建议:9-11小时' => 'Recommended sleep duration: 9-11 hours', + + '8-16岁的孩子:1、每周3-5次跳绳,50-100次左右/组,每天做5组,每组间隔5分钟;2、立定跳远,每周5-7次,每次20-50次;3、慢跑500-1000米;3、20个俯卧撑,30个上下蹲、30个仰卧起坐。' => '8-16 year olds: 1) Rope skipping 3-5x/week: 5 sets of 50-100 skips daily with 5-minute intervals; 2) Standing long jumps 5-7x/week (20-50 reps); 3) Jogging 500-1000m; 4) 20 push-ups, 30 squats, 30 sit-ups.', + + '这个阶段的孩子最调皮,一方面非常依赖父母,另一方面又相对独立。这个阶段仍然需要安全感,并且父母本身的心理状态对孩子的影响依然深远,当他们情绪不稳定,孩子也极有可能受到影响。' => 'Children at this stage exhibit mischievousness while balancing dependence and independence. They still require security, and parental emotional stability profoundly impacts them - children often mirror parental emotional turbulence.', + + '孩子可能存在营养不良:对于处在生长发育期的孩子而言,蛋白质、碳水化合物、维生素和矿物质这四类营养素非常重要。建议补充足够的蛋白质、锌、钙、铁、维生素D、赖氨酸等营养。' => 'The child may be malnourished: For growing children, four key nutrients - proteins, carbohydrates, vitamins and minerals - are crucial. Recommend supplementing adequate protein, zinc, calcium, iron, vitamin D, and lysine.', + + '孩子可能存在营养不良:对于处在生长发育期的孩子而言,最有利于长高的营养素是蛋白质、碳水化合物、维生素和矿物质四类。建议补充足够的蛋白质、锌、铁、钙、维生素D、赖氨酸等营养。' => 'The child may be malnourished: The most height-beneficial nutrients for growing children are proteins, carbohydrates, vitamins and minerals. Recommend supplementing adequate protein, zinc, iron, calcium, vitamin D, and lysine.', + + '对于处在生长发育期的孩子而言,最有利于长高的营养素是蛋白质、碳水化合物、维生素和矿物质四类。建议补充足够的蛋白质、锌、铁、钙、维生素D、赖氨酸等营养,预防营养不良。' => 'For growing children, the most height-promoting nutrients are proteins, carbohydrates, vitamins and minerals. Recommend supplementing adequate protein, zinc, iron, calcium, vitamin D, and lysine to prevent malnutrition.', + + '超重的孩子如不加以控制,则极易向肥胖转变。超重的孩子饮食注意事项:控制食量,吃八分饱;三餐规律,避免暴饮暴食;细嚼慢咽;营养均衡搭配,拒绝高油、高盐、高糖的食物,养成清淡的口味。' => 'Overweight children easily progress to obesity without intervention. Dietary guidelines: 80% fullness; regular meals; thorough chewing; balanced nutrition; avoiding greasy/salty/sugary foods; developing light tastes.', + + '孩子可能存在中度营养不良:对于处在生长发育期的孩子而言,最有利于长高的营养素是蛋白质、碳水化合物、维生素和矿物质四类。建议补充足够的蛋白质、锌、铁、钙、维生素D、赖氨酸等营养。' => 'The child may have moderate malnutrition: The most height-beneficial nutrients are proteins, carbohydrates, vitamins and minerals. Recommend supplementing adequate protein, zinc, iron, calcium, vitamin D, and lysine.', + + '孩子可能存在重度营养不良:对于处在生长发育期的孩子而言,最有利于长高的营养素是蛋白质、碳水化合物、维生素和矿物质四类。建议补充足够的蛋白质、锌、铁、钙、维生素D、赖氨酸等营养。' => 'The child may have severe malnutrition: The most height-beneficial nutrients are proteins, carbohydrates, vitamins and minerals. Recommend supplementing adequate protein, zinc, iron, calcium, vitamin D, and lysine.', + + '1、肥胖在某种意义来说是隐性的营养不良,由于摄入热量过高,孩子虽然看着胖,但营养的摄入是不均衡的,尤其对于8-14岁的孩子来说,肥胖会极大地提高性早熟的概率。肥胖的孩子过度进食甜食、油腻的食物极易出现血糖高、高脂血症从而影响生长激素的分泌,影响终身高。肥胖的孩子更容易缺乏维生素D影响骨骼的钙化和成长。2、肥胖的孩子饮食注意事项:控制食量,吃八分饱;三餐规律,避免暴饮暴食;细嚼慢咽;营养均衡搭配,拒绝高油、高盐、高糖的食物,养成清淡的口味。' => '1. Obesity represents hidden malnutrition - while calorie intake is excessive, nutrition remains unbalanced. Particularly for 8-14 year olds, obesity significantly increases precocious puberty risks. Overconsumption of sweets/greasy foods elevates blood sugar/lipids, impairing growth hormone secretion and final height. Obese children also face higher vitamin D deficiency risks, affecting bone calcification. 2. Dietary guidelines: 80% fullness; regular meals; thorough chewing; balanced nutrition; avoiding greasy/salty/sugary foods; developing light tastes.', + + '对于处在生长发育期的孩子而言,蛋白质、碳水化合物、维生素和矿物质这四类营养素非常重要。建议补充足够的蛋白质、锌、铁、钙、维生素D、赖氨酸等营养,预防营养不良造成体型偏瘦。' => 'For growing children, four key nutrients - proteins, carbohydrates, vitamins and minerals - are essential. Recommend supplementing adequate protein, zinc, iron, calcium, vitamin D, and lysine to prevent underweight malnutrition.', + + '超重或肥胖的孩子如不加以控制,则极易向肥胖转变。超重或肥胖的孩子饮食注意事项:控制食量,吃八分饱;三餐规律,避免暴饮暴食;细嚼慢咽;营养均衡搭配,拒绝高油、高盐、高糖的食物,养成清淡的口味。建议补充含鸡内金山楂膏健脾开胃类药食同源食物。' => 'Overweight/obese children easily progress to worse obesity without control. Dietary guidelines: 80% fullness; regular meals; thorough chewing; balanced nutrition; avoiding greasy/salty/sugary foods; developing light tastes. Recommend supplementing with chicken gizzard-hawthorn paste (a food-grade herbal digestant).', + + '对于处在生长发育期的孩子而言,蛋白质、碳水化合物、维生素和矿物质这四类营养素非常重要。建议补充足够的蛋白质、锌、钙、维生素D、赖氨酸等营养,预防营养不良造成体型偏瘦。建议补充含鸡内金山楂膏健脾开胃类药食同源食物。' => 'For growing children, four key nutrients - proteins, carbohydrates, vitamins and minerals - are essential. Recommend supplementing adequate protein, zinc, calcium, vitamin D, and lysine to prevent underweight malnutrition, along with chicken gizzard-hawthorn paste (a food-grade herbal digestant).', + + '对于处在生长发育期的孩子而言,最有利于长高的营养素是蛋白质、碳水化合物、维生素和矿物质四类。建议补充足够的蛋白质、锌、钙、维生素D、赖氨酸等营养,预防营养不良。铁' => 'For growing children, the most height-promoting nutrients are proteins, carbohydrates, vitamins and minerals. Recommend supplementing adequate protein, zinc, calcium, vitamin D, and lysine to prevent malnutrition. Iron.', + + '运动会消耗能量并加速胃肠蠕动,这会使孩子的食欲大开,再配合均衡的营养有利于孩子增重。'=> 'Physical activity burns calories and enhances gastrointestinal motility, significantly stimulating children\'s appetite. When combined with balanced nutrition, this effectively supports healthy weight gain.', + + '体育运动可以有效刺激骨骼与全身关节,从而促进生长激素分泌,加速软骨细胞分裂,从而促进了身高的增长。跳绳运动是一项非常健康的运动方式,可以促进青少年的骨骼生长和发育,促进青少年的体质健康。' => 'Exercise actively stimulates bones and joints throughout the body, promoting growth hormone secretion and accelerating chondrocyte division to facilitate height increase. Rope skipping is an exceptionally beneficial exercise that enhances adolescents\' bone development and overall physical fitness.', + + '适宜的运动,能促进全身及骨的钙磷代谢,促进骨生长,长期的户外运动,加速骨细胞的生长,使管状骨变长,横径增粗,促进生长发育。'=> 'Moderate exercise optimizes whole-body calcium-phosphorus metabolism and bone growth. Regular outdoor activities accelerate osteocyte proliferation, lengthening long bones while increasing their diameter to promote healthy development.', + + '运动会消耗能量,培养运动习惯,减少静坐时间,建议每天参加体育运动的时间至少30分钟,不贪睡,睡得越久,人体代谢速度就会越慢,极易囤积脂肪。'=> 'Exercise consumes energy, establishes active habits and reduces sedentary behavior. We recommend minimum 30 minutes of daily physical activity. Excessive sleep slows metabolic rate and promotes fat accumulation.', + + '体育运动可以有效刺激骨骼与全身关节,从而促进生长激素分泌,加速软骨细胞分裂,从而促进了身高的增长。长期科学地坚持跳绳,可以在很大程度上增加骨强度和骨密度,促进骨生长,从而改善青少年的骨健康情况。跳绳运动是一项非常健康的运动方式,可以促进青少年的骨骼生长和发育,促进青少年的体质健康。' => 'Physical training effectively activates skeletal and articular systems, boosting growth hormone production and chondrocyte multiplication to enhance height. Scientifically-guided long-term rope skipping significantly improves bone mineral density and strength, optimizing adolescents\' skeletal health. This exercise is particularly effective for promoting bone development and physical conditioning.', + + '体育运动可以有效刺激骨骼与全身关节,从而促进生长激素分泌,加速软骨细胞分裂,从而促进了身高的增长。补救身高的最好方式就是长期坚持适当的体育运动,只要是采取科学的锻炼方法,都能促进骨骼的生长。在所有的运动项目中,全身运动、动力性跳跃运动和伸展运动这三类运动最能够促进身高增长。' => 'Exercise stimulates osseous and joint systems to enhance growth hormone release and cartilage cell division, facilitating height development. The most effective height-correction method involves sustained, moderate physical activity - any scientifically-designed regimen promotes bone growth. Among all exercises, full-body movements, plyometric jumps and stretching prove most beneficial for height improvement.', + + '运动会消耗能量,会增加体内脂肪的消耗,减少储存量,起到帮助控制体重的作用;培养运动习惯,减少静坐时间,建议每天参加体育运动的时间至少30分钟,不贪睡,睡得越久,人体代谢速度就会越慢,极易囤积脂肪。' => 'Physical exertion increases calorie expenditure and fat utilization while reducing adipose storage, effectively aiding weight management. Establish consistent exercise routines and minimize inactivity with at least 30 minutes daily movement. Prolonged sleep decreases metabolic efficiency and encourages fat deposition.', + + '运动会消耗能量并加速胃肠蠕动,这会使孩子的食欲大开,再配合均衡的营养有利于孩子维持合格的体重。' => 'Exercise burns calories and stimulates digestive peristalsis, markedly improving children\'s appetite. Paired with nutritional balance, this helps maintain optimal body weight parameters.', + + '建议多做跳跃运动(立定跳远,跳绳)中跳跃刺激的频率以及速度都对于机体中过多脂肪的消耗起到促进作用,能够一定程度上起到预防和控制肥胖、降低体重的作用;同时培养运动习惯,减少静坐时间,建议每天参加体育运动的时间至少30分钟,不贪睡,睡得越久,人体代谢速度就会越慢,极易囤积脂肪。' => 'Prioritize jumping exercises (standing broad jumps, rope skipping) as their impact frequency and velocity significantly enhance fat oxidation, effectively preventing obesity and aiding weight control. Cultivate regular workout habits and limit sedentary periods to minimum 30 minutes daily activity. Excessive sleep duration reduces metabolic rate and promotes lipid accumulation.', + + '运动会消耗能量并加速胃肠蠕动,这会使孩子的食欲大开,再配合均衡的营养有利于孩子维持合格的体重。' => 'Physical activity expends energy and intensifies gastrointestinal motility, substantially boosting children\'s appetite. Combined with balanced nutrition, this assists in maintaining healthy weight standards.', + + '体育运动可以有效刺激骨骼与全身关节,从而促进生长激素分泌,加速软骨细胞分裂,从而促进了身高的增长。' => 'Systematic exercise effectively activates skeletal and articular systems, stimulating growth hormone secretion and accelerating cartilage cell proliferation to optimize height development.', + + '坚持适当、科学的跳跃运动能够科学地增加学生体重,能够改善学生体重过低的情况;同时运动会消耗能量并加速胃肠蠕动,这会使孩子的食欲大开,再配合均衡的营养有利于孩子增重。' => 'Consistent, properly-designed jumping exercises can scientifically increase students\' body mass and correct underweight conditions. Concurrently, physical training consumes energy and enhances digestive motility, stimulating appetite which - when supported by nutritional balance - promotes healthy weight gain.', + '《中华人民共和国卫生行业标准WS 423-2013》' => "《Chinese Health Industry Standard WS 423-2013》", '《中华人民共和国卫生行业标准WS/T 612-2018》' => "《Chinese Health Industry Standard WS/T 612-2018》", '《中华人民共和国卫生行业标准WS/T1586-2018》' => "《Chinese Health Industry Standard WS/T 1586-2018》", '《WHO 5~19岁身高/体重判定标准》' => "《WHO Growth Reference for Children and Adolescents (5–19 Years)》", '头围' => "Head Circumference", '头围是指绕头部一周的最大长度,头围的大小与脑的发育密切相关' => "Head circumference refers to the maximum length around the head. Its measurement is closely related to brain development.", - + '跳绳数量或者分钟、秒钟值必须为整数' => 'The number of jump ropes, minutes, or seconds must be integers.', + '跳绳数不能小于等于0' => 'The jump rope count cannot be less than or equal to 0.', + '秒钟值不能大于60' => 'The seconds value cannot exceed 60.', + '跳绳个数(个)' => 'Jump rope count (times)', + '跳绳时长(分钟)' => 'Jump rope duration (minutes)', + '消耗卡路里(kcal)' => 'Calories burned (kcal)', + '个数' => 'Count', + '时长' => 'Duration', + '卡路里' => 'Calories', + '第一次' => 'First try', + '第二次' => 'Second try', + '第三次' => 'Third try', + '三次平均' => 'Average of three', + '最后成绩' => 'Final score', + '分' => 'Score', + '平均' => 'Average', + '成绩' => 'Score', + '时间(天)' => 'Time (days)', + '增重(kg)' => 'Weight gain (kg)', + '减脂(kg)' => 'Fat loss (kg)', + '数据变化' => 'Data changes', + '趋势' => 'Trend', + '之前' => 'Before', + '之后' => 'After', + '异常' => 'Abnormal', ], // 可以添加更多语言映射 ]; @@ -104,14 +213,14 @@ class Language extends Base // dump($data); // 验证语言是否支持 if (!$this->isLanguageSupported($language)) { - return $this->msg($data['data']); + return $data; } // 如果是数组,递归处理每个元素 if (is_array($data)) { // dump(2); $data = $this->translateArray($language, $data); - return $this->msg($data['data']); + return $data; } // 如果是字符串,直接翻译 @@ -122,7 +231,7 @@ class Language extends Base // dump($data); // 其他类型直接返回 - return $this->msg($data['data']); + return $data; } /** diff --git a/application/testapp/controller/Login.php b/application/testapp/controller/Login.php index cd8f044..acfa417 100644 --- a/application/testapp/controller/Login.php +++ b/application/testapp/controller/Login.php @@ -1,11 +1,11 @@ 'app_account_number', + '1'=>'app_account_number_copy1', ]; ################################################################接口################################################################ @@ -413,7 +413,8 @@ class Login extends Base{ * $type(验证类型,是注册用,还是其他用途) 字符串 默认register(注册)(register、login、reset_password) * $road(是手机还是邮箱还是其他) 字符串 默认tel或email */ - public function send_phone_email_code($data = ['data'=>'18736019909']){ + //18736019909 18530934717 + public function send_phone_email_code($data = ['data'=>'18530934717']){ if(count(input('post.')) > 0){ $data = input('post.'); @@ -428,8 +429,12 @@ class Login extends Base{ $num = mt_rand(100000,999999); if (preg_match('/^\d{11}$/', $data['data'])) { + // 本公司短信 $result = $this->send_tel_code($data['data'],$num); - // return $this->msg($result); + // 阿里云短信 + // $sms_all = new Smsaliyun; + // $result = $sms_all->send_sms($data['data'],$num); + // dump($result); $road = 'tel'; }else{ $result = $this->send_email_code([$data['data']],['title'=>'体测APP验证码','from_user_name'=>'体测APP','content'=>$num]); @@ -467,13 +472,10 @@ class Login extends Base{ // 设置POST数据 $postData = array( 'phone' => $tel, - // 'content' => '您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码三分钟内有效,若非本人操作,请忽略!' - // 'content' => '【Reedaw】您好,欢迎使用Reedaw,您的验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' 'content' => '【巨天】您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' + // 'content' => '【郑州品传科技】您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' // 'content' => '【小白秤】您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' - // 'content' => '【品传科技】您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' - // 'content' => '【巨天】您好,欢迎使用巨天,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略!' - + // 'content' => '【郑州巨天信息】您好,欢迎使用Reedaw,您的手机验证码是:'.$code.',验证码一分钟内有效,若非本人操作,请忽略本短信' ); $postData = json_encode($postData); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); @@ -481,6 +483,7 @@ class Login extends Base{ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 发送请求并获取响应 $response = curl_exec($ch); + // dump($response); // 检查是否有错误发生 if (curl_errno($ch)) { $error_message = curl_error($ch); @@ -489,7 +492,7 @@ class Login extends Base{ // 关闭cURL会话 curl_close($ch); // 处理响应 - + // dump(json_decode($response,true)); if ($response) { return json_decode($response,true); } else { diff --git a/application/testapp/controller/Msginformation.php b/application/testapp/controller/Msginformation.php index 9139895..9ecded9 100644 --- a/application/testapp/controller/Msginformation.php +++ b/application/testapp/controller/Msginformation.php @@ -1,6 +1,6 @@ 'admin_editor_text_content', - '2'=>'admin_editor_text_like_up_log', - '3'=>'admin_notice_banner', - '4'=>'admin_business_cooperation' + '1'=>'admin_editor_text_content_copy1', + '2'=>'admin_editor_text_like_up_log_copy1', + '3'=>'admin_notice_banner_copy1', + '4'=>'admin_business_cooperation_copy1' ]; protected $page_num = 10; // 加 bcadd(,,20) diff --git a/application/testapp/controller/Myinformation.php b/application/testapp/controller/Myinformation.php index 69c9574..cf923dd 100644 --- a/application/testapp/controller/Myinformation.php +++ b/application/testapp/controller/Myinformation.php @@ -1,15 +1,15 @@ 'app_account_number', + '1'=>'app_account_number_copy1', ]; // 加 bcadd(,,20) // 减 bcsub(,,20) diff --git a/application/testapp/controller/Pagingcontrast.php b/application/testapp/controller/Pagingcontrast.php index 29a543a..cb1386e 100644 --- a/application/testapp/controller/Pagingcontrast.php +++ b/application/testapp/controller/Pagingcontrast.php @@ -1,18 +1,18 @@ 'app_card_body_data','6'=>'app_card_skip_data','8'=>'app_card_vitalcapacity_data']; + protected $db_name = ['2'=>'app_card_body_data_copy1','6'=>'app_card_skip_data_copy1','8'=>'app_card_vitalcapacity_data_copy1']; protected $pagingcontrast_use_db_name = [ - '1'=>'app_card_body_data', - '2'=>'app_card_skip_data', - '3'=>'app_card_vitalcapacity_data', - '4'=>'app_user_data', + '1'=>'app_card_body_data_copy1', + '2'=>'app_card_skip_data_copy1', + '3'=>'app_card_vitalcapacity_data_copy1', + '4'=>'app_user_data_copy1', ]; protected $request_result = [ '2'=>['height'=>['身高','cm'],'weight'=>['体重','kg'],'age'=>['年龄','岁'],'bmi'=>['BMI',''],'head'=>['头围',''],'fat_w'=>['脂肪量','kg'],'fat_r'=>['脂肪率','%'],'muscleval'=>['肌肉量','kg'],'muscle'=>['肌肉率','%'],'proteinval'=>['蛋白量','kg'],'protein'=>['蛋白率','%'],'water'=>['水分',''],'bone'=>['骨重','kg'],'visceral'=>['内脏指数',''],'sfr'=>['皮下脂肪','%'],'kcal'=>['基础代谢','kcal'],'un_fat_w_weight'=>['去脂体重','kg'],'body_age'=>['体龄',''],'body_level'=>['肥胖等级',''],'body_type'=>['体型','']], @@ -69,7 +69,7 @@ class Pagingcontrast extends Base{ } // 获取记录信息(分页)(包含身体、跳绳、肺活量) - public function get_all_record_data_page($data = ['aud_id'=>'11','page'=>1,'token'=>'0dafb98a10995c98b5a33b7d59d986ca','type'=>'2']){ + public function get_all_record_data_page($data = ['aud_id'=>'144','page'=>1,'token'=>'caadd1be045a65f30b92aa805f1de54a','type'=>'8']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -87,7 +87,7 @@ class Pagingcontrast extends Base{ if(!$this->verify_data_is_ok($data['type'],'intnum')){ return $this->msg(10005); } - unset($data['token']); + // unset($data['token']); if(array_key_exists($data['type'],$this->db_name)){ $return_data = $this->jump_transfer_interface_record($data,'page'); }else{ @@ -112,7 +112,7 @@ class Pagingcontrast extends Base{ } // 获取详细历史数据信息(包含身体、跳绳、肺活量) - public function get_all_record_detailed_information($data = ['id'=>'36','type'=>'8','token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ + public function get_all_record_detailed_information($data = ['id'=>'3802','type'=>'2','aan_id'=>'1841','token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -458,6 +458,8 @@ class Pagingcontrast extends Base{ // $for_data_arr = ['height'=>['身高','cm'],'weight'=>['体重','kg'],'age'=>['年龄','岁'],'bmi'=>['BMI','']]; // } $result_data = []; + // dump($result); + // dump($for_data_arr); foreach ($for_data_arr as $key => $value) { $temporary_arr['key_name'] = $key; $temporary_arr['name'] = $value[0]; @@ -471,10 +473,16 @@ class Pagingcontrast extends Base{ $temporary_arr['value'] = explode(',',$result[$key])[0]; } }else{ + if($key == 'un_fat_w_weight'){ $temporary_arr['value'] = bcsub(explode(',',$result['weight'])[0],explode(',',$result['fat_w'])[0],2); }else{ - $temporary_arr['value'] = explode(',',$result[$key])[0]; + // dump($key); + // dump($result[$key]); + if(array_key_exists($key,$result)){ + $temporary_arr['value'] = explode(',',$result[$key])[0]; + } + } } diff --git a/application/testapp/controller/Skip.php b/application/testapp/controller/Skip.php index 0dbc8fe..47e3243 100644 --- a/application/testapp/controller/Skip.php +++ b/application/testapp/controller/Skip.php @@ -1,6 +1,6 @@ ['跳绳个数','个','#009DFF'],'jump_time'=>['跳绳时长','分钟','#009DFF'],'jump_kcal'=>['消耗卡路里','kcal','#009DFF']]; protected $skip_use_db_name = [ - '1'=>'app_card_skip_data', - '2'=>'app_user_data', - '3'=>'app_card_body_data', + '1'=>'app_card_skip_data_copy1', + '2'=>'app_user_data_copy1', + '3'=>'app_card_body_data_copy1', + '4'=>'app_account_number_copy1', ]; protected $result_end_data_mould = [ 'name'=>'', @@ -29,7 +30,7 @@ class Skip extends Base{ ################################################################接口################################################################ ################################################################接口################################################################ // 手动记录 - public function skip_manual_recording($data = ['aud_id'=>'61','r_time'=>'2024-07-24','num'=>'369','time_m'=>'02','time_s'=>'42','type'=>'free','token'=>'caadd1be045a65f30b92aa805f1de54a']){ + public function skip_manual_recording($data = ['aud_id'=>'144','r_time'=>'2024-07-24','num'=>'369','time_m'=>'02','time_s'=>'42','type'=>'free','token'=>'caadd1be045a65f30b92aa805f1de54a']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -137,7 +138,7 @@ class Skip extends Base{ } // 今日数据 - public function skip_today_data($data = ['aud_id'=>'26','token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ + public function skip_today_data($data = ['aud_id'=>'144','token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -153,7 +154,7 @@ class Skip extends Base{ $return_data = $this->skip_today_data_action($data); // 成功 - $this->record_api_log($data, null, $return_data); + // $this->record_api_log($data, null, $return_data); return $return_data; } catch (\Exception $e) { // 捕获异常 @@ -171,7 +172,7 @@ class Skip extends Base{ } // 曲线 - public function skip_curve_chart($data = ['aud_id'=>'9','time'=>'2024-10','token'=>'0dafb98a10995c98b5a33b7d59d986ca']){ + public function skip_curve_chart($data = ['aud_id'=>'144','time'=>'2025-04','token'=>'caadd1be045a65f30b92aa805f1de54a']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -183,7 +184,6 @@ class Skip extends Base{ if(!$this->verify_data_is_ok($data['aud_id'],'intnum')){ return $this->msg(10005); } - unset($data['token']); $return_data = $this->skip_curve_chart_action($data); // 成功 @@ -422,6 +422,16 @@ class Skip extends Base{ // $return_data[1]['line']['series'][0]['data'][$key] = $jump_time_long['h'].':'.$jump_time_long['m'].':'.$jump_time_long['s']; } + // dump($return_data); + $language_str = Db::table($this->skip_use_db_name['4'])->where(['token'=>$data['token']])->field('language')->find(); + $language_data = new Language(); + if(!$language_str['language']){ + $language_str['language'] = 'zh-Hans'; + } + // dump($language_str['language']); + $return_data = $language_data->handling_languages_from_multiple_countries($language_str['language'], $return_data); + // dump($return_data); + // die; return $this->msg($return_data); } diff --git a/application/testapp/controller/Smsaliyun.php b/application/testapp/controller/Smsaliyun.php new file mode 100644 index 0000000..40c9e3b --- /dev/null +++ b/application/testapp/controller/Smsaliyun.php @@ -0,0 +1,84 @@ + 'LTAI5tQCdWe9Epir3ydXWbzp', + 'accessKeySecret' => 'JKLzF0b5AXw2ajhwtem2fhPSUZVOZ5', + 'signName' => '郑州巨天信息', + 'templateCode' => 'SMS_484085215', + 'regionId' => 'cn-hangzhou' + ]; + + /** + * 发送短信接口 + * @param string $phone 手机号 + * @param string $code 验证码 + */ + public function send_sms($phone='18530934717', $code='0932') + { + try { + // 初始化阿里云客户端 + AlibabaCloud::accessKeyClient( + $this->smsConfig['accessKeyId'], + $this->smsConfig['accessKeySecret'] + ) + ->regionId($this->smsConfig['regionId']) + ->asDefaultClient(); + + // 发送短信请求 + $result = AlibabaCloud::rpc() + ->product('Dysmsapi') + ->version('2017-05-25') + ->action('SendSms') + ->method('POST') + ->host('dysmsapi.aliyuncs.com') + ->options([ + 'query' => [ + 'RegionId' => $this->smsConfig['regionId'], + 'PhoneNumbers' => $phone, + 'SignName' => $this->smsConfig['signName'], + 'TemplateCode' => $this->smsConfig['templateCode'], + 'TemplateParam' => json_encode(['code' => $code]), + ], + ]) + ->request(); + + $result = $result->toArray(); + + if ($result['Code'] == 'OK') { + return [ + 'code' => 0, + 'message' => '短信发送成功', + 'data' => $result + ]; + } else { + return [ + 'code' => 99999, + 'message' => $result['Message'], + 'error' => $result + ]; + } + } catch (ClientException $e) { + return [ + 'code' => 99998, + 'message' => '客户端异常: ' . $e->getErrorMessage(), + 'error' => $e->getMessage() + ]; + } catch (ServerException $e) { + return [ + 'code' => 99997, + 'message' => '服务端异常: ' . $e->getErrorMessage(), + 'error' => $e->getMessage() + ]; + } + } +} \ No newline at end of file diff --git a/application/testapp/controller/Sportstesting.php b/application/testapp/controller/Sportstesting.php index 0b2e856..c707783 100644 --- a/application/testapp/controller/Sportstesting.php +++ b/application/testapp/controller/Sportstesting.php @@ -1,6 +1,6 @@ 'admin_estimate', - '2'=>'app_sportstesting_data', - '3'=>'app_user_data', + '1'=>'admin_estimate_copy1', + '2'=>'app_sportstesting_data_copy1', + '3'=>'app_user_data_copy1', ]; protected $page_num = 10; protected $default_address = '上海'; diff --git a/application/testapp/controller/Vitalcapacity.php b/application/testapp/controller/Vitalcapacity.php index 03902ac..fe64f70 100644 --- a/application/testapp/controller/Vitalcapacity.php +++ b/application/testapp/controller/Vitalcapacity.php @@ -1,6 +1,6 @@ '0','max_val'=>'9','text'=>'无效','color'=>'#FF5656'], ]; protected $vitalcapacity_use_db_name = [ - '1'=>'app_user_data', - '2'=>'app_card_vitalcapacity_data', - '3'=>'pc_vitalcapacity_standard', + '1'=>'app_user_data_copy1', + '2'=>'app_card_vitalcapacity_data_copy1', + '3'=>'pc_vitalcapacity_standard_copy1', ]; protected $result_end_data_mould = [ 'name'=>'', @@ -107,7 +107,7 @@ class Vitalcapacity extends Base{ } // 数据报告 - public function vitalcapacity_data_report($data = ['aud_id'=>'83','token'=>'caadd1be045a65f30b92aa805f1de54a']){ + public function vitalcapacity_data_report($data = ['aud_id'=>'144','token'=>'caadd1be045a65f30b92aa805f1de54a']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ diff --git a/application/testapp/controller/Wechat.php b/application/testapp/controller/Wechat.php index 53d19e4..9b35c95 100644 --- a/application/testapp/controller/Wechat.php +++ b/application/testapp/controller/Wechat.php @@ -1,6 +1,6 @@ 'admin_editor_text_content', - '2'=>'admin_editor_text_like_up_log', + '1'=>'admin_editor_text_content_copy1', + '2'=>'admin_editor_text_like_up_log_copy1', ]; protected $page_num = 10; // 加 bcadd(,,20) diff --git a/composer.json b/composer.json index 1a7fa4c..78988bd 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "phpmailer/phpmailer": "^6.9", "phpoffice/phpspreadsheet": "^1.25", "overtrue/wechat": "~4.0", - "zoujingli/ip2region": "^2.0" + "zoujingli/ip2region": "^2.0", + "alibabacloud/client": "^1.5" }, "autoload": { "psr-4": { diff --git a/vendor/adbario/php-dot-notation/LICENSE.md b/vendor/adbario/php-dot-notation/LICENSE.md new file mode 100644 index 0000000..fe01323 --- /dev/null +++ b/vendor/adbario/php-dot-notation/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2016-2019 Riku Särkinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/adbario/php-dot-notation/composer.json b/vendor/adbario/php-dot-notation/composer.json new file mode 100644 index 0000000..cea7126 --- /dev/null +++ b/vendor/adbario/php-dot-notation/composer.json @@ -0,0 +1,29 @@ +{ + "name": "adbario/php-dot-notation", + "description": "PHP dot notation access to arrays", + "keywords": ["dotnotation", "arrayaccess"], + "homepage": "https://github.com/adbario/php-dot-notation", + "license": "MIT", + "authors": [ + { + "name": "Riku Särkinen", + "email": "riku@adbar.io" + } + ], + "require": { + "php": "^5.5 || ^7.0 || ^8.0", + "ext-json": "*" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Adbar\\": "src" + } + } +} diff --git a/vendor/adbario/php-dot-notation/src/Dot.php b/vendor/adbario/php-dot-notation/src/Dot.php new file mode 100644 index 0000000..3cd1c50 --- /dev/null +++ b/vendor/adbario/php-dot-notation/src/Dot.php @@ -0,0 +1,623 @@ + + * @link https://github.com/adbario/php-dot-notation + * @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License) + */ +namespace Adbar; + +use Countable; +use ArrayAccess; +use ArrayIterator; +use JsonSerializable; +use IteratorAggregate; + +/** + * Dot + * + * This class provides a dot notation access and helper functions for + * working with arrays of data. Inspired by Laravel Collection. + */ +class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable +{ + /** + * The stored items + * + * @var array + */ + protected $items = []; + + + /** + * The delimiter (alternative to a '.') to be used. + * + * @var string + */ + protected $delimiter = '.'; + + + /** + * Create a new Dot instance + * + * @param mixed $items + * @param string $delimiter + */ + public function __construct($items = [], $delimiter = '.') + { + $this->items = $this->getArrayItems($items); + $this->delimiter = strlen($delimiter) ? $delimiter : '.'; + } + + /** + * Set a given key / value pair or pairs + * if the key doesn't exist already + * + * @param array|int|string $keys + * @param mixed $value + */ + public function add($keys, $value = null) + { + if (is_array($keys)) { + foreach ($keys as $key => $value) { + $this->add($key, $value); + } + } elseif (is_null($this->get($keys))) { + $this->set($keys, $value); + } + } + + /** + * Return all the stored items + * + * @return array + */ + public function all() + { + return $this->items; + } + + /** + * Delete the contents of a given key or keys + * + * @param array|int|string|null $keys + */ + public function clear($keys = null) + { + if (is_null($keys)) { + $this->items = []; + + return; + } + + $keys = (array) $keys; + + foreach ($keys as $key) { + $this->set($key, []); + } + } + + /** + * Delete the given key or keys + * + * @param array|int|string $keys + */ + public function delete($keys) + { + $keys = (array) $keys; + + foreach ($keys as $key) { + if ($this->exists($this->items, $key)) { + unset($this->items[$key]); + + continue; + } + + $items = &$this->items; + $segments = explode($this->delimiter, $key); + $lastSegment = array_pop($segments); + + foreach ($segments as $segment) { + if (!isset($items[$segment]) || !is_array($items[$segment])) { + continue 2; + } + + $items = &$items[$segment]; + } + + unset($items[$lastSegment]); + } + } + + /** + * Checks if the given key exists in the provided array. + * + * @param array $array Array to validate + * @param int|string $key The key to look for + * + * @return bool + */ + protected function exists($array, $key) + { + return array_key_exists($key, $array); + } + + /** + * Flatten an array with the given character as a key delimiter + * + * @param string $delimiter + * @param array|null $items + * @param string $prepend + * @return array + */ + public function flatten($delimiter = '.', $items = null, $prepend = '') + { + $flatten = []; + + if (is_null($items)) { + $items = $this->items; + } + + if (!func_num_args()) { + $delimiter = $this->delimiter; + } + + foreach ($items as $key => $value) { + if (is_array($value) && !empty($value)) { + $flatten = array_merge( + $flatten, + $this->flatten($delimiter, $value, $prepend.$key.$delimiter) + ); + } else { + $flatten[$prepend.$key] = $value; + } + } + + return $flatten; + } + + /** + * Return the value of a given key + * + * @param int|string|null $key + * @param mixed $default + * @return mixed + */ + public function get($key = null, $default = null) + { + if (is_null($key)) { + return $this->items; + } + + if ($this->exists($this->items, $key)) { + return $this->items[$key]; + } + + if (strpos($key, $this->delimiter) === false) { + return $default; + } + + $items = $this->items; + + foreach (explode($this->delimiter, $key) as $segment) { + if (!is_array($items) || !$this->exists($items, $segment)) { + return $default; + } + + $items = &$items[$segment]; + } + + return $items; + } + + /** + * Return the given items as an array + * + * @param mixed $items + * @return array + */ + protected function getArrayItems($items) + { + if (is_array($items)) { + return $items; + } elseif ($items instanceof self) { + return $items->all(); + } + + return (array) $items; + } + + /** + * Check if a given key or keys exists + * + * @param array|int|string $keys + * @return bool + */ + public function has($keys) + { + $keys = (array) $keys; + + if (!$this->items || $keys === []) { + return false; + } + + foreach ($keys as $key) { + $items = $this->items; + + if ($this->exists($items, $key)) { + continue; + } + + foreach (explode($this->delimiter, $key) as $segment) { + if (!is_array($items) || !$this->exists($items, $segment)) { + return false; + } + + $items = $items[$segment]; + } + } + + return true; + } + + /** + * Check if a given key or keys are empty + * + * @param array|int|string|null $keys + * @return bool + */ + public function isEmpty($keys = null) + { + if (is_null($keys)) { + return empty($this->items); + } + + $keys = (array) $keys; + + foreach ($keys as $key) { + if (!empty($this->get($key))) { + return false; + } + } + + return true; + } + + /** + * Merge a given array or a Dot object with the given key + * or with the whole Dot object + * + * @param array|string|self $key + * @param array|self $value + */ + public function merge($key, $value = []) + { + if (is_array($key)) { + $this->items = array_merge($this->items, $key); + } elseif (is_string($key)) { + $items = (array) $this->get($key); + $value = array_merge($items, $this->getArrayItems($value)); + + $this->set($key, $value); + } elseif ($key instanceof self) { + $this->items = array_merge($this->items, $key->all()); + } + } + + /** + * Recursively merge a given array or a Dot object with the given key + * or with the whole Dot object. + * + * Duplicate keys are converted to arrays. + * + * @param array|string|self $key + * @param array|self $value + */ + public function mergeRecursive($key, $value = []) + { + if (is_array($key)) { + $this->items = array_merge_recursive($this->items, $key); + } elseif (is_string($key)) { + $items = (array) $this->get($key); + $value = array_merge_recursive($items, $this->getArrayItems($value)); + + $this->set($key, $value); + } elseif ($key instanceof self) { + $this->items = array_merge_recursive($this->items, $key->all()); + } + } + + /** + * Recursively merge a given array or a Dot object with the given key + * or with the whole Dot object. + * + * Instead of converting duplicate keys to arrays, the value from + * given array will replace the value in Dot object. + * + * @param array|string|self $key + * @param array|self $value + */ + public function mergeRecursiveDistinct($key, $value = []) + { + if (is_array($key)) { + $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key); + } elseif (is_string($key)) { + $items = (array) $this->get($key); + $value = $this->arrayMergeRecursiveDistinct($items, $this->getArrayItems($value)); + + $this->set($key, $value); + } elseif ($key instanceof self) { + $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key->all()); + } + } + + /** + * Merges two arrays recursively. In contrast to array_merge_recursive, + * duplicate keys are not converted to arrays but rather overwrite the + * value in the first array with the duplicate value in the second array. + * + * @param array $array1 Initial array to merge + * @param array $array2 Array to recursively merge + * @return array + */ + protected function arrayMergeRecursiveDistinct(array $array1, array $array2) + { + $merged = &$array1; + + foreach ($array2 as $key => $value) { + if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { + $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value); + } else { + $merged[$key] = $value; + } + } + + return $merged; + } + + /** + * Return the value of a given key and + * delete the key + * + * @param int|string|null $key + * @param mixed $default + * @return mixed + */ + public function pull($key = null, $default = null) + { + if (is_null($key)) { + $value = $this->all(); + $this->clear(); + + return $value; + } + + $value = $this->get($key, $default); + $this->delete($key); + + return $value; + } + + /** + * Push a given value to the end of the array + * in a given key + * + * @param mixed $key + * @param mixed $value + */ + public function push($key, $value = null) + { + if (is_null($value)) { + $this->items[] = $key; + + return; + } + + $items = $this->get($key); + + if (is_array($items) || is_null($items)) { + $items[] = $value; + $this->set($key, $items); + } + } + + /** + * Replace all values or values within the given key + * with an array or Dot object + * + * @param array|string|self $key + * @param array|self $value + */ + public function replace($key, $value = []) + { + if (is_array($key)) { + $this->items = array_replace($this->items, $key); + } elseif (is_string($key)) { + $items = (array) $this->get($key); + $value = array_replace($items, $this->getArrayItems($value)); + + $this->set($key, $value); + } elseif ($key instanceof self) { + $this->items = array_replace($this->items, $key->all()); + } + } + + /** + * Set a given key / value pair or pairs + * + * @param array|int|string $keys + * @param mixed $value + */ + public function set($keys, $value = null) + { + if (is_array($keys)) { + foreach ($keys as $key => $value) { + $this->set($key, $value); + } + + return; + } + + $items = &$this->items; + + foreach (explode($this->delimiter, $keys) as $key) { + if (!isset($items[$key]) || !is_array($items[$key])) { + $items[$key] = []; + } + + $items = &$items[$key]; + } + + $items = $value; + } + + /** + * Replace all items with a given array + * + * @param mixed $items + */ + public function setArray($items) + { + $this->items = $this->getArrayItems($items); + } + + /** + * Replace all items with a given array as a reference + * + * @param array $items + */ + public function setReference(array &$items) + { + $this->items = &$items; + } + + /** + * Return the value of a given key or all the values as JSON + * + * @param mixed $key + * @param int $options + * @return string + */ + public function toJson($key = null, $options = 0) + { + if (is_string($key)) { + return json_encode($this->get($key), $options); + } + + $options = $key === null ? 0 : $key; + + return json_encode($this->items, $options); + } + + /* + * -------------------------------------------------------------- + * ArrayAccess interface + * -------------------------------------------------------------- + */ + + /** + * Check if a given key exists + * + * @param int|string $key + * @return bool + */ + #[\ReturnTypeWillChange] + public function offsetExists($key) + { + return $this->has($key); + } + + /** + * Return the value of a given key + * + * @param int|string $key + * @return mixed + */ + #[\ReturnTypeWillChange] + public function offsetGet($key) + { + return $this->get($key); + } + + /** + * Set a given value to the given key + * + * @param int|string|null $key + * @param mixed $value + */ + #[\ReturnTypeWillChange] + public function offsetSet($key, $value) + { + if (is_null($key)) { + $this->items[] = $value; + + return; + } + + $this->set($key, $value); + } + + /** + * Delete the given key + * + * @param int|string $key + */ + #[\ReturnTypeWillChange] + public function offsetUnset($key) + { + $this->delete($key); + } + + /* + * -------------------------------------------------------------- + * Countable interface + * -------------------------------------------------------------- + */ + + /** + * Return the number of items in a given key + * + * @param int|string|null $key + * @return int + */ + #[\ReturnTypeWillChange] + public function count($key = null) + { + return count($this->get($key)); + } + + /* + * -------------------------------------------------------------- + * IteratorAggregate interface + * -------------------------------------------------------------- + */ + + /** + * Get an iterator for the stored items + * + * @return \ArrayIterator + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + return new ArrayIterator($this->items); + } + + /* + * -------------------------------------------------------------- + * JsonSerializable interface + * -------------------------------------------------------------- + */ + + /** + * Return items for JSON serialization + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->items; + } +} diff --git a/vendor/adbario/php-dot-notation/src/helpers.php b/vendor/adbario/php-dot-notation/src/helpers.php new file mode 100644 index 0000000..bebb952 --- /dev/null +++ b/vendor/adbario/php-dot-notation/src/helpers.php @@ -0,0 +1,24 @@ + + * @link https://github.com/adbario/php-dot-notation + * @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License) + */ + +use Adbar\Dot; + +if (! function_exists('dot')) { + /** + * Create a new Dot object with the given items and optional delimiter + * + * @param mixed $items + * @param string $delimiter + * @return \Adbar\Dot + */ + function dot($items, $delimiter = '.') + { + return new Dot($items, $delimiter); + } +} diff --git a/vendor/alibabacloud/client/CHANGELOG.md b/vendor/alibabacloud/client/CHANGELOG.md new file mode 100644 index 0000000..ad5fcf8 --- /dev/null +++ b/vendor/alibabacloud/client/CHANGELOG.md @@ -0,0 +1,311 @@ +# CHANGELOG + +## 1.5.32 - 2022-12-08 + +- Support PHP versions: From 5.5 up to 8.1 + +## 1.5.31 - 2021-05-13 + +- Deprecate `\GuzzleHttp\Psr7\parse_query` method + +## 1.5.30 - 2021-03-22 +- Fixed incompatibility in PHP 5.6 version. + +## 1.5.29 - 2020-08-03 +- Fixed RPC Signature. + +## 1.5.28 - 2020-08-03 +- Updated `endpoints`. + +## 1.5.27 - 2020-07-17 +- Fixed composer error config. + +## 1.5.26 - 2020-07-17 +- Validate RegionID/EndpointSuffix/Network. + +## 1.5.25 - 2020-07-04 +- Fixed ROA signature. +- Deprecated `LogFormatter`. + +## 1.5.24 - 2020-06-04 +- Fixed Resolve Host. + +## 1.5.23 - 2020-05-22 +- Optimized global product support. + +## 1.5.22 - 2020-05-12 +- Updated Endpoints. + +## 1.5.21 - 2020-02-26 +- Improved Nonce. +- Updated Endpoints. + +## 1.5.20 - 2019-12-30 +- Improved Docs. +- Updated Endpoints. + +## 1.5.19 - 2019-12-17 +- Updated Endpoints. + +## 1.5.18 - 2019-10-11 +- Updated Request link. +- Updated Endpoints data. + +## 1.5.17 - 2019-09-15 +- Improved Host Finder. +- Updated Endpoints Data. + +## 1.5.16 - 2019-08-21 +- Updated Endpoints Data. + +## 1.5.15 - 2019-08-14 +- Improved Client. + + +## 1.5.14 - 2019-07-25 +- Improved Credential Filter. + + +## 1.5.13 - 2019-07-18 +- Improved API Resolver. + + +## 1.5.12 - 2019-06-20 +- Fixed Signature for ROA. + + +## 1.5.11 - 2019-06-14 +- Added endpoint rules. + + +## 1.5.10 - 2019-06-13 +- Improved `Resovler`. +- Updated `endpoints`. + + +## 1.5.9 - 2019-06-04 +- Improved `UUID`. + + +## 1.5.8 - 2019-05-30 +- Improved `Arrays`. + + +## 1.5.7 - 2019-05-29 +- Improved `uuid`. + + +## 1.5.6 - 2019-05-29 +- Fixed `uuid` version lock. + + +## 1.5.5 - 2019-05-23 +- Improved `Signature`. + + +## 1.5.4 - 2019-05-22 +- Updated `Endpoints`. +- Fixed `Content-Type` in header. + + +## 1.5.3 - 2019-05-13 +- Improved `Endpoint` tips. +- Improved `Endpoints` for `STS`. + + +## 1.5.2 - 2019-05-10 +- Improved `Result` object. + + +## 1.5.1 - 2019-05-09 +- Supported `Resolver` for Third-party dependencies. + + +## 1.5.0 - 2019-05-07 +- Improved `Resolver` for products. + + +## 1.4.0 - 2019-05-06 +- Support `Retry` and `Asynchronous` for Request. + + +## 1.3.1 - 2019-04-30 +- Allow timeouts to be set in microseconds. + + +## 1.3.0 - 2019-04-18 +- Improved parameters methods. +- Optimized the logic for body encode. + + +## 1.2.1 - 2019-04-11 +- Improve exception code and message for `Region ID`. + + +## 1.2.0 - 2019-04-11 +- Improve exception message for `Region ID`. + + +## 1.1.1 - 2019-04-02 +- Added endpoints for `batchcomputenew`, `privatelink`. +- Improve Region ID tips. + + +## 1.1.0 - 2019-04-01 +- Updated `composer.json`. + + +## 1.0.27 - 2019-03-31 +- Support `Policy` for `ramRoleArnClient`. + + +## 1.0.26 - 2019-03-27 +- Support `pid`, `cost`, `start_time` for Log. + + +## 1.0.25 - 2019-03-27 +- Updated default log format. +- Add endpoints for `dbs`. + + +## 1.0.24 - 2019-03-26 +- Support Log. + + +## 1.0.23 - 2019-03-23 +- Remove SVG. + + +## 1.0.22 - 2019-03-20 +- Add endpoint `cn-hangzhou` for `idaas` . + + +## 1.0.21 - 2019-03-19 +- Installing by Using the ZIP file. +- Update Docs. + + +## 1.0.20 - 2019-03-13 +- Improve Tests. +- Update Docs. + + +## 1.0.19 - 2019-03-12 +- Add SSL Verify Option `verify()`. + + +## 1.0.18 - 2019-03-11 +- Add endpoints for `acr`. +- Add endpoints for `faas`. +- Add endpoints for `ehs`. +- SSL certificates are not validated by default. + + +## 1.0.17 - 2019-03-08 +- Support Mock for Test. + + +## 1.0.16 - 2019-03-07 +- Support Credential Provider Chain. +- Support `CCC`. +- Add `ap-south-1` for `cas`. +- Add `ap-southeast-1` for `waf`. +- Update Docs. + + +## 1.0.15 - 2019-02-27 +- Add endpoints for `Chatbot`. +- Change endpoints for `drdspost` and `drdspre`. + + +## 1.0.14 - 2019-02-21 +- Enable debug mode by set environment variable `DEBUG=sdk`. + + +## 1.0.13 - 2019-02-18 +- Support Release Script `composer release`. +- Add endpoints for apigateway in `drdspre` in `cn-qingdao`. +- Add endpoints for apigateway in `drdspre` in `cn-beijing`. +- Add endpoints for apigateway in `drdspre` in `cn-hangzhou`. +- Add endpoints for apigateway in `drdspre` in `cn-shanghai`. +- Add endpoints for apigateway in `drdspre` in `cn-shenzhen`. +- Add endpoints for apigateway in `drdspre` in `cn-hongkong`. +- Add endpoints for apigateway in `drdspost` in `ap-southeast-1`. +- Add endpoints for apigateway in `drdspost` in `cn-shanghai`. +- Add endpoints for apigateway in `drdspost` in `cn-hongkong`. +- Add endpoints for apigateway in `vod` in `ap-southeast-1`. +- Add endpoints for apigateway in `vod` in `eu-central-1`. + + +## 1.0.12 - 2019-02-16 +- Support `open_basedir`. + + +## 1.0.11 - 2019-02-13 +- Improve User Agent. + + +## 1.0.10 - 2019-02-12 +- `userAgentAppend` is renamed to `appendUserAgent`. + + +## 1.0.9 - 2019-02-12 +- `userAgent` is renamed to `userAgentAppend`. + + +## 1.0.8 - 2019-02-11 +- `userAgent` - Support DIY User Agent. +- Add endpoints for apigateway in Zhangjiakou. +- Add endpoints for apigateway in Hu He Hao Te. +- Add endpoints for vod in Hu He Hao Te. +- Add endpoints for hsm in Zhangjiakou. +- Add endpoints for luban in Germany. +- Add endpoints for linkwan in Hangzhou. +- Add endpoints for drdspost in Singapore. + + +## 1.0.7 - 2019-01-28 +- Add endpoints for gpdb in Tokyo. +- Add endpoints for elasticsearch in Beijing. + + +## 1.0.6 - 2019-01-23 +- Add endpoints for dysmsapi in Singapore. +- Add endpoints for dybaseapi. +- Add endpoints for dyiotapi. +- Add endpoints for dycdpapi. +- Add endpoints for dyplsapi. +- Add endpoints for dypnsapi. +- Add endpoints for dyvmsapi. +- Add endpoints for snsuapi. + + +## 1.0.5 - 2019-01-21 +- Add endpoints for ApiGateway in Silicon Valley, Virginia. +- Add endpoints for Image Search in Shanghai. + + +## 1.0.4 - 2019-01-17 +- Support fixer all. +- Add Endpoints. + + +## 1.0.3 - 2019-01-15 +- Update Endpoints. +- Update README.md. +- Update Return Result Message. + + +## 1.0.2 - 2019-01-15 +- Optimize the documentation. +- Adjust the CI configuration. + + +## 1.0.1 - 2019-01-09 +- Distinguish credential error. +- Add endpoints for NLS. +- Add not found product tip. + + +## 1.0.0 - 2019-01-07 +- Initial release of the Alibaba Cloud Client for PHP Version 1.0.0 on Packagist See for more information. diff --git a/vendor/alibabacloud/client/CONTRIBUTING.md b/vendor/alibabacloud/client/CONTRIBUTING.md new file mode 100644 index 0000000..a1c52a0 --- /dev/null +++ b/vendor/alibabacloud/client/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Contributing to the Alibaba Cloud Client for PHP + +We work hard to provide a high-quality and useful SDK for Alibaba Cloud, and +we greatly value feedback and contributions from our community. Please submit +your [issues][issues] or [pull requests][pull-requests] through GitHub. + +## Tips + +- The SDK is released under the [Apache license][license]. Any code you submit + will be released under that license. For substantial contributions, we may + ask you to sign a [Alibaba Documentation Corporate Contributor License + Agreement (CLA)][cla]. +- We follow all of the relevant PSR recommendations from the [PHP Framework + Interop Group][php-fig]. Please submit code that follows these standards. + The [PHP CS Fixer][cs-fixer] tool can be helpful for formatting your code. + Your can use `composer fixer` to fix code. +- We maintain a high percentage of code coverage in our unit tests. If you make + changes to the code, please add, update, and/or remove tests as appropriate. +- If your code does not conform to the PSR standards, does not include adequate + tests, or does not contain a changelog document, we may ask you to update + your pull requests before we accept them. We also reserve the right to deny + any pull requests that do not align with our standards or goals. + +[issues]: https://github.com/aliyun/openapi-sdk-php-client/issues +[pull-requests]: https://github.com/aliyun/openapi-sdk-php-client/pulls +[license]: http://www.apache.org/licenses/LICENSE-2.0 +[cla]: https://alibaba-cla-2018.oss-cn-beijing.aliyuncs.com/Alibaba_Documentation_Open_Source_Corporate_CLA.pdf +[php-fig]: http://php-fig.org +[cs-fixer]: http://cs.sensiolabs.org/ +[docs-readme]: https://github.com/aliyun/openapi-sdk-php-client/blob/master/README.md diff --git a/vendor/alibabacloud/client/LICENSE.md b/vendor/alibabacloud/client/LICENSE.md new file mode 100644 index 0000000..ec13fcc --- /dev/null +++ b/vendor/alibabacloud/client/LICENSE.md @@ -0,0 +1,13 @@ +Copyright (c) 2009-present, Alibaba Cloud All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/alibabacloud/client/NOTICE.md b/vendor/alibabacloud/client/NOTICE.md new file mode 100644 index 0000000..db04164 --- /dev/null +++ b/vendor/alibabacloud/client/NOTICE.md @@ -0,0 +1,88 @@ +# Alibaba Cloud Client for PHP + + + +Copyright (c) 2009-present, Alibaba Cloud All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"). +You may not use this file except in compliance with the License. +A copy of the License is located at + + + +or in the "license" file accompanying this file. This file is distributed +on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +express or implied. See the License for the specific language governing +permissions and limitations under the License. + +# Guzzle + + + +Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling + +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. + +# jmespath.php + + + +Copyright (c) 2014 Michael Dowling, https://github.com/mtdowling + +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. + +# Dot + + + +Copyright (c) 2016-2019 Riku Särkinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/alibabacloud/client/README-zh-CN.md b/vendor/alibabacloud/client/README-zh-CN.md new file mode 100644 index 0000000..b27d282 --- /dev/null +++ b/vendor/alibabacloud/client/README-zh-CN.md @@ -0,0 +1,168 @@ +[English](/README.md) | 简体中文 + + +# Alibaba Cloud Client for PHP +[![Latest Stable Version](https://poser.pugx.org/alibabacloud/client/v/stable)](https://packagist.org/packages/alibabacloud/client) +[![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client) +[![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client) +[![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client) +[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg?token=90Yd5Bne3S)](https://codecov.io/gh/aliyun/openapi-sdk-php-client) +[![PHP Version Require](http://poser.pugx.org/alibabacloud/client/require/php)](https://packagist.org/packages/alibabacloud/client) + + +![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg) + + +Alibaba Cloud Client for PHP 是帮助 PHP 开发者管理凭据、发送请求的客户端工具,[Alibaba Cloud SDK for PHP][SDK] 由本工具提供底层支持。 + + +## 使用诊断 +[Troubleshoot](https://troubleshoot.api.aliyun.com/?source=github_sdk) 提供 OpenAPI 使用诊断服务,通过 `RequestID` 或 `报错信息` ,帮助开发者快速定位,为开发者提供解决方案。 + +## 在线示例 +[阿里云 OpenAPI 开发者门户]https://next.api.aliyun.com/) 提供在线调用阿里云产品,并动态生成 SDK 代码和快速检索接口等能力,能显著降低使用云 API 的难度。 + + +## 先决条件 +您的系统需要满足[先决条件](/docs/zh-CN/0-Prerequisites.md),包括 PHP> = 5.5。 我们强烈建议使用cURL扩展,并使用TLS后端编译cURL 7.16.2+。 + + +## 安装依赖 +如果已在系统上[全局安装 Composer](https://getcomposer.org/doc/00-intro.md#globally),请直接在项目目录中运行以下内容来安装 Alibaba Cloud Client for PHP 作为依赖项: +``` +composer require alibabacloud/client +``` +> 一些用户可能由于网络问题无法安装,可以使用[阿里云 Composer 全量镜像](https://developer.aliyun.com/composer)。 + +请看[安装](/docs/zh-CN/1-Installation.md)有关通过 Composer 和其他方式安装的详细信息。 + + +## 快速使用 +在您开始之前,您需要注册阿里云帐户并获取您的[凭证](https://usercenter.console.aliyun.com/#/manage/ak)。 + +```php +asDefaultClient(); +``` + + +## 请求 +> 请求风格分为 `ROA` 和 `RPC`,不同产品风格不同,使用前,请参考产品文档。推荐使用 [Alibaba Cloud SDK for PHP][SDK] ,细节已被封装,无需关心风格。 + + +### ROA 请求 +```php +regionId('cn-hangzhou') // 指定请求的区域,不指定则使用客户端区域、默认区域 + ->product('CS') // 指定产品 + ->version('2015-12-15') // 指定产品版本 + ->action('DescribeClusterServices') // 指定产品接口 + ->serviceCode('cs') // 设置 ServiceCode 以备寻址,非必须 + ->endpointType('openAPI') // 设置类型,非必须 + ->method('GET') // 指定请求方式 + ->host('cs.aliyun.com') // 指定域名则不会寻址,如认证方式为 Bearer Token 的服务则需要指定 + ->pathPattern('/clusters/[ClusterId]/services') // 指定ROA风格路径规则 + ->withClusterId('123456') // 为路径中参数赋值,方法名:with + 参数 + ->request(); // 发起请求并返回结果对象,请求需要放在设置的最后面 + + print_r($result->toArray()); + +} catch (ClientException $exception) { + print_r($exception->getErrorMessage()); +} catch (ServerException $exception) { + print_r($exception->getErrorMessage()); +} +``` + +### RPC 请求 +```php +product('Cdn') + ->version('2014-11-11') + ->action('DescribeCdnService') + ->method('POST') + ->request(); + + print_r($result->toArray()); + +} catch (ClientException $exception) { + print_r($exception->getErrorMessage()); +} catch (ServerException $exception) { + print_r($exception->getErrorMessage()); +} +``` + + +## 文档 +* [先决条件](/docs/zh-CN/0-Prerequisites.md) +* [安装](/docs/zh-CN/1-Installation.md) +* [客户端和凭证](/docs/zh-CN/2-Client.md) +* [请求](/docs/zh-CN/3-Request.md) +* [结果](/docs/zh-CN/4-Result.md) +* [区域](/docs/zh-CN/5-Region.md) +* [域名](/docs/zh-CN/6-Host.md) +* [SSL 验证](/docs/zh-CN/7-Verify.md) +* [调试](/docs/zh-CN/8-Debug.md) +* [日志](/docs/zh-CN/9-Log.md) +* [测试](/docs/zh-CN/10-Test.md) + + +## 问题 +[提交 Issue](https://github.com/aliyun/openapi-sdk-php-client/issues/new/choose),不符合指南的问题可能会立即关闭。 + + +## 发行说明 +每个版本的详细更改记录在[发行说明](/CHANGELOG.md)中。 + + +## 贡献 +提交 Pull Request 之前请阅读[贡献指南](/CONTRIBUTING.md)。 + + +## 相关 +* [阿里云服务 Regions & Endpoints][endpoints] +* [阿里云 OpenAPI 开发者门户][open-api] +* [Packagist][packagist] +* [Composer][composer] +* [Guzzle中文文档][guzzle-docs] +* [最新源码][latest-release] + + +## 许可证 +[Apache-2.0](/LICENSE.md) + +Copyright (c) 2009-present, Alibaba Cloud All rights reserved. + + +[SDK]: https://github.com/aliyun/openapi-sdk-php +[open-api]: https://next.api.aliyun.com/ +[latest-release]: https://github.com/aliyun/openapi-sdk-php-client +[guzzle-docs]: https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html +[composer]: https://getcomposer.org +[packagist]: https://packagist.org/packages/alibabacloud/sdk +[home]: https://home.console.aliyun.com +[aliyun]: https://www.aliyun.com +[regions]: https://help.aliyun.com/document_detail/40654.html +[endpoints]: https://developer.aliyun.com/endpoints +[cURL]: http://php.net/manual/zh/book.curl.php +[OPCache]: http://php.net/manual/zh/book.opcache.php +[xdebug]: http://xdebug.org +[OpenSSL]: http://php.net/manual/zh/book.openssl.php +[client]: https://github.com/aliyun/openapi-sdk-php-client diff --git a/vendor/alibabacloud/client/README.md b/vendor/alibabacloud/client/README.md new file mode 100644 index 0000000..dacf2bf --- /dev/null +++ b/vendor/alibabacloud/client/README.md @@ -0,0 +1,167 @@ +English | [简体中文](/README-zh-CN.md) + + +# Alibaba Cloud Client for PHP +[![Latest Stable Version](https://poser.pugx.org/alibabacloud/client/v/stable)](https://packagist.org/packages/alibabacloud/client) +[![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client) +[![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client) +[![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client) +[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg?token=90Yd5Bne3S)](https://codecov.io/gh/aliyun/openapi-sdk-php-client) +[![PHP Version Require](http://poser.pugx.org/alibabacloud/client/require/php)](https://packagist.org/packages/alibabacloud/client) + + +![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg) + + +Alibaba Cloud Client for PHP is a client tool that helps PHP developers manage credentials and send requests, [Alibaba Cloud SDK for PHP][SDK] dependency on this tool. + +## Troubleshoot +[Troubleshoot](https://troubleshoot.api.aliyun.com/?source=github_sdk) Provide OpenAPI diagnosis service to help developers locate quickly and provide solutions for developers through `RequestID` or `error message`. + +## Online Demo +[Alibaba Cloud OpenAPI Developer Portal](https://next.api.aliyun.com/) provides the ability to call the cloud product OpenAPI online, and dynamically generate SDK Example code and quick retrieval interface, which can significantly reduce the difficulty of using the cloud API. + +## Prerequisites +Your system will need to meet the [Prerequisites](/docs/en-US/0-Prerequisites.md), including having PHP >= 5.5. We highly recommend having it compiled with the cURL extension and cURL 7.16.2+. + + +## Installation +If Composer is already [installed globally on your system](https://getcomposer.org/doc/00-intro.md#globally), run the following in the base directory of your project to install Alibaba Cloud Client for PHP as a dependency: +``` +composer require alibabacloud/client +``` +> Some users may not be able to install due to network problems, you can try to switch the Composer mirror. + +Please see the [Installation](/docs/en-US/1-Installation.md) for more detailed information about installing the Alibaba Cloud Client for PHP through Composer and other means. + + +## Quick Examples +Before you begin, you need to sign up for an Alibaba Cloud account and retrieve your [Credentials](https://usercenter.console.aliyun.com/#/manage/ak). + +### Create Client +```php +asDefaultClient(); +``` + + +## Request +> Request styles are divided into `ROA` and `RPC`. Different product styles are different. Please refer to the product documentation before using. It is recommended to use [Alibaba cloud SDK for PHP][SDK], the details have been encapsulated, and you do not need to care about the style. + + +### ROA Request +```php +regionId('cn-hangzhou') // Specify the requested regionId, if not specified, use the client regionId, then default regionId + ->product('CS') // Specify product + ->version('2015-12-15') // Specify product version + ->action('DescribeClusterServices') // Specify product interface + ->serviceCode('cs') // Set ServiceCode for addressing, optional + ->endpointType('openAPI') // Set type, optional + ->method('GET') // Set request method + ->host('cs.aliyun.com') // Location Service will not be enabled if the host is specified. For example, service with a Certification type-Bearer Token should be specified + ->pathPattern('/clusters/[ClusterId]/services') // Specify path rule with ROA-style + ->withClusterId('123456') // Assign values to parameters in the path. Method: with + Parameter + ->request(); // Make a request and return to result object. The request is to be placed at the end of the setting + + print_r($result->toArray()); + +} catch (ClientException $exception) { + print_r($exception->getErrorMessage()); +} catch (ServerException $exception) { + print_r($exception->getErrorMessage()); +} +``` + +### RPC Request +```php +product('Cdn') + ->version('2014-11-11') + ->action('DescribeCdnService') + ->method('POST') + ->request(); + + print_r($result->toArray()); + +} catch (ClientException $exception) { + print_r($exception->getErrorMessage()); +} catch (ServerException $exception) { + print_r($exception->getErrorMessage()); +} +``` + + +## Documentation +* [Prerequisites](/docs/en-US/0-Prerequisites.md) +* [Installation](/docs/en-US/1-Installation.md) +* [Client & Credentials](/docs/en-US/2-Client.md) +* [Request](/docs/en-US/3-Request.md) +* [Result](/docs/en-US/4-Result.md) +* [Region](/docs/en-US/5-Region.md) +* [Host](/docs/en-US/6-Host.md) +* [SSL Verify](/docs/en-US/7-Verify.md) +* [Debug](/docs/en-US/8-Debug.md) +* [Log](/docs/en-US/9-Log.md) +* [Test](/docs/en-US/10-Test.md) + + +## Issues +[Opening an Issue](https://github.com/aliyun/openapi-sdk-php-client/issues/new/choose), Issues not conforming to the guidelines may be closed immediately. + + +## Changelog +Detailed changes for each release are documented in the [release notes](/CHANGELOG.md). + + +## Contribution +Please make sure to read the [Contributing Guide](/CONTRIBUTING.md) before making a pull request. + + +## References +* [Alibaba Cloud Regions & Endpoints][endpoints] +* [Alibaba Cloud OpenAPI Developer Portal][open-api] +* [Packagist][packagist] +* [Composer][composer] +* [Guzzle Documentation][guzzle-docs] +* [Latest Release][latest-release] + + +## License +[Apache-2.0](/LICENSE.md) + +Copyright (c) 2009-present, Alibaba Cloud All rights reserved. + + +[SDK]: https://github.com/aliyun/openapi-sdk-php +[open-api]: https://next.api.aliyun.com/ +[latest-release]: https://github.com/aliyun/openapi-sdk-php-client +[guzzle-docs]: http://docs.guzzlephp.org/en/stable/request-options.html +[composer]: https://getcomposer.org +[packagist]: https://packagist.org/packages/alibabacloud/sdk +[home]: https://home.console.aliyun.com +[alibabacloud]: https://www.alibabacloud.com +[regions]: https://www.alibabacloud.com/help/doc-detail/40654.html +[endpoints]: https://developer.aliyun.com/endpoints +[cURL]: http://php.net/manual/en/book.curl.php +[OPCache]: http://php.net/manual/en/book.opcache.php +[xdebug]: http://xdebug.org +[OpenSSL]: http://php.net/manual/en/book.openssl.php +[client]: https://github.com/aliyun/openapi-sdk-php-client diff --git a/vendor/alibabacloud/client/UPGRADING.md b/vendor/alibabacloud/client/UPGRADING.md new file mode 100644 index 0000000..08c1bb3 --- /dev/null +++ b/vendor/alibabacloud/client/UPGRADING.md @@ -0,0 +1,6 @@ +Upgrading Guide +=============== + +1.x +----------------------- +- This is the first version. See for more information. diff --git a/vendor/alibabacloud/client/autoload.php b/vendor/alibabacloud/client/autoload.php new file mode 100644 index 0000000..e654320 --- /dev/null +++ b/vendor/alibabacloud/client/autoload.php @@ -0,0 +1,17 @@ +=5.5", + "ext-curl": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-openssl": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xmlwriter": "*", + "guzzlehttp/guzzle": "^6.3|^7.0", + "mtdowling/jmespath.php": "^2.5", + "adbario/php-dot-notation": "^2.4.1", + "clagiordano/weblibs-configmanager": "^1.0" + }, + "require-dev": { + "ext-spl": "*", + "ext-dom": "*", + "ext-pcre": "*", + "psr/cache": "^1.0", + "ext-sockets": "*", + "drupal/coder": "^8.3", + "symfony/dotenv": "^3.4", + "league/climate": "^3.2.4", + "phpunit/phpunit": "^5.7|^6.6|^7.5|^8.5|^9.5", + "monolog/monolog": "^1.24", + "composer/composer": "^1.8", + "mikey179/vfsstream": "^1.6", + "symfony/var-dumper": "^3.4" + }, + "suggest": { + "ext-sockets": "To use client-side monitoring" + }, + "autoload": { + "psr-4": { + "AlibabaCloud\\Client\\": "src" + }, + "files": [ + "src/Functions.php" + ] + }, + "autoload-dev": { + "psr-4": { + "AlibabaCloud\\Client\\Tests\\": "tests/" + } + }, + "config": { + "preferred-install": "dist", + "optimize-autoloader": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "scripts-descriptions": { + "cs": "Tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard.", + "cbf": "Automatically correct coding standard violations.", + "fixer": "Fixes code to follow standards.", + "test": "Run all tests.", + "unit": "Run Unit tests.", + "feature": "Run Feature tests.", + "clearCache": "Clear cache like coverage.", + "coverage": "Show Coverage html.", + "endpoints": "Update endpoints from OSS." + }, + "scripts": { + "cs": "phpcs --standard=PSR2 -n ./", + "cbf": "phpcbf --standard=PSR2 -n ./", + "fixer": "php-cs-fixer fix ./", + "test": [ + "phpunit --colors=always" + ], + "test4HighVersion": [ + "@clearCache", + "phpunit --testsuite=Test4HighVersion --colors=always" + ], + "test4LowVersion": [ + "@clearCache", + "phpunit --testsuite=Test4LowVersion --colors=always" + ], + "unit4HighVersion": [ + "@clearCache", + "phpunit --testsuite=Unit4HighVersion --colors=always" + ], + "unit4LowVersion": [ + "@clearCache", + "phpunit --testsuite=Unit4LowVersion --colors=always" + ], + "feature4HighVersion": [ + "@clearCache", + "phpunit --testsuite=Feature4HighVersion --colors=always" + ], + "feature4LowVersion": [ + "@clearCache", + "phpunit --testsuite=Feature4LowVersion --colors=always" + ], + "coverage": "open cache/coverage/index.html", + "clearCache": "rm -rf cache/*", + "endpoints": [ + "AlibabaCloud\\Client\\Regions\\LocationService::updateEndpoints", + "@fixer" + ], + "release": [ + "AlibabaCloud\\Client\\Release::release" + ] + } +} diff --git a/vendor/alibabacloud/client/src/Accept.php b/vendor/alibabacloud/client/src/Accept.php new file mode 100644 index 0000000..e7c5261 --- /dev/null +++ b/vendor/alibabacloud/client/src/Accept.php @@ -0,0 +1,53 @@ +format = $format; + } + + /** + * @param $format + * + * @return Accept + */ + public static function create($format) + { + return new static($format); + } + + /** + * @return mixed|string + */ + public function toString() + { + $key = \strtoupper($this->format); + + $list = [ + 'JSON' => 'application/json', + 'XML' => 'application/xml', + 'RAW' => 'application/octet-stream', + 'FORM' => 'application/x-www-form-urlencoded' + ]; + + return isset($list[$key]) ? $list[$key] : $list['RAW']; + } +} diff --git a/vendor/alibabacloud/client/src/AlibabaCloud.php b/vendor/alibabacloud/client/src/AlibabaCloud.php new file mode 100644 index 0000000..16847fa --- /dev/null +++ b/vendor/alibabacloud/client/src/AlibabaCloud.php @@ -0,0 +1,62 @@ +credential = $credential; + $this->signature = $signature; + $this->options['connect_timeout'] = Request::CONNECT_TIMEOUT; + $this->options['timeout'] = Request::TIMEOUT; + $this->options['verify'] = false; + } + + /** + * @return AccessKeyCredential|BearerTokenCredential|CredentialsInterface|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential|StsCredential + */ + public function getCredential() + { + return $this->credential; + } + + /** + * @return SignatureInterface|BearerTokenSignature|ShaHmac1Signature|ShaHmac256Signature|ShaHmac256WithRsaSignature + */ + public function getSignature() + { + return $this->signature; + } +} diff --git a/vendor/alibabacloud/client/src/Clients/EcsRamRoleClient.php b/vendor/alibabacloud/client/src/Clients/EcsRamRoleClient.php new file mode 100644 index 0000000..e97cd6c --- /dev/null +++ b/vendor/alibabacloud/client/src/Clients/EcsRamRoleClient.php @@ -0,0 +1,26 @@ +credential)) { + case EcsRamRoleCredential::class: + return (new EcsRamRoleProvider($this))->get(); + case RamRoleArnCredential::class: + return (new RamRoleArnProvider($this))->get($timeout, $connectTimeout); + case RsaKeyPairCredential::class: + return (new RsaKeyPairProvider($this))->get($timeout, $connectTimeout); + default: + return $this->credential; + } + } + + /** + * @return static + * @throws ClientException + * @deprecated + * @codeCoverageIgnore + */ + public function asGlobalClient() + { + return $this->asDefaultClient(); + } + + /** + * Set the current client as the default client. + * + * @return static + * @throws ClientException + */ + public function asDefaultClient() + { + return $this->name(CredentialsProvider::getDefaultName()); + } + + /** + * Naming clients. + * + * @param string $name + * + * @return static + * @throws ClientException + */ + public function name($name) + { + Filter::name($name); + + return AlibabaCloud::set($name, $this); + } + + /** + * @return bool + */ + public function isDebug() + { + if (isset($this->options['debug'])) { + return $this->options['debug'] === true && PHP_SAPI === 'cli'; + } + + return false; + } +} diff --git a/vendor/alibabacloud/client/src/Clients/RamRoleArnClient.php b/vendor/alibabacloud/client/src/Clients/RamRoleArnClient.php new file mode 100644 index 0000000..b7d3087 --- /dev/null +++ b/vendor/alibabacloud/client/src/Clients/RamRoleArnClient.php @@ -0,0 +1,33 @@ +getValue( + \strtolower($configPath), + $defaultValue + ); + } + + /** + * @return ConfigManager + */ + private static function getConfigManager() + { + if (!self::$configManager instanceof ConfigManager) { + self::$configManager = new ConfigManager(__DIR__ . DIRECTORY_SEPARATOR . 'Data.php'); + } + + return self::$configManager; + } + + /** + * @param string $configPath + * @param mixed $newValue + * + * @return ConfigManager + * @throws Exception + */ + public static function set($configPath, $newValue) + { + self::getConfigManager()->setValue(\strtolower($configPath), $newValue); + + return self::getConfigManager()->saveConfigFile(); + } +} diff --git a/vendor/alibabacloud/client/src/Config/Data.php b/vendor/alibabacloud/client/src/Config/Data.php new file mode 100644 index 0000000..883b2f0 --- /dev/null +++ b/vendor/alibabacloud/client/src/Config/Data.php @@ -0,0 +1,3799 @@ + + [ + 'dysmsapi' => + [ + 'cn-hangzhou' => 'dysmsapi.aliyuncs.com', + 'ap-southeast-1' => 'dysmsapi.ap-southeast-1.aliyuncs.com', + ], + 'ccc' => + [ + 'global' => 'ccc.cn-shanghai.aliyuncs.com', + 'cn-shanghai' => 'ccc.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'ccc.cn-hangzhou.aliyuncs.com', + ], + 'dbs' => + [ + 'cn-hangzhou' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'dbs-api.ap-southeast-1.aliyuncs.com', + 'ap-northeast-1' => 'dbs-api.ap-northeast-1.aliyuncs.com', + ], + 'dybaseapi' => + [ + 'global' => 'dybaseapi.aliyuncs.com', + 'cn-hangzhou' => 'dybaseapi.aliyuncs.com', + ], + 'dyiotapi' => + [ + 'global' => 'dyiotapi.aliyuncs.com', + 'cn-hangzhou' => 'dyiotapi.aliyuncs.com', + ], + 'dycdpapi' => + [ + 'global' => 'dycdpapi.aliyuncs.com', + 'cn-hangzhou' => 'dycdpapi.aliyuncs.com', + ], + 'dyplsapi' => + [ + 'global' => 'dyplsapi.aliyuncs.com', + 'cn-hangzhou' => 'dyplsapi.aliyuncs.com', + ], + 'dypnsapi' => + [ + 'global' => 'dypnsapi.aliyuncs.com', + 'cn-hangzhou' => 'dypnsapi.aliyuncs.com', + ], + 'dyvmsapi' => + [ + 'global' => 'dyvmsapi.aliyuncs.com', + 'cn-hangzhou' => 'dyvmsapi.aliyuncs.com', + ], + 'snsuapi' => + [ + 'global' => 'snsuapi.aliyuncs.com', + 'cn-hangzhou' => 'snsuapi.aliyuncs.com', + ], + 'ecs' => + [ + 'jp-fudao-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'me-east-1' => 'ecs.me-east-1.aliyuncs.com', + 'us-east-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'ap-northeast-1' => 'ecs.ap-northeast-1.aliyuncs.com', + 'cn-hangzhou-bj-b01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-beijing-nu16-b01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-beijing-am13-c01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'in-west-antgroup-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-guizhou-gov' => 'ecs-cn-hangzhou.aliyuncs.com', + 'in-west-antgroup-2' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'ecs-cn-hangzhou.aliyuncs.com', + 'tw-snowcloud-kaohsiung' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-finance-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-guizhou' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-fujian' => 'ecs-cn-hangzhou.aliyuncs.com', + 'in-mumbai-alipay' => 'ecs-cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-anhui-gov-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-anhui-gov' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'ecs-cn-hangzhou.aliyuncs.com', + 'ap-southeast-2' => 'ecs.ap-southeast-2.aliyuncs.com', + 'cn-qingdao' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-su18-b02' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-su18-b03' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-su18-b01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'ap-southeast-antgroup-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-henan-am12001' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-gansu-am6' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-ningxiazhongwei' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-ningxia-am7-c01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-st4-d01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'eu-central-1' => 'ecs.eu-central-1.aliyuncs.com', + 'cn-zhangjiakou' => 'ecs.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'ecs.cn-huhehaote.aliyuncs.com', + 'ap-southeast-3' => 'ecs.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'ecs.ap-southeast-5.aliyuncs.com', + 'eu-west-1' => 'ecs.eu-west-1.aliyuncs.com', + 'ap-south-1' => 'ecs.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'ecs.cn-chengdu.aliyuncs.com', + 'cn-north-2-gov-1' => 'ecs.aliyuncs.com', + 'cn-edge-1' => 'ecs.cn-qingdao-nebula.aliyuncs.com', + 'cn-hangzhou-internal-prod-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-internal-test-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-internal-test-2' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-internal-test-3' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-huhehaote-nebula-1' => 'ecs.cn-qingdao-nebula.aliyuncs.com', + 'cn-qingdao-nebula' => 'ecs.cn-qingdao-nebula.aliyuncs.com', + 'cn-shanghai-internal-test-1' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-zhangbei-na61-b01' => 'ecs-cn-hangzhou.aliyuncs.com', + 'cn-zhengzhou-nebula-1' => 'ecs.cn-qingdao-nebula.aliyuncs.com', + 'eu-west-1-oxs' => 'ecs.cn-shenzhen-cloudstone.aliyuncs.com', + 'cn-heyuan' => 'ecs.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'ecs.cn-wulanchabu.aliyuncs.com', + ], + 'rds' => + [ + 'me-east-1' => 'rds.me-east-1.aliyuncs.com', + 'us-east-1' => 'rds.aliyuncs.com', + 'ap-northeast-1' => 'rds.ap-northeast-1.aliyuncs.com', + 'cn-hongkong' => 'rds.aliyuncs.com', + 'cn-qingdao-cm9' => 'rds.aliyuncs.com', + 'cn-shanghai-finance-1' => 'rds.aliyuncs.com', + 'cn-beijing-gov-1' => 'rds.aliyuncs.com', + 'cn-shanghai' => 'rds.aliyuncs.com', + 'cn-shenzhen-inner' => 'rds.aliyuncs.com', + 'cn-fujian' => 'rds.aliyuncs.com', + 'us-west-1' => 'rds.aliyuncs.com', + 'cn-shanghai-inner' => 'rds.aliyuncs.com', + 'cn-hangzhou' => 'rds.aliyuncs.com', + 'cn-beijing-inner' => 'rds.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'rds.aliyuncs.com', + 'cn-shenzhen' => 'rds.aliyuncs.com', + 'ap-southeast-2' => 'rds.ap-southeast-2.aliyuncs.com', + 'cn-qingdao' => 'rds.aliyuncs.com', + 'cn-beijing' => 'rds.aliyuncs.com', + 'cn-hangzhou-d' => 'rds.aliyuncs.com', + 'cn-gansu-am6' => 'rds.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'rds.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'rds.aliyuncs.com', + 'ap-southeast-1' => 'rds.aliyuncs.com', + 'eu-central-1' => 'rds.eu-central-1.aliyuncs.com', + 'cn-zhangjiakou' => 'rds.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'rds.cn-huhehaote.aliyuncs.com', + 'ap-southeast-3' => 'rds.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'rds.ap-southeast-5.aliyuncs.com', + 'eu-west-1' => 'rds.eu-west-1.aliyuncs.com', + 'ap-south-1' => 'rds.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'rds.cn-chengdu.aliyuncs.com', + 'cn-north-2-gov-1' => 'rds.aliyuncs.com', + 'cn-yushanfang' => 'rds.aliyuncs.com', + 'cn-huhehaote-nebula-1' => 'rds.cn-chengdu.aliyuncs.com', + 'cn-heyuan' => 'rds.aliyuncs.com', + ], + 'vpc' => + [ + 'me-east-1' => 'vpc.me-east-1.aliyuncs.com', + 'us-east-1' => 'vpc.aliyuncs.com', + 'ap-northeast-1' => 'vpc.ap-northeast-1.aliyuncs.com', + 'cn-hongkong' => 'vpc.aliyuncs.com', + 'cn-beijing-am13-c01' => 'vpc.aliyuncs.com', + 'cn-guizhou-gov' => 'vpc.aliyuncs.com', + 'cn-shanghai-finance-1' => 'vpc.aliyuncs.com', + 'cn-guizhou' => 'vpc.aliyuncs.com', + 'cn-shanghai' => 'vpc.aliyuncs.com', + 'us-west-1' => 'vpc.aliyuncs.com', + 'cn-hangzhou' => 'vpc.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'vpc.aliyuncs.com', + 'cn-anhui-gov' => 'vpc.aliyuncs.com', + 'cn-shenzhen' => 'vpc.aliyuncs.com', + 'ap-southeast-2' => 'vpc.ap-southeast-2.aliyuncs.com', + 'cn-henan-am12001' => 'vpc.aliyuncs.com', + 'cn-beijing' => 'vpc.aliyuncs.com', + 'cn-gansu-am6' => 'vpc.aliyuncs.com', + 'cn-ningxiazhongwei' => 'vpc.aliyuncs.com', + 'cn-ningxia-am7-c01' => 'vpc.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'vpc.aliyuncs.com', + 'ap-southeast-1' => 'vpc.aliyuncs.com', + 'eu-central-1' => 'vpc.eu-central-1.aliyuncs.com', + 'cn-zhangjiakou' => 'vpc.cn-zhangjiakou.aliyuncs.com', + 'cn-qingdao' => 'vpc.aliyuncs.com', + 'cn-huhehaote' => 'vpc.cn-huhehaote.aliyuncs.com', + 'ap-southeast-3' => 'vpc.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'vpc.ap-southeast-5.aliyuncs.com', + 'eu-west-1' => 'vpc.eu-west-1.aliyuncs.com', + 'ap-south-1' => 'vpc.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'vpc.cn-chengdu.aliyuncs.com', + 'cn-north-2-gov-1' => 'vpc.aliyuncs.com', + 'ap-northeast-2-pop' => 'vpc.aliyuncs.com', + 'cn-beijing-finance-1' => 'vpc.aliyuncs.com', + 'cn-beijing-finance-pop' => 'vpc.aliyuncs.com', + 'cn-edge-1' => 'vpc-nebula.cn-qingdao-nebula.aliyuncs.com', + 'cn-hangzhou-internal-test-1' => 'vpc.aliyuncs.com', + 'cn-hangzhou-internal-test-2' => 'vpc.aliyuncs.com', + 'cn-hangzhou-internal-test-3' => 'vpc.aliyuncs.com', + 'cn-hongkong-finance-pop' => 'vpc.aliyuncs.com', + 'cn-huhehaote-nebula-1' => 'vpc-nebula.cn-qingdao-nebula.aliyuncs.com', + 'cn-qingdao-nebula' => 'vpc-nebula.cn-qingdao-nebula.aliyuncs.com', + 'cn-shanghai-et15-b01' => 'vpc.aliyuncs.com', + 'cn-wuhan' => 'vpc.aliyuncs.com', + 'cn-zhangbei-na61-b01' => 'vpc.aliyuncs.com', + 'cn-zhengzhou-nebula-1' => 'vpc-nebula.cn-qingdao-nebula.aliyuncs.com', + 'eu-west-1-oxs' => 'vpc-nebula.cn-shenzhen-cloudstone.aliyuncs.com', + 'rus-west-1-pop' => 'vpc.aliyuncs.com', + 'cn-heyuan' => 'vpc.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'vpc.cn-wulanchabu.aliyuncs.com', + ], + 'kms' => + [ + 'me-east-1' => 'kms.me-east-1.aliyuncs.com', + 'ap-northeast-1' => 'kms.ap-northeast-1.aliyuncs.com', + 'cn-hongkong' => 'kms.cn-hongkong.aliyuncs.com', + 'cn-shanghai-finance-1' => 'kms.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shanghai' => 'kms.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'kms.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'kms.cn-shenzhen.aliyuncs.com', + 'ap-southeast-2' => 'kms.ap-southeast-2.aliyuncs.com', + 'cn-beijing' => 'kms.cn-beijing.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'kms.cn-shenzhen-finance-1.aliyuncs.com', + 'ap-southeast-1' => 'kms.ap-southeast-1.aliyuncs.com', + 'eu-central-1' => 'kms.eu-central-1.aliyuncs.com', + 'cn-qingdao' => 'kms.cn-qingdao.aliyuncs.com', + 'cn-zhangjiakou' => 'kms.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'kms.cn-huhehaote.aliyuncs.com', + 'ap-southeast-3' => 'kms.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'kms.ap-southeast-5.aliyuncs.com', + 'eu-west-1' => 'kms.eu-west-1.aliyuncs.com', + 'us-west-1' => 'kms.us-west-1.aliyuncs.com', + 'us-east-1' => 'kms.us-east-1.aliyuncs.com', + 'ap-south-1' => 'kms.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'kms.cn-chengdu.aliyuncs.com', + 'cn-hangzhou-finance' => 'kms.cn-hangzhou-finance.aliyuncs.com', + 'cn-north-2-gov-1' => 'kms.cn-north-2-gov-1.aliyuncs.com', + 'cn-hangzhou-internal-test-1' => 'kms.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-internal-test-2' => 'kms.cn-hangzhou.aliyuncs.com', + 'cn-heyuan' => 'kms.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'kms.cn-wulanchabu.aliyuncs.com', + ], + 'cms' => + [ + 'me-east-1' => 'metrics.cn-hangzhou.aliyuncs.com', + 'us-east-1' => 'metrics.cn-hangzhou.aliyuncs.com', + 'ap-northeast-1' => 'metrics.ap-northeast-1.aliyuncs.com', + 'cn-hongkong' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'metrics.aliyuncs.com', + 'cn-shanghai' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'metrics.aliyuncs.com', + 'us-west-1' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'metrics.aliyuncs.com', + 'cn-hangzhou' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'metrics.aliyuncs.com', + 'cn-shenzhen' => 'metrics.cn-hangzhou.aliyuncs.com', + 'ap-southeast-2' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'metrics.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'metrics.aliyuncs.com', + 'ap-southeast-1' => 'metrics.cn-hangzhou.aliyuncs.com', + 'eu-central-1' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-zhangjiakou' => 'metrics.cn-hangzhou.aliyuncs.com', + 'cn-huhehaote' => 'metrics.cn-huhehaote.aliyuncs.com', + 'ap-southeast-3' => 'metrics.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'metrics.ap-southeast-5.aliyuncs.com', + 'eu-west-1' => 'metrics.eu-west-1.aliyuncs.com', + 'ap-south-1' => 'metrics.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'metrics.cn-chengdu.aliyuncs.com', + 'cn-shanghai-finance-1' => 'metrics.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'metrics.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'metrics.cn-north-2-gov-1.aliyuncs.com', + 'cn-qingdao-nebula' => 'metrics.cn-qingdao-nebula.aliyuncs.com', + 'cn-heyuan' => 'metrics.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'metrics.cn-wulanchabu.aliyuncs.com', + ], + 'slb' => + [ + 'me-east-1' => 'slb.me-east-1.aliyuncs.com', + 'us-east-1' => 'slb.aliyuncs.com', + 'ap-northeast-1' => 'slb.ap-northeast-1.aliyuncs.com', + 'cn-hongkong' => 'slb.aliyuncs.com', + 'cn-qingdao-cm9' => 'slb.aliyuncs.com', + 'cn-shanghai' => 'slb.aliyuncs.com', + 'cn-shenzhen-inner' => 'slb.aliyuncs.com', + 'us-west-1' => 'slb.aliyuncs.com', + 'cn-shanghai-inner' => 'slb.aliyuncs.com', + 'cn-hangzhou' => 'slb.aliyuncs.com', + 'cn-beijing-inner' => 'slb.aliyuncs.com', + 'cn-shenzhen' => 'slb.aliyuncs.com', + 'ap-southeast-2' => 'slb.ap-southeast-2.aliyuncs.com', + 'cn-qingdao' => 'slb.aliyuncs.com', + 'cn-beijing' => 'slb.aliyuncs.com', + 'cn-hangzhou-d' => 'slb.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'slb.aliyuncs.com', + 'ap-southeast-1' => 'slb.aliyuncs.com', + 'eu-central-1' => 'slb.eu-central-1.aliyuncs.com', + 'cn-zhangjiakou' => 'slb.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'slb.cn-huhehaote.aliyuncs.com', + 'ap-southeast-3' => 'slb.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'slb.ap-southeast-5.aliyuncs.com', + 'eu-west-1' => 'slb.eu-west-1.aliyuncs.com', + 'ap-south-1' => 'slb.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'slb.cn-chengdu.aliyuncs.com', + 'cn-shanghai-finance-1' => 'slb.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'slb.aliyuncs.com', + 'cn-north-2-gov-1' => 'slb.aliyuncs.com', + 'cn-fujian' => 'slb.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'slb.aliyuncs.com', + 'cn-hangzhou-test-306' => 'slb.aliyuncs.com', + 'cn-huhehaote-nebula-1' => 'slb-api.cn-qingdao-nebula.aliyuncs.com', + 'cn-heyuan' => 'slb.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'slb.cn-wulanchabu.aliyuncs.com', + ], + 'cs' => + [ + 'us-east-1' => 'cs.us-east-1.aliyuncs.com', + 'cn-hongkong' => 'cs.cn-hongkong.aliyuncs.com', + 'cn-qingdao-cm9' => 'cs.aliyuncs.com', + 'cn-shanghai' => 'cs.cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'cs.aliyuncs.com', + 'us-west-1' => 'cs.us-west-1.aliyuncs.com', + 'cn-shanghai-inner' => 'cs.aliyuncs.com', + 'cn-hangzhou' => 'cs.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'cs.aliyuncs.com', + 'cn-shenzhen' => 'cs.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'cs.aliyuncs.com', + 'cn-beijing' => 'cs.cn-beijing.aliyuncs.com', + 'cn-hangzhou-d' => 'cs.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'cs.aliyuncs.com', + 'ap-southeast-1' => 'cs.ap-southeast-1.aliyuncs.com', + 'cn-chengdu' => 'cs.cn-chengdu.aliyuncs.com', + 'cn-zhangjiakou' => 'cs.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'cs.cn-huhehaote.aliyuncs.com', + 'ap-southeast-2' => 'cs.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'cs.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'cs.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'cs.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'cs.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'cs.eu-central-1.aliyuncs.com', + 'me-east-1' => 'cs.me-east-1.aliyuncs.com', + 'ap-south-1' => 'cs.ap-south-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'cs.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'cs.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'cs.cn-north-2-gov-1.aliyuncs.com', + ], + 'push' => + [ + 'us-east-1' => 'cloudpush.aliyuncs.com', + 'cn-hongkong' => 'cloudpush.aliyuncs.com', + 'cn-qingdao-cm9' => 'cloudpush.aliyuncs.com', + 'cn-shanghai' => 'cloudpush.aliyuncs.com', + 'cn-shenzhen-inner' => 'cloudpush.aliyuncs.com', + 'us-west-1' => 'cloudpush.aliyuncs.com', + 'cn-shanghai-inner' => 'cloudpush.aliyuncs.com', + 'cn-hangzhou' => 'cloudpush.aliyuncs.com', + 'cn-beijing-inner' => 'cloudpush.aliyuncs.com', + 'cn-shenzhen' => 'cloudpush.aliyuncs.com', + 'cn-qingdao' => 'cloudpush.aliyuncs.com', + 'cn-beijing' => 'cloudpush.aliyuncs.com', + 'cn-hangzhou-d' => 'cloudpush.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'cloudpush.aliyuncs.com', + 'ap-southeast-1' => 'cloudpush.aliyuncs.com', + ], + 'cos' => + [ + 'us-east-1' => 'cos.aliyuncs.com', + 'cn-hongkong' => 'cos.aliyuncs.com', + 'cn-qingdao-cm9' => 'cos.aliyuncs.com', + 'cn-shanghai' => 'cos.aliyuncs.com', + 'cn-shenzhen-inner' => 'cos.aliyuncs.com', + 'us-west-1' => 'cos.aliyuncs.com', + 'cn-shanghai-inner' => 'cos.aliyuncs.com', + 'cn-hangzhou' => 'cos.aliyuncs.com', + 'cn-beijing-inner' => 'cos.aliyuncs.com', + 'cn-shenzhen' => 'cos.aliyuncs.com', + 'cn-qingdao' => 'cos.aliyuncs.com', + 'cn-beijing' => 'cos.aliyuncs.com', + 'cn-hangzhou-d' => 'cos.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'cos.aliyuncs.com', + 'ap-southeast-1' => 'cos.aliyuncs.com', + ], + 'ess' => + [ + 'us-east-1' => 'ess.aliyuncs.com', + 'cn-hongkong' => 'ess.aliyuncs.com', + 'cn-qingdao-cm9' => 'ess.aliyuncs.com', + 'cn-shanghai' => 'ess.aliyuncs.com', + 'cn-shenzhen-inner' => 'ess.aliyuncs.com', + 'us-west-1' => 'ess.aliyuncs.com', + 'cn-shanghai-inner' => 'ess.aliyuncs.com', + 'cn-hangzhou' => 'ess.aliyuncs.com', + 'cn-beijing-inner' => 'ess.aliyuncs.com', + 'cn-shenzhen' => 'ess.aliyuncs.com', + 'cn-qingdao' => 'ess.aliyuncs.com', + 'cn-beijing' => 'ess.aliyuncs.com', + 'cn-hangzhou-d' => 'ess.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ess.aliyuncs.com', + 'ap-southeast-1' => 'ess.aliyuncs.com', + 'cn-zhangjiakou' => 'ess.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'ess.cn-huhehaote.aliyuncs.com', + 'ap-southeast-2' => 'ess.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'ess.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'ess.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'ess.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'ess.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'ess.eu-central-1.aliyuncs.com', + 'me-east-1' => 'ess.me-east-1.aliyuncs.com', + 'ap-south-1' => 'ess.ap-south-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'ess.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'ess.aliyuncs.com', + 'cn-north-2-gov-1' => 'ess.aliyuncs.com', + 'cn-chengdu' => 'ess.cn-chengdu.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'ess.aliyuncs.com', + 'cn-heyuan' => 'ess.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'ess.cn-wulanchabu.aliyuncs.com', + ], + 'ace-ops' => + [ + 'us-east-1' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'ace-ops.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ace-ops.cn-hangzhou.aliyuncs.com', + ], + 'billing' => + [ + 'us-east-1' => 'billing.aliyuncs.com', + 'cn-hongkong' => 'billing.aliyuncs.com', + 'cn-qingdao-cm9' => 'billing.aliyuncs.com', + 'cn-shanghai' => 'billing.aliyuncs.com', + 'cn-shenzhen-inner' => 'billing.aliyuncs.com', + 'us-west-1' => 'billing.aliyuncs.com', + 'cn-shanghai-inner' => 'billing.aliyuncs.com', + 'cn-hangzhou' => 'billing.aliyuncs.com', + 'cn-beijing-inner' => 'billing.aliyuncs.com', + 'cn-beijing' => 'billing.aliyuncs.com', + 'cn-hangzhou-d' => 'billing.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'billing.aliyuncs.com', + 'ap-southeast-1' => 'billing.aliyuncs.com', + ], + 'dqs' => + [ + 'us-east-1' => 'dqs.aliyuncs.com', + 'cn-hongkong' => 'dqs.aliyuncs.com', + 'cn-qingdao-cm9' => 'dqs.aliyuncs.com', + 'cn-shanghai' => 'dqs.aliyuncs.com', + 'cn-shenzhen-inner' => 'dqs.aliyuncs.com', + 'us-west-1' => 'dqs.aliyuncs.com', + 'cn-shanghai-inner' => 'dqs.aliyuncs.com', + 'cn-hangzhou' => 'dqs.aliyuncs.com', + 'cn-beijing-inner' => 'dqs.aliyuncs.com', + 'cn-shenzhen' => 'dqs.aliyuncs.com', + 'cn-qingdao' => 'dqs.aliyuncs.com', + 'cn-beijing' => 'dqs.aliyuncs.com', + 'cn-hangzhou-d' => 'dqs.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'dqs.aliyuncs.com', + 'ap-southeast-1' => 'dqs.aliyuncs.com', + ], + 'dds' => + [ + 'us-east-1' => 'mongodb.aliyuncs.com', + 'cn-hongkong' => 'mongodb.aliyuncs.com', + 'cn-qingdao-cm9' => 'mongodb.aliyuncs.com', + 'cn-shanghai' => 'mongodb.aliyuncs.com', + 'cn-shenzhen-inner' => 'mongodb.aliyuncs.com', + 'us-west-1' => 'mongodb.aliyuncs.com', + 'cn-shanghai-inner' => 'mongodb.aliyuncs.com', + 'cn-hangzhou' => 'mongodb.aliyuncs.com', + 'cn-beijing-inner' => 'mongodb.aliyuncs.com', + 'cn-shenzhen' => 'mongodb.aliyuncs.com', + 'cn-qingdao' => 'mongodb.aliyuncs.com', + 'cn-beijing' => 'mongodb.aliyuncs.com', + 'cn-hangzhou-d' => 'mongodb.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'mongodb.aliyuncs.com', + 'ap-southeast-1' => 'mongodb.aliyuncs.com', + 'cn-zhangjiakou' => 'mongodb.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'mongodb.cn-huhehaote.aliyuncs.com', + 'ap-southeast-2' => 'mongodb.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'mongodb.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'mongodb.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'mongodb.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'mongodb.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'mongodb.eu-central-1.aliyuncs.com', + 'me-east-1' => 'mongodb.me-east-1.aliyuncs.com', + 'ap-south-1' => 'mongodb.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'mongodb.cn-chengdu.aliyuncs.com', + 'cn-hangzhou-finance' => 'mongodb.aliyuncs.com', + 'cn-shanghai-finance-1' => 'mongodb.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'mongodb.aliyuncs.com', + 'cn-north-2-gov-1' => 'mongodb.aliyuncs.com', + 'cn-heyuan' => 'mongodb.aliyuncs.com', + 'cn-wulanchabu' => 'mongodb.aliyuncs.com', + ], + 'emr' => + [ + 'us-east-1' => 'emr.us-east-1.aliyuncs.com', + 'cn-hongkong' => 'emr.cn-hongkong.aliyuncs.com', + 'cn-qingdao-cm9' => 'emr.aliyuncs.com', + 'cn-shanghai' => 'emr.aliyuncs.com', + 'cn-shenzhen-inner' => 'emr.aliyuncs.com', + 'us-west-1' => 'emr.aliyuncs.com', + 'cn-shanghai-inner' => 'emr.aliyuncs.com', + 'cn-hangzhou' => 'emr.aliyuncs.com', + 'cn-beijing-inner' => 'emr.aliyuncs.com', + 'cn-shenzhen' => 'emr.aliyuncs.com', + 'cn-qingdao' => 'emr.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'emr.aliyuncs.com', + 'cn-hangzhou-d' => 'emr.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'emr.aliyuncs.com', + 'ap-southeast-1' => 'emr.aliyuncs.com', + 'cn-zhangjiakou' => 'emr.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'emr.cn-huhehaote.aliyuncs.com', + 'ap-southeast-2' => 'emr.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'emr.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'emr.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'emr.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'emr.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'emr.eu-central-1.aliyuncs.com', + 'me-east-1' => 'emr.me-east-1.aliyuncs.com', + 'ap-south-1' => 'emr.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'emr.cn-chengdu.aliyuncs.com', + 'cn-shanghai-finance-1' => 'emr.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'emr.aliyuncs.com', + ], + 'sms' => + [ + 'us-east-1' => 'sms.aliyuncs.com', + 'cn-hongkong' => 'sms.aliyuncs.com', + 'cn-qingdao-cm9' => 'sms.aliyuncs.com', + 'cn-shanghai' => 'sms.aliyuncs.com', + 'cn-shenzhen-inner' => 'sms.aliyuncs.com', + 'us-west-1' => 'sms.aliyuncs.com', + 'cn-shanghai-inner' => 'sms.aliyuncs.com', + 'cn-hangzhou' => 'sms.aliyuncs.com', + 'cn-beijing-inner' => 'sms.aliyuncs.com', + 'cn-shenzhen' => 'sms.aliyuncs.com', + 'cn-qingdao' => 'sms.aliyuncs.com', + 'cn-beijing' => 'sms.aliyuncs.com', + 'cn-hangzhou-d' => 'sms.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'sms.aliyuncs.com', + 'ap-southeast-1' => 'sms.aliyuncs.com', + ], + 'jaq' => + [ + 'us-east-1' => 'jaq.aliyuncs.com', + 'cn-hongkong' => 'jaq.aliyuncs.com', + 'cn-qingdao-cm9' => 'jaq.aliyuncs.com', + 'cn-shanghai' => 'jaq.aliyuncs.com', + 'cn-shenzhen-inner' => 'jaq.aliyuncs.com', + 'us-west-1' => 'jaq.aliyuncs.com', + 'cn-shanghai-inner' => 'jaq.aliyuncs.com', + 'cn-hangzhou' => 'jaq.aliyuncs.com', + 'cn-beijing-inner' => 'jaq.aliyuncs.com', + 'cn-shenzhen' => 'jaq.aliyuncs.com', + 'cn-qingdao' => 'jaq.aliyuncs.com', + 'cn-beijing' => 'jaq.aliyuncs.com', + 'cn-hangzhou-d' => 'jaq.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'jaq.aliyuncs.com', + 'ap-southeast-1' => 'jaq.aliyuncs.com', + ], + 'hpc' => + [ + 'us-east-1' => 'hpc.aliyuncs.com', + 'cn-hongkong' => 'hpc.aliyuncs.com', + 'cn-qingdao-cm9' => 'hpc.aliyuncs.com', + 'cn-shanghai' => 'hpc.aliyuncs.com', + 'cn-shenzhen-inner' => 'hpc.aliyuncs.com', + 'us-west-1' => 'hpc.aliyuncs.com', + 'cn-shanghai-inner' => 'hpc.aliyuncs.com', + 'cn-hangzhou' => 'hpc.aliyuncs.com', + 'cn-beijing-inner' => 'hpc.aliyuncs.com', + 'cn-shenzhen' => 'hpc.aliyuncs.com', + 'cn-qingdao' => 'hpc.aliyuncs.com', + 'cn-beijing' => 'hpc.aliyuncs.com', + 'cn-hangzhou-d' => 'hpc.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'hpc.aliyuncs.com', + 'ap-southeast-1' => 'hpc.aliyuncs.com', + ], + 'location' => + [ + 'us-east-1' => 'location.aliyuncs.com', + 'cn-hongkong' => 'location.aliyuncs.com', + 'cn-qingdao-cm9' => 'location.aliyuncs.com', + 'cn-shanghai' => 'location.aliyuncs.com', + 'cn-shenzhen-inner' => 'location.aliyuncs.com', + 'us-west-1' => 'location.aliyuncs.com', + 'cn-shanghai-inner' => 'location.aliyuncs.com', + 'cn-hangzhou' => 'location.aliyuncs.com', + 'cn-beijing-inner' => 'location.aliyuncs.com', + 'cn-shenzhen' => 'location.aliyuncs.com', + 'cn-qingdao' => 'location.aliyuncs.com', + 'cn-beijing' => 'location.aliyuncs.com', + 'cn-hangzhou-d' => 'location.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'location.aliyuncs.com', + 'ap-southeast-1' => 'location.aliyuncs.com', + ], + 'chargingservice' => + [ + 'us-east-1' => 'chargingservice.aliyuncs.com', + 'cn-hongkong' => 'chargingservice.aliyuncs.com', + 'cn-qingdao-cm9' => 'chargingservice.aliyuncs.com', + 'cn-shanghai' => 'chargingservice.aliyuncs.com', + 'cn-shenzhen-inner' => 'chargingservice.aliyuncs.com', + 'us-west-1' => 'chargingservice.aliyuncs.com', + 'cn-shanghai-inner' => 'chargingservice.aliyuncs.com', + 'cn-hangzhou' => 'chargingservice.aliyuncs.com', + 'cn-beijing-inner' => 'chargingservice.aliyuncs.com', + 'cn-beijing' => 'chargingservice.aliyuncs.com', + 'cn-hangzhou-d' => 'chargingservice.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'chargingservice.aliyuncs.com', + 'ap-southeast-1' => 'chargingservice.aliyuncs.com', + ], + 'msg' => + [ + 'us-east-1' => 'msg-inner.aliyuncs.com', + 'cn-hongkong' => 'msg-inner.aliyuncs.com', + 'cn-qingdao-cm9' => 'msg-inner.aliyuncs.com', + 'cn-shanghai' => 'msg-inner.aliyuncs.com', + 'cn-shenzhen-inner' => 'msg-inner.aliyuncs.com', + 'us-west-1' => 'msg-inner.aliyuncs.com', + 'cn-shanghai-inner' => 'msg-inner.aliyuncs.com', + 'cn-hangzhou' => 'msg-inner.aliyuncs.com', + 'cn-beijing-inner' => 'msg-inner.aliyuncs.com', + 'cn-beijing' => 'msg-inner.aliyuncs.com', + 'cn-hangzhou-d' => 'msg-inner.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'msg-inner.aliyuncs.com', + 'ap-southeast-1' => 'msg-inner.aliyuncs.com', + ], + 'commondriver' => + [ + 'us-east-1' => 'common.driver.aliyuncs.com', + 'cn-hongkong' => 'common.driver.aliyuncs.com', + 'cn-qingdao-cm9' => 'common.driver.aliyuncs.com', + 'cn-shanghai' => 'common.driver.aliyuncs.com', + 'cn-shenzhen-inner' => 'common.driver.aliyuncs.com', + 'us-west-1' => 'common.driver.aliyuncs.com', + 'cn-shanghai-inner' => 'common.driver.aliyuncs.com', + 'cn-hangzhou' => 'common.driver.aliyuncs.com', + 'cn-beijing-inner' => 'common.driver.aliyuncs.com', + 'cn-shenzhen' => 'common.driver.aliyuncs.com', + 'cn-qingdao' => 'common.driver.aliyuncs.com', + 'cn-beijing' => 'common.driver.aliyuncs.com', + 'cn-hangzhou-d' => 'common.driver.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'common.driver.aliyuncs.com', + 'ap-southeast-1' => 'common.driver.aliyuncs.com', + ], + 'r-kvstore' => + [ + 'us-east-1' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'r-kvstore-cn-hangzhou.aliyuncs.com', + ], + 'bss' => + [ + 'us-east-1' => 'bss.aliyuncs.com', + 'cn-hongkong' => 'bss.aliyuncs.com', + 'cn-qingdao-cm9' => 'bss.aliyuncs.com', + 'cn-shanghai' => 'bss.aliyuncs.com', + 'cn-shenzhen-inner' => 'bss.aliyuncs.com', + 'us-west-1' => 'bss.aliyuncs.com', + 'cn-shanghai-inner' => 'bss.aliyuncs.com', + 'cn-hangzhou' => 'bss.aliyuncs.com', + 'cn-beijing-inner' => 'bss.aliyuncs.com', + 'cn-shenzhen' => 'bss.aliyuncs.com', + 'cn-qingdao' => 'bss.aliyuncs.com', + 'cn-beijing' => 'bss.aliyuncs.com', + 'cn-hangzhou-d' => 'bss.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'bss.aliyuncs.com', + 'ap-southeast-1' => 'bss.aliyuncs.com', + ], + 'workorder' => + [ + 'us-east-1' => 'workorder.aliyuncs.com', + 'cn-hongkong' => 'workorder.aliyuncs.com', + 'cn-qingdao-cm9' => 'workorder.aliyuncs.com', + 'cn-shanghai' => 'workorder.aliyuncs.com', + 'cn-shenzhen-inner' => 'workorder.aliyuncs.com', + 'us-west-1' => 'workorder.aliyuncs.com', + 'cn-shanghai-inner' => 'workorder.aliyuncs.com', + 'cn-hangzhou' => 'workorder.aliyuncs.com', + 'cn-beijing-inner' => 'workorder.aliyuncs.com', + 'cn-beijing' => 'workorder.aliyuncs.com', + 'cn-hangzhou-d' => 'workorder.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'workorder.aliyuncs.com', + 'ap-southeast-1' => 'workorder.aliyuncs.com', + ], + 'ocs' => + [ + 'us-east-1' => 'm-kvstore.aliyuncs.com', + 'cn-hongkong' => 'm-kvstore.aliyuncs.com', + 'cn-qingdao-cm9' => 'm-kvstore.aliyuncs.com', + 'cn-shanghai' => 'm-kvstore.aliyuncs.com', + 'cn-shenzhen-inner' => 'm-kvstore.aliyuncs.com', + 'us-west-1' => 'm-kvstore.aliyuncs.com', + 'cn-shanghai-inner' => 'm-kvstore.aliyuncs.com', + 'cn-hangzhou' => 'm-kvstore.aliyuncs.com', + 'cn-beijing-inner' => 'm-kvstore.aliyuncs.com', + 'cn-shenzhen' => 'm-kvstore.aliyuncs.com', + 'cn-qingdao' => 'm-kvstore.aliyuncs.com', + 'cn-beijing' => 'm-kvstore.aliyuncs.com', + 'cn-hangzhou-d' => 'm-kvstore.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'm-kvstore.aliyuncs.com', + 'ap-southeast-1' => 'm-kvstore.aliyuncs.com', + ], + 'yundun' => + [ + 'us-east-1' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'yundun-cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'yundun-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'yundun-cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'yundun-cn-hangzhou.aliyuncs.com', + ], + 'ubsms-inner' => + [ + 'us-east-1' => 'ubsms-inner.aliyuncs.com', + 'cn-hongkong' => 'ubsms-inner.aliyuncs.com', + 'cn-qingdao-cm9' => 'ubsms-inner.aliyuncs.com', + 'cn-shanghai' => 'ubsms-inner.aliyuncs.com', + 'cn-shenzhen-inner' => 'ubsms-inner.aliyuncs.com', + 'us-west-1' => 'ubsms-inner.aliyuncs.com', + 'cn-shanghai-inner' => 'ubsms-inner.aliyuncs.com', + 'cn-hangzhou' => 'ubsms-inner.aliyuncs.com', + 'cn-beijing-inner' => 'ubsms-inner.aliyuncs.com', + 'cn-shenzhen' => 'ubsms-inner.aliyuncs.com', + 'cn-qingdao' => 'ubsms-inner.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'ubsms-inner.aliyuncs.com', + 'cn-hangzhou-d' => 'ubsms-inner.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ubsms-inner.aliyuncs.com', + 'ap-southeast-1' => 'ubsms-inner.aliyuncs.com', + ], + 'dm' => + [ + 'us-east-1' => 'dm.aliyuncs.com', + 'cn-hongkong' => 'dm.aliyuncs.com', + 'cn-qingdao-cm9' => 'dm.aliyuncs.com', + 'cn-shanghai' => 'dm.aliyuncs.com', + 'cn-shenzhen-inner' => 'dm.aliyuncs.com', + 'us-west-1' => 'dm.aliyuncs.com', + 'cn-shanghai-inner' => 'dm.aliyuncs.com', + 'cn-hangzhou' => 'dm.aliyuncs.com', + 'cn-beijing-inner' => 'dm.aliyuncs.com', + 'cn-shenzhen' => 'dm.aliyuncs.com', + 'cn-qingdao' => 'dm.aliyuncs.com', + 'cn-beijing' => 'dm.aliyuncs.com', + 'cn-hangzhou-d' => 'dm.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'dm.aliyuncs.com', + 'ap-southeast-1' => 'dm.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'dm.ap-southeast-2.aliyuncs.com', + ], + 'green' => + [ + 'us-east-1' => 'green.aliyuncs.com', + 'cn-hongkong' => 'green.aliyuncs.com', + 'cn-qingdao-cm9' => 'green.aliyuncs.com', + 'cn-shanghai' => 'green.cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'green.aliyuncs.com', + 'us-west-1' => 'green.us-west-1.aliyuncs.com', + 'cn-shanghai-inner' => 'green.aliyuncs.com', + 'cn-hangzhou' => 'green.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'green.aliyuncs.com', + 'cn-shenzhen' => 'green.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'green.aliyuncs.com', + 'cn-beijing' => 'green.cn-beijing.aliyuncs.com', + 'cn-hangzhou-d' => 'green.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'green.aliyuncs.com', + 'ap-southeast-1' => 'green.ap-southeast-1.aliyuncs.com', + ], + 'risk' => + [ + 'us-east-1' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'risk-cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'risk-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'risk-cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'risk-cn-hangzhou.aliyuncs.com', + ], + 'oceanbase' => + [ + 'us-east-1' => 'oceanbase.aliyuncs.com', + 'cn-hongkong' => 'oceanbase.aliyuncs.com', + 'cn-qingdao-cm9' => 'oceanbase.aliyuncs.com', + 'cn-shanghai' => 'oceanbasepro-share.cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'oceanbase.aliyuncs.com', + 'us-west-1' => 'oceanbase.aliyuncs.com', + 'cn-shanghai-inner' => 'oceanbase.aliyuncs.com', + 'cn-hangzhou' => 'oceanbasepro-share.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'oceanbase.aliyuncs.com', + 'cn-shenzhen' => 'oceanbase.aliyuncs.com', + 'cn-qingdao' => 'oceanbase.aliyuncs.com', + 'cn-beijing' => 'oceanbasepro-share.cn-beijing.aliyuncs.com', + 'cn-hangzhou-d' => 'oceanbase.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'oceanbase.aliyuncs.com', + 'ap-southeast-1' => 'oceanbasepro-share.ap-southeast-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'oceanbasepro-share.cn-shanghai-finance-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'oceanbasepro-share.cn-hangzhou.aliyuncs.com', + ], + 'msc' => + [ + 'us-east-1' => 'msc-inner.aliyuncs.com', + 'cn-hongkong' => 'msc-inner.aliyuncs.com', + 'cn-qingdao-cm9' => 'msc-inner.aliyuncs.com', + 'cn-shanghai' => 'msc-inner.aliyuncs.com', + 'cn-shenzhen-inner' => 'msc-inner.aliyuncs.com', + 'us-west-1' => 'msc-inner.aliyuncs.com', + 'cn-shanghai-inner' => 'msc-inner.aliyuncs.com', + 'cn-hangzhou' => 'msc-inner.aliyuncs.com', + 'cn-beijing-inner' => 'msc-inner.aliyuncs.com', + 'cn-beijing' => 'msc-inner.aliyuncs.com', + 'cn-hangzhou-d' => 'msc-inner.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'msc-inner.aliyuncs.com', + 'ap-southeast-1' => 'msc-inner.aliyuncs.com', + ], + 'yundunhsm' => + [ + 'us-east-1' => 'yundunhsm.aliyuncs.com', + 'cn-hongkong' => 'yundunhsm.aliyuncs.com', + 'cn-qingdao-cm9' => 'yundunhsm.aliyuncs.com', + 'cn-shanghai' => 'yundunhsm.aliyuncs.com', + 'cn-shenzhen-inner' => 'yundunhsm.aliyuncs.com', + 'us-west-1' => 'yundunhsm.aliyuncs.com', + 'cn-shanghai-inner' => 'yundunhsm.aliyuncs.com', + 'cn-hangzhou' => 'yundunhsm.aliyuncs.com', + 'cn-beijing-inner' => 'yundunhsm.aliyuncs.com', + 'cn-beijing' => 'yundunhsm.aliyuncs.com', + 'cn-hangzhou-d' => 'yundunhsm.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'yundunhsm.aliyuncs.com', + 'ap-southeast-1' => 'yundunhsm.aliyuncs.com', + ], + 'iot' => + [ + 'cn-hongkong' => 'iot.aliyuncs.com', + 'cn-qingdao-cm9' => 'iot.aliyuncs.com', + 'cn-shanghai' => 'iot.cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'iot.aliyuncs.com', + 'us-west-1' => 'iot.us-west-1.aliyuncs.com', + 'cn-shanghai-inner' => 'iot.aliyuncs.com', + 'cn-hangzhou' => 'iot.aliyuncs.com', + 'cn-beijing-inner' => 'iot.aliyuncs.com', + 'cn-shenzhen' => 'iot.aliyuncs.com', + 'cn-qingdao' => 'iot.aliyuncs.com', + 'cn-beijing' => 'iot.aliyuncs.com', + 'cn-hangzhou-d' => 'iot.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'iot.aliyuncs.com', + 'ap-southeast-1' => 'iot.ap-southeast-1.aliyuncs.com', + 'ap-northeast-1' => 'iot.ap-northeast-1.aliyuncs.com', + 'us-east-1' => 'iot.us-east-1.aliyuncs.com', + 'eu-central-1' => 'iot.eu-central-1.aliyuncs.com', + ], + 'oms' => + [ + 'us-east-1' => 'oms.aliyuncs.com', + 'cn-hongkong' => 'oms.aliyuncs.com', + 'cn-qingdao-cm9' => 'oms.aliyuncs.com', + 'cn-shanghai' => 'oms.aliyuncs.com', + 'cn-shenzhen-inner' => 'oms.aliyuncs.com', + 'us-west-1' => 'oms.aliyuncs.com', + 'cn-shanghai-inner' => 'oms.aliyuncs.com', + 'cn-hangzhou' => 'oms.aliyuncs.com', + 'cn-beijing-inner' => 'oms.aliyuncs.com', + 'cn-shenzhen' => 'oms.aliyuncs.com', + 'cn-qingdao' => 'oms.aliyuncs.com', + 'cn-beijing' => 'oms.aliyuncs.com', + 'cn-hangzhou-d' => 'oms.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'oms.aliyuncs.com', + 'ap-southeast-1' => 'oms.aliyuncs.com', + ], + 'live' => + [ + 'us-east-1' => 'live.aliyuncs.com', + 'cn-hongkong' => 'live.aliyuncs.com', + 'cn-qingdao-cm9' => 'live.aliyuncs.com', + 'cn-shanghai' => 'live.aliyuncs.com', + 'cn-shenzhen-inner' => 'live.aliyuncs.com', + 'us-west-1' => 'live.aliyuncs.com', + 'cn-shanghai-inner' => 'live.aliyuncs.com', + 'cn-hangzhou' => 'live.aliyuncs.com', + 'cn-beijing-inner' => 'live.aliyuncs.com', + 'cn-shenzhen' => 'live.aliyuncs.com', + 'cn-qingdao' => 'live.aliyuncs.com', + 'cn-beijing' => 'live.aliyuncs.com', + 'cn-hangzhou-d' => 'live.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'live.aliyuncs.com', + 'ap-southeast-1' => 'live.aliyuncs.com', + 'ap-northeast-1' => 'live.aliyuncs.com', + 'eu-central-1' => 'live.aliyuncs.com', + 'ap-southeast-5' => 'live.aliyuncs.com', + 'ap-south-1' => 'live.aliyuncs.com', + ], + 'ubsms' => + [ + 'us-east-1' => 'ubsms.aliyuncs.com', + 'cn-hongkong' => 'ubsms.aliyuncs.com', + 'cn-qingdao-cm9' => 'ubsms.aliyuncs.com', + 'cn-shanghai' => 'ubsms.aliyuncs.com', + 'cn-shenzhen-inner' => 'ubsms.aliyuncs.com', + 'us-west-1' => 'ubsms.aliyuncs.com', + 'cn-shanghai-inner' => 'ubsms.aliyuncs.com', + 'cn-hangzhou' => 'ubsms.aliyuncs.com', + 'cn-beijing-inner' => 'ubsms.aliyuncs.com', + 'cn-shenzhen' => 'ubsms.aliyuncs.com', + 'cn-qingdao' => 'ubsms.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'ubsms.aliyuncs.com', + 'cn-hangzhou-d' => 'ubsms.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ubsms.aliyuncs.com', + 'ap-southeast-1' => 'ubsms.aliyuncs.com', + ], + 'alert' => + [ + 'us-east-1' => 'alert.aliyuncs.com', + 'cn-hongkong' => 'alert.aliyuncs.com', + 'cn-qingdao-cm9' => 'alert.aliyuncs.com', + 'cn-shanghai' => 'alert.aliyuncs.com', + 'cn-shenzhen-inner' => 'alert.aliyuncs.com', + 'us-west-1' => 'alert.aliyuncs.com', + 'cn-shanghai-inner' => 'alert.aliyuncs.com', + 'cn-hangzhou' => 'alert.aliyuncs.com', + 'cn-beijing-inner' => 'alert.aliyuncs.com', + 'cn-shenzhen' => 'alert.aliyuncs.com', + 'cn-qingdao' => 'alert.aliyuncs.com', + 'cn-beijing' => 'alert.aliyuncs.com', + 'cn-hangzhou-d' => 'alert.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'alert.aliyuncs.com', + 'ap-southeast-1' => 'alert.aliyuncs.com', + ], + 'ace' => + [ + 'us-east-1' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'ace.cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'ace.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ace.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'ace.cn-hangzhou.aliyuncs.com', + ], + 'ams' => + [ + 'us-east-1' => 'ams.aliyuncs.com', + 'cn-hongkong' => 'ams.aliyuncs.com', + 'cn-qingdao-cm9' => 'ams.aliyuncs.com', + 'cn-shanghai' => 'ams.aliyuncs.com', + 'cn-shenzhen-inner' => 'ams.aliyuncs.com', + 'us-west-1' => 'ams.aliyuncs.com', + 'cn-shanghai-inner' => 'ams.aliyuncs.com', + 'cn-hangzhou' => 'ams.aliyuncs.com', + 'cn-beijing-inner' => 'ams.aliyuncs.com', + 'cn-beijing' => 'ams.aliyuncs.com', + 'cn-hangzhou-d' => 'ams.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ams.aliyuncs.com', + 'ap-southeast-1' => 'ams.aliyuncs.com', + ], + 'ros' => + [ + 'us-east-1' => 'ros.aliyuncs.com', + 'cn-hongkong' => 'ros.aliyuncs.com', + 'cn-qingdao-cm9' => 'ros.aliyuncs.com', + 'cn-shanghai' => 'ros.aliyuncs.com', + 'cn-shenzhen-inner' => 'ros.aliyuncs.com', + 'us-west-1' => 'ros.aliyuncs.com', + 'cn-shanghai-inner' => 'ros.aliyuncs.com', + 'cn-hangzhou' => 'ros.aliyuncs.com', + 'cn-beijing-inner' => 'ros.aliyuncs.com', + 'cn-shenzhen' => 'ros.aliyuncs.com', + 'cn-qingdao' => 'ros.aliyuncs.com', + 'cn-beijing' => 'ros.aliyuncs.com', + 'cn-hangzhou-d' => 'ros.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ros.aliyuncs.com', + 'ap-southeast-1' => 'ros.aliyuncs.com', + ], + 'pts' => + [ + 'us-east-1' => 'pts.aliyuncs.com', + 'cn-hongkong' => 'pts.aliyuncs.com', + 'cn-qingdao-cm9' => 'pts.aliyuncs.com', + 'cn-shanghai' => 'pts.aliyuncs.com', + 'cn-shenzhen-inner' => 'pts.aliyuncs.com', + 'us-west-1' => 'pts.aliyuncs.com', + 'cn-shanghai-inner' => 'pts.aliyuncs.com', + 'cn-hangzhou' => 'pts.aliyuncs.com', + 'cn-beijing-inner' => 'pts.aliyuncs.com', + 'cn-shenzhen' => 'pts.aliyuncs.com', + 'cn-qingdao' => 'pts.aliyuncs.com', + 'cn-beijing' => 'pts.aliyuncs.com', + 'cn-hangzhou-d' => 'pts.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'pts.aliyuncs.com', + 'ap-southeast-1' => 'pts.aliyuncs.com', + ], + 'qualitycheck' => + [ + 'us-east-1' => 'qualitycheck.aliyuncs.com', + 'cn-hongkong' => 'qualitycheck.aliyuncs.com', + 'cn-qingdao-cm9' => 'qualitycheck.aliyuncs.com', + 'cn-shanghai' => 'qualitycheck.aliyuncs.com', + 'cn-shenzhen-inner' => 'qualitycheck.aliyuncs.com', + 'us-west-1' => 'qualitycheck.aliyuncs.com', + 'cn-shanghai-inner' => 'qualitycheck.aliyuncs.com', + 'cn-hangzhou' => 'qualitycheck.aliyuncs.com', + 'cn-beijing-inner' => 'qualitycheck.aliyuncs.com', + 'cn-hangzhou-d' => 'qualitycheck.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'qualitycheck.aliyuncs.com', + 'ap-southeast-1' => 'qualitycheck.aliyuncs.com', + ], + 'm-kvstore' => + [ + 'us-east-1' => 'm-kvstore.aliyuncs.com', + 'cn-hongkong' => 'm-kvstore.aliyuncs.com', + 'cn-qingdao-cm9' => 'm-kvstore.aliyuncs.com', + 'cn-shanghai' => 'm-kvstore.aliyuncs.com', + 'cn-shenzhen-inner' => 'm-kvstore.aliyuncs.com', + 'us-west-1' => 'm-kvstore.aliyuncs.com', + 'cn-shanghai-inner' => 'm-kvstore.aliyuncs.com', + 'cn-hangzhou' => 'm-kvstore.aliyuncs.com', + 'cn-beijing-inner' => 'm-kvstore.aliyuncs.com', + 'cn-shenzhen' => 'm-kvstore.aliyuncs.com', + 'cn-qingdao' => 'm-kvstore.aliyuncs.com', + 'cn-beijing' => 'm-kvstore.aliyuncs.com', + 'cn-hangzhou-d' => 'm-kvstore.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'm-kvstore.aliyuncs.com', + 'ap-southeast-1' => 'm-kvstore.aliyuncs.com', + ], + 'highddos' => + [ + 'us-east-1' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'yd-highddos-cn-hangzhou.aliyuncs.com', + ], + 'cmssitemonitor' => + [ + 'us-east-1' => 'sitemonitor.aliyuncs.com', + 'cn-hongkong' => 'sitemonitor.aliyuncs.com', + 'cn-qingdao-cm9' => 'sitemonitor.aliyuncs.com', + 'cn-shanghai' => 'sitemonitor.aliyuncs.com', + 'cn-shenzhen-inner' => 'sitemonitor.aliyuncs.com', + 'us-west-1' => 'sitemonitor.aliyuncs.com', + 'cn-shanghai-inner' => 'sitemonitor.aliyuncs.com', + 'cn-hangzhou' => 'sitemonitor.aliyuncs.com', + 'cn-beijing-inner' => 'sitemonitor.aliyuncs.com', + 'cn-shenzhen' => 'sitemonitor.aliyuncs.com', + 'cn-qingdao' => 'sitemonitor.aliyuncs.com', + 'cn-beijing' => 'sitemonitor.aliyuncs.com', + 'cn-hangzhou-d' => 'sitemonitor.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'sitemonitor.aliyuncs.com', + 'ap-southeast-1' => 'sitemonitor.aliyuncs.com', + ], + 'batchcompute' => + [ + 'us-east-1' => 'batchCompute.us-east-1.aliyuncs.com', + 'cn-hongkong' => 'batchCompute.cn-hongkong.aliyuncs.com', + 'cn-shanghai' => 'batchCompute.cn-shanghai.aliyuncs.com', + 'us-west-1' => 'batchCompute.us-west-1.aliyuncs.com', + 'cn-hangzhou' => 'batchCompute.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'batchcompute.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'batchcompute.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'batchCompute.cn-beijing.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'batchCompute.cn-shanghai-et2-b01.aliyuncs.com', + 'ap-southeast-1' => 'batchCompute.ap-southeast-1.aliyuncs.com', + ], + 'cf' => + [ + 'us-east-1' => 'cf.aliyuncs.com', + 'cn-hongkong' => 'cf.aliyuncs.com', + 'cn-qingdao-cm9' => 'cf.aliyuncs.com', + 'cn-shanghai' => 'cf.aliyuncs.com', + 'cn-shenzhen-inner' => 'cf.aliyuncs.com', + 'us-west-1' => 'cf.aliyuncs.com', + 'cn-shanghai-inner' => 'cf.aliyuncs.com', + 'cn-hangzhou' => 'cf.aliyuncs.com', + 'cn-beijing-inner' => 'cf.aliyuncs.com', + 'cn-shenzhen' => 'cf.aliyuncs.com', + 'cn-qingdao' => 'cf.aliyuncs.com', + 'cn-beijing' => 'cf.aliyuncs.com', + 'cn-hangzhou-d' => 'cf.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'cf.aliyuncs.com', + 'ap-southeast-1' => 'cf.aliyuncs.com', + ], + 'drds' => + [ + 'us-east-1' => 'drds.aliyuncs.com', + 'cn-hongkong' => 'drds.aliyuncs.com', + 'cn-qingdao-cm9' => 'drds.aliyuncs.com', + 'cn-shanghai' => 'drds.aliyuncs.com', + 'cn-shenzhen-inner' => 'drds.aliyuncs.com', + 'us-west-1' => 'drds.aliyuncs.com', + 'cn-shanghai-inner' => 'drds.aliyuncs.com', + 'cn-hangzhou' => 'drds.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'drds.aliyuncs.com', + 'cn-shenzhen' => 'drds.aliyuncs.com', + 'cn-qingdao' => 'drds.aliyuncs.com', + 'cn-beijing' => 'drds.aliyuncs.com', + 'cn-hangzhou-d' => 'drds.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'drds.aliyuncs.com', + 'ap-southeast-1' => 'drds.aliyuncs.com', + ], + 'acs' => + [ + 'us-east-1' => 'acs.aliyun-inc.com', + 'cn-hongkong' => 'acs.aliyun-inc.com', + 'cn-shanghai' => 'acs.aliyun-inc.com', + 'us-west-1' => 'acs.aliyun-inc.com', + 'cn-hangzhou' => 'acs.aliyun-inc.com', + 'cn-shenzhen' => 'acs.aliyun-inc.com', + 'cn-qingdao' => 'acs.aliyun-inc.com', + 'cn-beijing' => 'acs.aliyun-inc.com', + 'cn-shanghai-et2-b01' => 'acs.aliyun-inc.com', + ], + 'httpdns' => + [ + 'us-east-1' => 'httpdns-api.aliyuncs.com', + 'cn-hongkong' => 'httpdns-api.aliyuncs.com', + 'cn-qingdao-cm9' => 'httpdns-api.aliyuncs.com', + 'cn-shanghai' => 'httpdns-api.aliyuncs.com', + 'cn-shenzhen-inner' => 'httpdns-api.aliyuncs.com', + 'us-west-1' => 'httpdns-api.aliyuncs.com', + 'cn-shanghai-inner' => 'httpdns-api.aliyuncs.com', + 'cn-hangzhou' => 'httpdns-api.aliyuncs.com', + 'cn-beijing-inner' => 'httpdns-api.aliyuncs.com', + 'cn-shenzhen' => 'httpdns-api.aliyuncs.com', + 'cn-qingdao' => 'httpdns-api.aliyuncs.com', + 'cn-beijing' => 'httpdns-api.aliyuncs.com', + 'cn-hangzhou-d' => 'httpdns-api.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'httpdns-api.aliyuncs.com', + 'ap-southeast-1' => 'httpdns-api.aliyuncs.com', + ], + 'location-inner' => + [ + 'us-east-1' => 'location-inner.aliyuncs.com', + 'cn-hongkong' => 'location-inner.aliyuncs.com', + 'cn-qingdao-cm9' => 'location-inner.aliyuncs.com', + 'cn-shanghai' => 'location-inner.aliyuncs.com', + 'cn-shenzhen-inner' => 'location-inner.aliyuncs.com', + 'us-west-1' => 'location-inner.aliyuncs.com', + 'cn-shanghai-inner' => 'location-inner.aliyuncs.com', + 'cn-hangzhou' => 'location-inner.aliyuncs.com', + 'cn-beijing-inner' => 'location-inner.aliyuncs.com', + 'cn-shenzhen' => 'location-inner.aliyuncs.com', + 'cn-qingdao' => 'location-inner.aliyuncs.com', + 'cn-beijing' => 'location-inner.aliyuncs.com', + 'cn-hangzhou-d' => 'location-inner.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'location-inner.aliyuncs.com', + 'ap-southeast-1' => 'location-inner.aliyuncs.com', + ], + 'aas' => + [ + 'us-east-1' => 'aas.aliyuncs.com', + 'cn-hongkong' => 'aas.aliyuncs.com', + 'cn-qingdao-cm9' => 'aas.aliyuncs.com', + 'cn-shanghai' => 'aas.aliyuncs.com', + 'cn-shenzhen-inner' => 'aas.aliyuncs.com', + 'us-west-1' => 'aas.aliyuncs.com', + 'cn-shanghai-inner' => 'aas.aliyuncs.com', + 'cn-hangzhou' => 'aas.aliyuncs.com', + 'cn-beijing-inner' => 'aas.aliyuncs.com', + 'cn-shenzhen' => 'aas.aliyuncs.com', + 'cn-qingdao' => 'aas.aliyuncs.com', + 'cn-beijing' => 'aas.aliyuncs.com', + 'cn-hangzhou-d' => 'aas.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'aas.aliyuncs.com', + 'ap-southeast-1' => 'aas.aliyuncs.com', + ], + 'sts' => + [ + 'cn-hangzhou' => 'sts.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'sts.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'sts.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'sts.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'sts.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'sts.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'sts.cn-huhehaote.aliyuncs.com', + 'cn-hongkong' => 'sts.cn-hongkong.aliyuncs.com', + 'cn-chengdu' => 'sts.cn-chengdu.aliyuncs.com', + 'ap-southeast-1' => 'sts.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'sts.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'sts.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'sts.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'sts.ap-northeast-1.aliyuncs.com', + 'ap-south-1' => 'sts.ap-south-1.aliyuncs.com', + 'us-west-1' => 'sts.us-west-1.aliyuncs.com', + 'us-east-1' => 'sts.us-east-1.aliyuncs.com', + 'eu-central-1' => 'sts.eu-central-1.aliyuncs.com', + 'me-east-1' => 'sts.me-east-1.aliyuncs.com', + 'eu-west-1' => 'sts.eu-west-1.aliyuncs.com', + ], + 'dts' => + [ + 'us-east-1' => 'dts.aliyuncs.com', + 'cn-hongkong' => 'dts.aliyuncs.com', + 'cn-qingdao-cm9' => 'dts.aliyuncs.com', + 'cn-shanghai' => 'dts.aliyuncs.com', + 'cn-shenzhen-inner' => 'dts.aliyuncs.com', + 'us-west-1' => 'dts.aliyuncs.com', + 'cn-shanghai-inner' => 'dts.aliyuncs.com', + 'cn-hangzhou' => 'dts.aliyuncs.com', + 'cn-beijing-inner' => 'dts.aliyuncs.com', + 'cn-shenzhen' => 'dts.aliyuncs.com', + 'cn-qingdao' => 'dts.aliyuncs.com', + 'cn-beijing' => 'dts.aliyuncs.com', + 'cn-hangzhou-d' => 'dts.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'dts.aliyuncs.com', + 'ap-southeast-1' => 'dts.aliyuncs.com', + 'cn-zhangjiakou' => 'dts.aliyuncs.com', + 'cn-huhehaote' => 'dts.aliyuncs.com', + 'ap-southeast-2' => 'dts.aliyuncs.com', + 'ap-southeast-3' => 'dts.aliyuncs.com', + 'ap-southeast-5' => 'dts.aliyuncs.com', + 'eu-west-1' => 'dts.aliyuncs.com', + 'eu-central-1' => 'dts.aliyuncs.com', + 'me-east-1' => 'dts.aliyuncs.com', + 'ap-south-1' => 'dts.aliyuncs.com', + 'cn-hangzhou-finance' => 'dts.aliyuncs.com', + 'cn-shanghai-finance-1' => 'dts.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'dts.aliyuncs.com', + 'cn-north-2-gov-1' => 'dts.aliyuncs.com', + 'cn-beijing-gov-1' => 'dts.aliyuncs.com', + ], + 'drc' => + [ + 'us-east-1' => 'drc.aliyuncs.com', + 'cn-hongkong' => 'drc.aliyuncs.com', + 'cn-qingdao-cm9' => 'drc.aliyuncs.com', + 'cn-shanghai' => 'drc.aliyuncs.com', + 'cn-shenzhen-inner' => 'drc.aliyuncs.com', + 'us-west-1' => 'drc.aliyuncs.com', + 'cn-shanghai-inner' => 'drc.aliyuncs.com', + 'cn-hangzhou' => 'drc.aliyuncs.com', + 'cn-beijing-inner' => 'drc.aliyuncs.com', + 'cn-shenzhen' => 'drc.aliyuncs.com', + 'cn-qingdao' => 'drc.aliyuncs.com', + 'cn-beijing' => 'drc.aliyuncs.com', + 'cn-hangzhou-d' => 'drc.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'drc.aliyuncs.com', + 'ap-southeast-1' => 'drc.aliyuncs.com', + ], + 'vpc-inner' => + [ + 'us-east-1' => 'vpc-inner.aliyuncs.com', + 'cn-hongkong' => 'vpc-inner.aliyuncs.com', + 'cn-shanghai' => 'vpc-inner.aliyuncs.com', + 'us-west-1' => 'vpc-inner.aliyuncs.com', + 'cn-hangzhou' => 'vpc-inner.aliyuncs.com', + 'cn-shenzhen' => 'vpc-inner.aliyuncs.com', + 'cn-qingdao' => 'vpc-inner.aliyuncs.com', + 'cn-beijing' => 'vpc-inner.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'vpc-inner.aliyuncs.com', + ], + 'crm' => + [ + 'us-east-1' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'crm-cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'crm-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'crm-cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'crm-cn-hangzhou.aliyuncs.com', + ], + 'domain' => + [ + 'us-east-1' => 'domain.aliyuncs.com', + 'cn-hongkong' => 'domain.aliyuncs.com', + 'cn-qingdao-cm9' => 'domain.aliyuncs.com', + 'cn-shanghai' => 'domain.aliyuncs.com', + 'cn-shenzhen-inner' => 'domain.aliyuncs.com', + 'us-west-1' => 'domain.aliyuncs.com', + 'cn-shanghai-inner' => 'domain.aliyuncs.com', + 'cn-hangzhou' => 'domain.aliyuncs.com', + 'cn-beijing-inner' => 'domain.aliyuncs.com', + 'cn-shenzhen' => 'domain.aliyuncs.com', + 'cn-qingdao' => 'domain.aliyuncs.com', + 'cn-beijing' => 'domain.aliyuncs.com', + 'cn-hangzhou-d' => 'domain.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'domain.aliyuncs.com', + 'ap-southeast-1' => 'domain.aliyuncs.com', + ], + 'ots' => + [ + 'us-east-1' => 'ots.us-east-1.aliyuncs.com', + 'cn-hongkong' => 'ots.cn-hongkong.aliyuncs.com', + 'cn-qingdao-cm9' => 'ots-pop.aliyuncs.com', + 'cn-shanghai' => 'ots.cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'ots-pop.aliyuncs.com', + 'us-west-1' => 'ots.us-west-1.aliyuncs.com', + 'cn-shanghai-inner' => 'ots-pop.aliyuncs.com', + 'cn-hangzhou' => 'ots.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'ots-pop.aliyuncs.com', + 'cn-shenzhen' => 'ots.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'ots.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'ots.cn-beijing.aliyuncs.com', + 'cn-hangzhou-d' => 'ots-pop.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ots-pop.aliyuncs.com', + 'ap-southeast-1' => 'ots.ap-southeast-1.aliyuncs.com', + 'cn-zhangjiakou' => 'ots.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'ots.cn-huhehaote.aliyuncs.com', + 'ap-southeast-2' => 'ots.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'ots.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'ots.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'ots.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'ots.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'ots.eu-central-1.aliyuncs.com', + 'me-east-1' => 'ots.me-east-1.aliyuncs.com', + 'ap-south-1' => 'ots.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'ots.cn-chengdu.aliyuncs.com', + 'cn-shanghai-finance-1' => 'ots.cn-shanghai-finance-1.aliyuncs.com', + ], + 'oss' => + [ + 'us-east-1' => 'oss-cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'oss-cn-hongkong.aliyuncs.com', + 'cn-qingdao-cm9' => 'oss-cn-hangzhou.aliyuncs.com', + 'cn-qingdao-finance' => 'oss-cn-qdjbp-a.aliyuncs.com', + 'cn-beijing-gov-1' => 'oss-cn-haidian-a.aliyuncs.com', + 'cn-shanghai' => 'oss-cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'oss-cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'oss-us-west-1.aliyuncs.com', + 'cn-shanghai-inner' => 'oss-cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-finance' => 'oss-cn-hzjbp-b-console.aliyuncs.com', + 'cn-hangzhou' => 'oss-cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'oss-cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'oss-cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'oss-cn-qingdao.aliyuncs.com', + 'oss-cn-bjzwy' => 'oss-cn-bjzwy.aliyuncs.com', + 'cn-beijing' => 'oss-cn-beijing.aliyuncs.com', + 'cn-hangzhou-d' => 'oss-cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'oss-cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'oss-ap-southeast-1.aliyuncs.com', + 'cn-chengdu' => 'oss-cn-chengdu.aliyuncs.com', + 'ap-northeast-1' => 'oss-ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'oss-eu-west-1.aliyuncs.com', + 'me-east-1' => 'oss-me-east-1.aliyuncs.com', + 'ap-south-1' => 'oss-ap-south-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'oss-cn-shanghai-finance-1-internal.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'oss-cn-shenzhen-finance-1-internal.aliyuncs.com', + 'cn-huhehaote-nebula-1' => 'oss-cn-huhehaote-nebula-1.aliyuncs.com', + 'cn-zhengzhou-nebula-1' => 'oss-cn-zhengzhou-nebula-1.aliyuncs.com', + 'cn-heyuan' => 'oss-cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'oss-cn-wulanchabu.aliyuncs.com', + ], + 'ram' => + [ + 'global' => 'ram.aliyuncs.com', + 'us-east-1' => 'ram.aliyuncs.com', + 'cn-hongkong' => 'ram.aliyuncs.com', + 'cn-qingdao-cm9' => 'ram.aliyuncs.com', + 'cn-shanghai' => 'ram.aliyuncs.com', + 'cn-shenzhen-inner' => 'ram.aliyuncs.com', + 'us-west-1' => 'ram.aliyuncs.com', + 'cn-shanghai-inner' => 'ram.aliyuncs.com', + 'cn-hangzhou' => 'ram.aliyuncs.com', + 'cn-beijing-inner' => 'ram.aliyuncs.com', + 'cn-shenzhen' => 'ram.aliyuncs.com', + 'cn-qingdao' => 'ram.aliyuncs.com', + 'cn-beijing' => 'ram.aliyuncs.com', + 'cn-hangzhou-d' => 'ram.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ram.aliyuncs.com', + 'ap-southeast-1' => 'ram.aliyuncs.com', + ], + 'sales' => + [ + 'us-east-1' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'sales.cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'sales.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'sales.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'sales.cn-hangzhou.aliyuncs.com', + ], + 'ossadmin' => + [ + 'us-east-1' => 'oss-admin.aliyuncs.com', + 'cn-hongkong' => 'oss-admin.aliyuncs.com', + 'cn-qingdao-cm9' => 'oss-admin.aliyuncs.com', + 'cn-shanghai' => 'oss-admin.aliyuncs.com', + 'cn-shenzhen-inner' => 'oss-admin.aliyuncs.com', + 'us-west-1' => 'oss-admin.aliyuncs.com', + 'cn-shanghai-inner' => 'oss-admin.aliyuncs.com', + 'cn-hangzhou' => 'oss-admin.aliyuncs.com', + 'cn-beijing-inner' => 'oss-admin.aliyuncs.com', + 'cn-shenzhen' => 'oss-admin.aliyuncs.com', + 'cn-qingdao' => 'oss-admin.aliyuncs.com', + 'cn-beijing' => 'oss-admin.aliyuncs.com', + 'cn-hangzhou-d' => 'oss-admin.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'oss-admin.aliyuncs.com', + 'ap-southeast-1' => 'oss-admin.aliyuncs.com', + ], + 'alidns' => + [ + 'us-east-1' => 'alidns.aliyuncs.com', + 'cn-hongkong' => 'alidns.aliyuncs.com', + 'cn-qingdao-cm9' => 'alidns.aliyuncs.com', + 'cn-shanghai' => 'alidns.aliyuncs.com', + 'cn-shenzhen-inner' => 'alidns.aliyuncs.com', + 'us-west-1' => 'alidns.aliyuncs.com', + 'cn-shanghai-inner' => 'alidns.aliyuncs.com', + 'cn-hangzhou' => 'alidns.aliyuncs.com', + 'cn-beijing-inner' => 'alidns.aliyuncs.com', + 'cn-shenzhen' => 'alidns.aliyuncs.com', + 'cn-qingdao' => 'alidns.aliyuncs.com', + 'cn-beijing' => 'alidns.aliyuncs.com', + 'cn-hangzhou-d' => 'alidns.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'alidns.aliyuncs.com', + 'ap-southeast-1' => 'alidns.aliyuncs.com', + ], + 'ons' => + [ + 'us-east-1' => 'ons.us-east-1.aliyuncs.com', + 'cn-hongkong' => 'ons.cn-hongkong.aliyuncs.com', + 'cn-qingdao-cm9' => 'ons.aliyuncs.com', + 'cn-shanghai' => 'ons.cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'ons.aliyuncs.com', + 'us-west-1' => 'ons.us-west-1.aliyuncs.com', + 'cn-shanghai-inner' => 'ons.aliyuncs.com', + 'cn-hangzhou' => 'ons.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'ons.aliyuncs.com', + 'cn-shenzhen' => 'ons.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'ons.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'ons.cn-beijing.aliyuncs.com', + 'cn-hangzhou-d' => 'ons.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'ons.aliyuncs.com', + 'ap-southeast-1' => 'ons.ap-southeast-1.aliyuncs.com', + 'cn-zhangjiakou' => 'ons.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'ons.cn-huhehaote.aliyuncs.com', + 'ap-southeast-2' => 'ons.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'ons.ap-southeast-3.aliyuncs.com', + 'ap-northeast-1' => 'ons.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'ons.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'ons.eu-central-1.aliyuncs.com', + 'me-east-1' => 'ons.me-east-1.aliyuncs.com', + 'ap-south-1' => 'ons.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'ons.cn-chengdu.aliyuncs.com', + 'cn-hangzhou-finance' => 'ons.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'ons.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'ons.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'ons.cn-north-2-gov-1.aliyuncs.com', + 'ap-southeast-5' => 'ons.ap-southeast-5.aliyuncs.com', + ], + 'cdn' => + [ + 'global' => 'cdn.aliyuncs.com', + 'us-east-1' => 'cdn.aliyuncs.com', + 'cn-hongkong' => 'cdn.aliyuncs.com', + 'cn-qingdao-cm9' => 'cdn.aliyuncs.com', + 'cn-shanghai' => 'cdn.aliyuncs.com', + 'cn-shenzhen-inner' => 'cdn.aliyuncs.com', + 'us-west-1' => 'cdn.aliyuncs.com', + 'cn-shanghai-inner' => 'cdn.aliyuncs.com', + 'cn-hangzhou' => 'cdn.aliyuncs.com', + 'cn-beijing-inner' => 'cdn.aliyuncs.com', + 'cn-shenzhen' => 'cdn.aliyuncs.com', + 'cn-qingdao' => 'cdn.aliyuncs.com', + 'cn-beijing' => 'cdn.aliyuncs.com', + 'cn-hangzhou-d' => 'cdn.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'cdn.aliyuncs.com', + 'ap-southeast-1' => 'cdn.aliyuncs.com', + ], + 'yundunddos' => + [ + 'us-east-1' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-qingdao-cm9' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-inner' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'us-west-1' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-inner' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou-d' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'inner-yundun-ddos.cn-hangzhou.aliyuncs.com', + ], + 'kvstore' => + [ + 'ap-northeast-1' => 'r-kvstore.ap-northeast-1.aliyuncs.com', + ], + 'cloudapi' => + [ + 'cn-hongkong' => 'apigateway.cn-hongkong.aliyuncs.com', + 'cn-shanghai' => 'apigateway.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'apigateway.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'apigateway.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'apigateway.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'apigateway.cn-beijing.aliyuncs.com', + 'ap-southeast-1' => 'apigateway.ap-southeast-1.aliyuncs.com', + ], + 'mts' => + [ + 'cn-hongkong' => 'mts.cn-hongkong.aliyuncs.com', + 'cn-qingdao-cm9' => 'mts.cn-qingdao.aliyuncs.com', + 'cn-shanghai' => 'mts.cn-shanghai.aliyuncs.com', + 'cn-shenzhen-inner' => 'mts.cn-shenzhen.aliyuncs.com', + 'us-west-1' => 'mts.us-west-1.aliyuncs.com', + 'cn-shanghai-inner' => 'mts.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'mts.cn-hangzhou.aliyuncs.com', + 'cn-beijing-inner' => 'mts.cn-beijing.aliyuncs.com', + 'cn-shenzhen' => 'mts.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'mts.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'mts.cn-beijing.aliyuncs.com', + 'cn-hangzhou-d' => 'mts.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'mts.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'mts.ap-southeast-1.aliyuncs.com', + 'cn-zhangjiakou' => 'mts.cn-zhangjiakou.aliyuncs.com', + 'ap-northeast-1' => 'mts.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'mts.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'mts.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'mts.ap-south-1.aliyuncs.com', + 'ap-southeast-5' => 'mts.ap-southeast-5.aliyuncs.com', + ], + 'saf' => + [ + 'cn-shanghai' => 'saf.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'saf.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'saf.cn-shenzhen.aliyuncs.com', + 'ap-southeast-1' => 'saf.ap-southeast-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'saf.cn-north-2-gov-1.aliyuncs.com', + 'cn-zhangjiakou' => 'saf.cn-zhangjiakou.aliyuncs.com', + ], + 'arms' => + [ + 'cn-shanghai' => 'arms.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'arms.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'arms.cn-shenzhen.aliyuncs.com', + 'cn-beijing' => 'arms.cn-beijing.aliyuncs.com', + 'cn-qingdao' => 'arms.cn-qingdao.aliyuncs.com', + 'cn-zhangjiakou' => 'arms.cn-zhangjiakou.aliyuncs.com', + 'cn-hongkong' => 'arms.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'arms.ap-southeast-1.aliyuncs.com', + 'ap-south-1' => 'arms.ap-south-1.aliyuncs.com', + ], + 'apigateway' => + [ + 'cn-shanghai' => 'apigateway.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'apigateway.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'apigateway.cn-shenzhen.aliyuncs.com', + 'cn-qingdao' => 'apigateway.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'apigateway.cn-beijing.aliyuncs.com', + 'ap-southeast-1' => 'apigateway.ap-southeast-1.aliyuncs.com', + 'cn-hongkong' => 'apigateway.cn-hongkong.aliyuncs.com', + 'ap-southeast-2' => 'apigateway.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'apigateway.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'apigateway.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'apigateway.ap-northeast-1.aliyuncs.com', + 'eu-central-1' => 'apigateway.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'apigateway.ap-south-1.aliyuncs.com', + 'eu-west-1' => 'apigateway.eu-west-1.aliyuncs.com', + 'me-east-1' => 'apigateway.me-east-1.aliyuncs.com', + 'us-east-1' => 'apigateway.us-east-1.aliyuncs.com', + 'us-west-1' => 'apigateway.us-west-1.aliyuncs.com', + 'cn-zhangjiakou' => 'apigateway.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'apigateway.cn-huhehaote.aliyuncs.com', + 'cn-chengdu' => 'apigateway.cn-chengdu.aliyuncs.com', + 'cn-north-2-gov-1' => 'apigateway.cn-north-2-gov-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'apigateway.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'apigateway.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'apigateway.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-shanghai-inner' => 'apigateway.cn-shanghai-inner.aliyuncs.com', + 'cn-heyuan' => 'apigateway.cn-heyuan.aliyuncs.com', + ], + 'vod' => + [ + 'cn-shanghai' => 'vod.cn-shanghai.aliyuncs.com', + 'cn-beijing' => 'vod.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'vod.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'vod.cn-shenzhen.aliyuncs.com', + 'ap-southeast-1' => 'vod.ap-southeast-1.aliyuncs.com', + 'eu-central-1' => 'vod.eu-central-1.aliyuncs.com', + 'cn-zhangjiakou' => 'vod.cn-zhangjiakou.aliyuncs.com', + 'cn-hongkong' => 'vod.cn-hongkong.aliyuncs.com', + 'ap-southeast-5' => 'vod.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'vod.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'vod.eu-west-1.aliyuncs.com', + 'us-west-1' => 'vod.us-west-1.aliyuncs.com', + 'ap-south-1' => 'vod.ap-south-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'vod.cn-north-2-gov-1.aliyuncs.com', + ], + 'afs' => + [ + 'cn-hangzhou' => 'afs.aliyuncs.com', + ], + 'oas' => + [ + 'cn-hangzhou' => 'cn-hangzhou.oas.aliyuncs.com', + 'cn-shenzhen' => 'cn-shenzhen.oas.aliyuncs.com', + 'cn-beijing' => 'cn-beijing.oas.aliyuncs.com', + ], + 'alikafka' => + [ + 'cn-qingdao' => 'alikafka.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'alikafka.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'alikafka.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'alikafka.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'alikafka.cn-shenzhen.aliyuncs.com', + 'cn-zhangjiakou' => 'alikafka.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'alikafka.cn-huhehaote.aliyuncs.com', + 'cn-hongkong' => 'alikafka.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'alikafka.ap-southeast-1.aliyuncs.com', + 'ap-southeast-5' => 'alikafka.ap-southeast-5.aliyuncs.com', + 'ap-south-1' => 'alikafka.ap-south-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'alikafka.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'alikafka.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'alikafka.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-chengdu' => 'alikafka.cn-chengdu.aliyuncs.com', + 'cn-north-2-gov-1' => 'alikafka.cn-north-2-gov-1.aliyuncs.com', + 'cn-heyuan' => 'alikafka.cn-heyuan.aliyuncs.com', + 'ap-southeast-3' => 'alikafka.ap-southeast-3.aliyuncs.com', + 'ap-northeast-1' => 'alikafka.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'alikafka.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'alikafka.eu-central-1.aliyuncs.com', + ], + 'cbn' => + [ + 'cn-qingdao' => 'cbn.aliyuncs.com', + 'cn-beijing' => 'cbn.aliyuncs.com', + 'cn-zhangjiakou' => 'cbn.aliyuncs.com', + 'cn-huhehaote' => 'cbn.aliyuncs.com', + 'cn-hangzhou' => 'cbn.aliyuncs.com', + 'cn-shanghai' => 'cbn.aliyuncs.com', + 'cn-shenzhen' => 'cbn.aliyuncs.com', + 'cn-hongkong' => 'cbn.aliyuncs.com', + 'ap-southeast-1' => 'cbn.aliyuncs.com', + 'ap-southeast-2' => 'cbn.aliyuncs.com', + 'ap-southeast-3' => 'cbn.aliyuncs.com', + 'ap-southeast-5' => 'cbn.aliyuncs.com', + 'ap-northeast-1' => 'cbn.aliyuncs.com', + 'eu-west-1' => 'cbn.aliyuncs.com', + 'us-west-1' => 'cbn.aliyuncs.com', + 'us-east-1' => 'cbn.aliyuncs.com', + 'eu-central-1' => 'cbn.aliyuncs.com', + 'me-east-1' => 'cbn.aliyuncs.com', + 'ap-south-1' => 'cbn.aliyuncs.com', + 'cn-chengdu' => 'cbn.aliyuncs.com', + 'cn-shanghai-finance-1' => 'cbn.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'cbn.aliyuncs.com', + 'ap-northeast-2-pop' => 'cbn.aliyuncs.com', + 'cn-beijing-finance-pop' => 'cbn.aliyuncs.com', + 'cn-hangzhou-internal-test-1' => 'cbn.aliyuncs.com', + 'cn-hangzhou-internal-test-2' => 'cbn.aliyuncs.com', + 'cn-hangzhou-internal-test-3' => 'cbn.aliyuncs.com', + 'cn-wuhan' => 'cbn.aliyuncs.com', + 'cn-heyuan' => 'cbn.aliyuncs.com', + 'cn-wulanchabu' => 'cbn.aliyuncs.com', + 'cn-north-2-gov-1' => 'cbn.aliyuncs.com', + ], + 'onsvip' => + [ + 'cn-qingdao' => 'ons.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'ons.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'ons.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ons.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'ons.cn-shenzhen.aliyuncs.com', + 'ap-southeast-1' => 'ons.ap-southeast-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'ons.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'ons.cn-shanghai-finance.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'ons.cn-shenzhen-finance.aliyuncs.com', + ], + 'ddosbgp' => + [ + 'cn-qingdao' => 'ddosbgp.aliyuncs.com', + 'cn-beijing' => 'ddosbgp.aliyuncs.com', + 'cn-zhangjiakou' => 'ddosbgp.aliyuncs.com', + 'cn-huhehaote' => 'ddosbgp.aliyuncs.com', + 'cn-hangzhou' => 'ddosbgp.aliyuncs.com', + 'cn-shanghai' => 'ddosbgp.aliyuncs.com', + 'cn-shenzhen' => 'ddosbgp.aliyuncs.com', + 'cn-hongkong' => 'ddosbgp.cn-hongkong.aliyuncs.com', + 'us-west-1' => 'ddosbgp.us-west-1.aliyuncs.com', + 'ap-southeast-1' => 'ddosbgp.ap-southeast-1.aliyuncs.com', + 'us-east-1' => 'ddosbgp.us-east-1.aliyuncs.com', + 'cn-chengdu' => 'ddosbgp.aliyuncs.com', + 'cn-heyuan' => 'ddosbgp.aliyuncs.com', + 'cn-wulanchabu' => 'ddosbgp.aliyuncs.com', + 'ap-southeast-2' => 'ddosbgp.aliyuncs.com', + 'ap-southeast-3' => 'ddosbgp.aliyuncs.com', + 'ap-southeast-5' => 'ddosbgp.aliyuncs.com', + 'ap-northeast-1' => 'ddosbgp.aliyuncs.com', + 'eu-west-1' => 'ddosbgp.aliyuncs.com', + 'eu-central-1' => 'ddosbgp.aliyuncs.com', + 'me-east-1' => 'ddosbgp.aliyuncs.com', + 'ap-south-1' => 'ddosbgp.aliyuncs.com', + ], + 'ehs' => + [ + 'cn-qingdao' => 'ehpc.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'ehpc.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'ehpc.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'ehpc.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'ehpc.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ehpc.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'ehpc.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'ehpc.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'ehpc.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'ehpc.ap-southeast-2.aliyuncs.com', + 'eu-central-1' => 'ehpc.eu-central-1.aliyuncs.com', + 'ap-northeast-1' => 'ehpc.ap-northeast-1.aliyuncs.com', + ], + 'redisa' => + [ + 'cn-qingdao' => 'r-kvstore.aliyuncs.com', + 'cn-beijing' => 'r-kvstore.aliyuncs.com', + 'cn-zhangjiakou' => 'r-kvstore.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'r-kvstore.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'r-kvstore.aliyuncs.com', + 'cn-shanghai' => 'r-kvstore.aliyuncs.com', + 'cn-shenzhen' => 'r-kvstore.aliyuncs.com', + 'cn-hongkong' => 'r-kvstore.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'r-kvstore.aliyuncs.com', + 'ap-southeast-2' => 'r-kvstore.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'r-kvstore.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'r-kvstore.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'r-kvstore.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'r-kvstore.eu-west-1.aliyuncs.com', + 'us-west-1' => 'r-kvstore.aliyuncs.com', + 'us-east-1' => 'r-kvstore.aliyuncs.com', + 'eu-central-1' => 'r-kvstore.eu-central-1.aliyuncs.com', + 'me-east-1' => 'r-kvstore.me-east-1.aliyuncs.com', + 'ap-south-1' => 'r-kvstore.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'r-kvstore.cn-chengdu.aliyuncs.com', + 'cn-hangzhou-finance' => 'r-kvstore.aliyuncs.com', + 'cn-shanghai-finance-1' => 'r-kvstore.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'r-kvstore.aliyuncs.com', + 'cn-north-2-gov-1' => 'r-kvstore.aliyuncs.com', + 'cn-heyuan' => 'r-kvstore.aliyuncs.com', + 'cn-wulanchabu' => 'r-kvstore.aliyuncs.com', + ], + 'nas' => + [ + 'cn-qingdao' => 'nas.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'nas.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'nas.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'nas.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'nas.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'nas.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'nas.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'nas.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'nas.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'nas.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'nas.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'nas.ap-southeast-5.aliyuncs.com', + 'us-east-1' => 'nas.us-east-1.aliyuncs.com', + 'eu-central-1' => 'nas.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'nas.ap-south-1.aliyuncs.com', + 'ap-northeast-1' => 'nas.ap-northeast-1.aliyuncs.com', + 'us-west-1' => 'nas.us-west-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'nas.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'nas.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'nas.cn-north-2-gov-1.aliyuncs.com', + 'eu-west-1' => 'nas.eu-west-1.aliyuncs.com', + 'cn-chengdu' => 'nas.cn-chengdu.aliyuncs.com', + 'cn-heyuan' => 'nas.cn-heyuan.aliyuncs.com', + ], + 'hbase' => + [ + 'cn-qingdao' => 'hbase.aliyuncs.com', + 'cn-beijing' => 'hbase.aliyuncs.com', + 'cn-huhehaote' => 'hbase.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'hbase.aliyuncs.com', + 'cn-shanghai' => 'hbase.aliyuncs.com', + 'cn-shenzhen' => 'hbase.aliyuncs.com', + 'ap-southeast-1' => 'hbase.aliyuncs.com', + 'ap-southeast-2' => 'hbase.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'hbase.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'hbase.ap-southeast-5.aliyuncs.com', + 'us-west-1' => 'hbase.aliyuncs.com', + 'us-east-1' => 'hbase.aliyuncs.com', + 'eu-central-1' => 'hbase.eu-central-1.aliyuncs.com', + 'me-east-1' => 'hbase.me-east-1.aliyuncs.com', + 'ap-south-1' => 'hbase.ap-south-1.aliyuncs.com', + 'eu-west-1' => 'hbase.eu-west-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'hbase.aliyuncs.com', + 'cn-shanghai-finance-1' => 'hbase.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'hbase.aliyuncs.com', + 'cn-north-2-gov-1' => 'hbase.aliyuncs.com', + 'cn-zhangjiakou' => 'hbase.cn-zhangjiakou.aliyuncs.com', + 'cn-hongkong' => 'hbase.aliyuncs.com', + 'ap-northeast-1' => 'hbase.ap-northeast-1.aliyuncs.com', + ], + 'ddosbasic' => + [ + 'cn-qingdao' => 'antiddos.aliyuncs.com', + 'cn-beijing' => 'antiddos.aliyuncs.com', + 'cn-zhangjiakou' => 'antiddos-openapi.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'antiddos-openapi.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'antiddos.aliyuncs.com', + 'cn-shanghai' => 'antiddos.aliyuncs.com', + 'cn-shenzhen' => 'antiddos.aliyuncs.com', + 'cn-hongkong' => 'antiddos.aliyuncs.com', + 'ap-southeast-1' => 'antiddos.aliyuncs.com', + 'ap-southeast-2' => 'antiddos-openapi.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'antiddos-openapi.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'antiddos-openapi.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'antiddos-openapi.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'antiddos-openapi.eu-west-1.aliyuncs.com', + 'us-west-1' => 'antiddos.aliyuncs.com', + 'us-east-1' => 'antiddos.aliyuncs.com', + 'eu-central-1' => 'antiddos-openapi.eu-central-1.aliyuncs.com', + 'me-east-1' => 'antiddos-openapi.me-east-1.aliyuncs.com', + 'ap-south-1' => 'antiddos-openapi.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'antiddos-openapi.cn-chengdu.aliyuncs.com', + 'cn-shanghai-finance-1' => 'antiddos.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'antiddos.aliyuncs.com', + 'cn-north-2-gov-1' => 'antiddos.aliyuncs.com', + 'cn-fujian' => 'antiddos.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'antiddos.aliyuncs.com', + 'cn-heyuan' => 'antiddos-openapi.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'antiddos-openapi.cn-wulanchabu.aliyuncs.com', + ], + 'polardb' => + [ + 'cn-qingdao' => 'polardb.aliyuncs.com', + 'cn-beijing' => 'polardb.aliyuncs.com', + 'cn-huhehaote' => 'polardb.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'polardb.aliyuncs.com', + 'cn-shanghai' => 'polardb.aliyuncs.com', + 'cn-shenzhen' => 'polardb.aliyuncs.com', + 'cn-hongkong' => 'polardb.aliyuncs.com', + 'cn-zhangjiakou' => 'polardb.cn-zhangjiakou.aliyuncs.com', + 'ap-southeast-1' => 'polardb.aliyuncs.com', + 'ap-southeast-3' => 'polardb.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'polardb.ap-southeast-5.aliyuncs.com', + 'us-west-1' => 'polardb.aliyuncs.com', + 'cn-hangzhou-finance' => 'polardb.aliyuncs.com', + 'cn-shanghai-finance-1' => 'polardb.aliyuncs.com', + 'eu-central-1' => 'polardb.eu-central-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'polardb.aliyuncs.com', + 'ap-south-1' => 'polardb.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'polardb.cn-chengdu.aliyuncs.com', + 'ap-northeast-1' => 'polardb.ap-northeast-1.aliyuncs.com', + 'us-east-1' => 'polardb.aliyuncs.com', + ], + 'actiontrail' => + [ + 'cn-qingdao' => 'actiontrail.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'actiontrail.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'actiontrail.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'actiontrail.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'actiontrail.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'actiontrail.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'actiontrail.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'actiontrail.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'actiontrail.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'actiontrail.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'actiontrail.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'actiontrail.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'actiontrail.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'actiontrail.eu-west-1.aliyuncs.com', + 'us-west-1' => 'actiontrail.us-west-1.aliyuncs.com', + 'us-east-1' => 'actiontrail.us-east-1.aliyuncs.com', + 'eu-central-1' => 'actiontrail.eu-central-1.aliyuncs.com', + 'me-east-1' => 'actiontrail.me-east-1.aliyuncs.com', + 'ap-south-1' => 'actiontrail.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'actiontrail.cn-chengdu.aliyuncs.com', + 'cn-shanghai-finance-1' => 'actiontrail.cn-shanghai-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'actiontrail.cn-north-2-gov-1.aliyuncs.com', + 'cn-heyuan' => 'actiontrail.cn-heyuan.aliyuncs.com', + ], + 'codepipeline' => + [ + 'cn-beijing' => 'cds.cn-beijing.aliyuncs.com', + ], + 'hcs_sgw' => + [ + 'cn-beijing' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-zhangjiakou' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-shanghai' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-hongkong' => 'sgw.cn-shanghai.aliyuncs.com', + 'ap-southeast-1' => 'sgw.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'sgw.ap-southeast-2.aliyuncs.com', + 'eu-central-1' => 'sgw.eu-central-1.aliyuncs.com', + 'cn-qingdao' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-huhehaote' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-chengdu' => 'sgw.cn-shanghai.aliyuncs.com', + 'ap-southeast-5' => 'sgw.ap-southeast-5.aliyuncs.com', + 'ap-southeast-3' => 'sgw.ap-southeast-3.aliyuncs.com', + 'ap-northeast-1' => 'sgw.ap-northeast-1.aliyuncs.com', + 'us-west-1' => 'sgw.us-west-1.aliyuncs.com', + 'us-east-1' => 'sgw.us-west-1.aliyuncs.com', + 'cn-heyuan' => 'sgw.cn-shanghai.aliyuncs.com', + 'cn-north-2-gov-1' => 'sgw.cn-north-2-gov-1.aliyuncs.com', + ], + 'openanalytics' => + [ + 'cn-beijing' => 'openanalytics.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'openanalytics.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'openanalytics.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'openanalytics.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'openanalytics.cn-shenzhen.aliyuncs.com', + 'ap-southeast-1' => 'openanalytics.ap-southeast-1.aliyuncs.com', + 'ap-southeast-3' => 'openanalytics.ap-southeast-3.aliyuncs.com', + 'eu-west-1' => 'openanalytics.eu-west-1.aliyuncs.com', + 'cn-hongkong' => 'openanalytics.cn-hongkong.aliyuncs.com', + 'us-west-1' => 'openanalytics.us-west-1.aliyuncs.com', + 'ap-southeast-2' => 'datalakeanalytics.ap-southeast-2.aliyuncs.com', + 'ap-northeast-1' => 'datalakeanalytics.ap-northeast-1.aliyuncs.com', + 'us-east-1' => 'datalakeanalytics.us-east-1.aliyuncs.com', + 'eu-central-1' => 'datalakeanalytics.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'openanalytics.ap-south-1.aliyuncs.com', + 'ap-southeast-5' => 'openanalytics.ap-southeast-5.aliyuncs.com', + ], + 'clouddesktop' => + [ + 'cn-beijing' => 'clouddesktop.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'clouddesktop.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'clouddesktop.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'clouddesktop.cn-shenzhen.aliyuncs.com', + ], + 'ivision' => + [ + 'cn-beijing' => 'ivision.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'ivision.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ivision.cn-shanghai.aliyuncs.com', + ], + 'fc' => + [ + 'cn-beijing' => 'cn-beijing.fc.aliyuncs.com', + 'cn-hangzhou' => 'cn-hangzhou.fc.aliyuncs.com', + 'cn-shanghai' => 'cn-shanghai.fc.aliyuncs.com', + 'cn-shenzhen' => 'cn-shenzhen.fc.aliyuncs.com', + 'ap-southeast-2' => 'ap-southeast-2.fc.aliyuncs.com', + 'cn-huhehaote' => 'cn-huhehaote.fc.aliyuncs.com', + 'cn-qingdao' => 'cn-qingdao.fc.aliyuncs.com', + 'cn-chengdu' => 'cn-chengdu.fc.aliyuncs.com', + 'cn-zhangjiakou' => 'cn-zhangjiakou.fc.aliyuncs.com', + 'cn-hongkong' => 'cn-hongkong.fc.aliyuncs.com', + 'ap-southeast-1' => 'ap-southeast-1.fc.aliyuncs.com', + 'ap-southeast-3' => 'ap-southeast-3.fc.aliyuncs.com', + 'ap-southeast-5' => 'ap-southeast-5.fc.aliyuncs.com', + 'ap-northeast-1' => 'ap-northeast-1.fc.aliyuncs. com', + 'eu-west-1' => 'eu-west-1.fc.aliyuncs.com', + 'us-west-1' => 'us-west-1.fc.aliyuncs.com', + 'us-east-1' => 'us-east-1.fc.aliyuncs.com', + 'eu-central-1' => 'eu-central-1.fc.aliyuncs.com', + 'ap-south-1' => 'ap-south-1.fc.aliyuncs.com', + 'cn-hangzhou-finance' => 'cn-hangzhou-finance.fc.aliyuncs.com', + ], + 'hsm' => + [ + 'cn-beijing' => 'hsm.aliyuncs.com', + 'cn-hangzhou' => 'hsm.aliyuncs.com', + 'cn-shanghai' => 'hsm.aliyuncs.com', + 'cn-shenzhen' => 'hsm.aliyuncs.com', + 'cn-hongkong' => 'hsm.aliyuncs.com', + 'ap-southeast-1' => 'hsm.aliyuncs.com', + 'cn-shanghai-finance-1' => 'hsm.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'hsm.aliyuncs.com', + 'cn-hangzhou-finance' => 'hsm.aliyuncs.com', + 'cn-north-2-gov-1' => 'hsm.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'hsm.aliyuncs.com', + 'cn-heyuan' => 'hsm.aliyuncs.com', + 'ap-southeast-3' => 'hsm.aliyuncs.com', + ], + 'petadata' => + [ + 'cn-beijing' => 'petadata.aliyuncs.com', + 'cn-zhangjiakou' => 'petadata.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'petadata.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'petadata.aliyuncs.com', + 'cn-shanghai' => 'petadata.aliyuncs.com', + 'cn-shenzhen' => 'petadata.aliyuncs.com', + 'ap-southeast-1' => 'petadata.aliyuncs.com', + 'ap-southeast-2' => 'petadata.ap-southeast-2.aliyuncs.com', + 'ap-southeast-5' => 'petadata.ap-southeast-5.aliyuncs.com', + 'us-west-1' => 'petadata.aliyuncs.com', + 'us-east-1' => 'petadata.aliyuncs.com', + 'eu-central-1' => 'petadata.eu-central-1.aliyuncs.com', + 'me-east-1' => 'petadata.me-east-1.aliyuncs.com', + 'cn-hongkong' => 'petadata.aliyuncs.com', + 'cn-qingdao' => 'petadata.aliyuncs.com', + 'cn-shanghai-et2-b01' => 'petadata.aliyuncs.com', + 'cn-zhangjiakou-na62-a01' => 'petadata.aliyuncs.com', + ], + 'gpdb' => + [ + 'cn-beijing' => 'gpdb.aliyuncs.com', + 'cn-zhangjiakou' => 'gpdb.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'gpdb.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'gpdb.aliyuncs.com', + 'cn-shanghai' => 'gpdb.aliyuncs.com', + 'cn-shenzhen' => 'gpdb.aliyuncs.com', + 'ap-southeast-1' => 'gpdb.aliyuncs.com', + 'ap-southeast-2' => 'gpdb.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'gpdb.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'gpdb.ap-southeast-5.aliyuncs.com', + 'eu-west-1' => 'gpdb.eu-west-1.aliyuncs.com', + 'us-west-1' => 'gpdb.aliyuncs.com', + 'us-east-1' => 'gpdb.aliyuncs.com', + 'eu-central-1' => 'gpdb.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'gpdb.ap-south-1.aliyuncs.com', + 'ap-northeast-1' => 'gpdb.ap-northeast-1.aliyuncs.com', + 'cn-hongkong' => 'gpdb.aliyuncs.com', + 'cn-chengdu' => 'gpdb.cn-chengdu.aliyuncs.com', + 'cn-hangzhou-finance' => 'gpdb.aliyuncs.com', + 'cn-shanghai-finance-1' => 'gpdb.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'gpdb.aliyuncs.com', + ], + 'eci' => + [ + 'cn-beijing' => 'eci.aliyuncs.com', + 'cn-hangzhou' => 'eci.aliyuncs.com', + 'cn-shanghai' => 'eci.aliyuncs.com', + 'cn-shenzhen' => 'eci.aliyuncs.com', + 'ap-southeast-1' => 'eci.aliyuncs.com', + 'us-west-1' => 'eci.aliyuncs.com', + 'cn-hongkong' => 'eci.aliyuncs.com', + 'cn-zhangjiakou' => 'eci.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'eci.cn-huhehaote.aliyuncs.com', + 'ap-southeast-2' => 'eci.ap-southeast-2.aliyuncs.com', + 'eu-west-1' => 'eci.eu-west-1.aliyuncs.com', + 'us-east-1' => 'eci.aliyuncs.com', + 'eu-central-1' => 'eci.eu-central-1.aliyuncs.com', + 'cn-chengdu' => 'eci.cn-chengdu.aliyuncs.com', + 'ap-southeast-5' => 'eci.ap-southeast-5.aliyuncs.com', + 'ap-south-1' => 'eci.ap-south-1.aliyuncs.com', + 'cn-hangzhou-internal-test-1' => 'eci.aliyuncs.com', + 'cn-hangzhou-internal-test-2' => 'eci.aliyuncs.com', + 'cn-qingdao' => 'eci.aliyuncs.com', + 'cn-heyuan' => 'eci.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'eci.cn-wulanchabu.aliyuncs.com', + 'ap-southeast-3' => 'eci.ap-southeast-3.aliyuncs.com', + 'ap-northeast-1' => 'eci.ap-northeast-1.aliyuncs.com', + ], + 'airec' => + [ + 'cn-beijing' => 'airec.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'airec.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'airec.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'airec.cn-shenzhen.aliyuncs.com', + ], + 'imm' => + [ + 'cn-beijing' => 'imm.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'imm.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'imm.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'imm.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'imm.cn-shenzhen.aliyuncs.com', + 'ap-southeast-1' => 'imm.ap-southeast-1.aliyuncs.com', + ], + 'gameshield' => + [ + 'cn-zhangjiakou' => 'gameshield.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'gameshield.aliyuncs.com', + ], + 'ims' => + [ + 'cn-hangzhou' => 'ims.aliyuncs.com', + ], + 'cloudfirewall' => + [ + 'cn-hangzhou' => 'cloudfw.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'cloudfw.ap-southeast-1.aliyuncs.com', + ], + 'ens' => + [ + 'cn-hangzhou' => 'ens.aliyuncs.com', + 'ap-southeast-1' => 'ens.ap-southeast-1.aliyuncs.com', + 'cn-beijing' => 'ens.aliyuncs.com', + 'cn-chengdu' => 'ens.aliyuncs.com', + 'cn-zhangjiakou' => 'ens.aliyuncs.com', + 'cn-shanghai' => 'ens.aliyuncs.com', + 'cn-heyuan' => 'ens.aliyuncs.com', + 'cn-wulanchabu' => 'ens.aliyuncs.com', + ], + 'hitsdb' => + [ + 'cn-hangzhou' => 'hitsdb.aliyuncs.com', + 'cn-qingdao' => 'hitsdb.aliyuncs.com', + 'cn-beijing' => 'hitsdb.aliyuncs.com', + 'cn-zhangjiakou' => 'hitsdb.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'hitsdb.cn-huhehaote.aliyuncs.com', + 'cn-shanghai' => 'hitsdb.aliyuncs.com', + 'cn-shenzhen' => 'hitsdb.aliyuncs.com', + 'cn-hongkong' => 'hitsdb.aliyuncs.com', + 'ap-southeast-5' => 'hitsdb.ap-southeast-5.aliyuncs.com', + 'us-west-1' => 'hitsdb.aliyuncs.com', + 'us-east-1' => 'hitsdb.aliyuncs.com', + 'ap-southeast-1' => 'hitsdb.aliyuncs.com', + 'ap-southeast-2' => 'hitsdb.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'hitsdb.ap-southeast-3.aliyuncs.com', + 'ap-northeast-1' => 'hitsdb.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'hitsdb.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'hitsdb.eu-central-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'hitsdb.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'hitsdb.aliyuncs.com', + ], + 'ddos' => + [ + 'cn-hangzhou' => 'ddospro.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'ddospro.cn-hongkong.aliyuncs.com', + ], + 'rtc' => + [ + 'cn-hangzhou' => 'rtc.aliyuncs.com', + ], + 'emas' => + [ + 'cn-hangzhou' => 'mhub.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'mhub.cn-shanghai.aliyuncs.com', + ], + 'vipaegis' => + [ + 'cn-hangzhou' => 'aegis.cn-hangzhou.aliyuncs.com', + 'ap-southeast-3' => 'aegis.ap-southeast-3.aliyuncs.com', + ], + 'ddosrewards' => + [ + 'cn-hangzhou' => 'ddosright.cn-hangzhou.aliyuncs.com', + ], + 'cloudap' => + [ + 'cn-hangzhou' => 'cloudwf.aliyuncs.com', + ], + 'ensdisk' => + [ + 'cn-hangzhou' => 'ens.aliyuncs.com', + ], + 'bastionhost' => + [ + 'cn-hangzhou' => 'yundun-bastionhost.aliyuncs.com', + 'cn-qingdao' => 'yundun-bastionhost.aliyuncs.com', + 'cn-beijing' => 'yundun-bastionhost.aliyuncs.com', + 'cn-chengdu' => 'yundun-bastionhost.aliyuncs.com', + 'cn-zhangjiakou' => 'yundun-bastionhost.aliyuncs.com', + 'cn-huhehaote' => 'yundun-bastionhost.aliyuncs.com', + 'cn-shanghai' => 'yundun-bastionhost.aliyuncs.com', + 'cn-shenzhen' => 'yundun-bastionhost.aliyuncs.com', + 'cn-hongkong' => 'bastionhost.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'bastionhost.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'bastionhost.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'bastionhost.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'bastionhost.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'bastionhost.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'bastionhost.eu-west-1.aliyuncs.com', + 'us-west-1' => 'bastionhost.us-west-1.aliyuncs.com', + 'us-east-1' => 'bastionhost.us-east-1.aliyuncs.com', + 'eu-central-1' => 'bastionhost.eu-central-1.aliyuncs.com', + 'me-east-1' => 'yundun-bastionhost.aliyuncs.com', + 'ap-south-1' => 'bastionhost.ap-south-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'yundun-bastionhost.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'yundun-bastionhost.aliyuncs.com', + 'cn-north-2-gov-1' => 'yundun-bastionhost.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'yundun-bastionhost.aliyuncs.com', + 'cn-heyuan' => 'yundun-bastionhost.aliyuncs.com', + ], + 'pvtz' => + [ + 'cn-hangzhou' => 'pvtz.aliyuncs.com', + ], + 'ccs' => + [ + 'cn-hangzhou' => 'ccs.aliyuncs.com', + ], + 'yunmarket' => + [ + 'cn-hangzhou' => 'market.aliyuncs.com', + ], + 'cas' => + [ + 'cn-hangzhou' => 'cas.aliyuncs.com', + 'ap-southeast-2' => 'cas.ap-southeast-2.aliyuncs.com', + 'ap-northeast-1' => 'cas.ap-northeast-1.aliyuncs.com', + 'eu-central-1' => 'cas.eu-central-1.aliyuncs.com', + 'me-east-1' => 'cas.me-east-1.aliyuncs.com', + 'ap-south-1' => 'cas.ap-south-1.aliyuncs.com', + ], + 'ddoscoo' => + [ + 'cn-hangzhou' => 'ddoscoo.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'ddoscoo.ap-southeast-1.aliyuncs.com', + ], + 'waf' => + [ + 'cn-hangzhou' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'cn-qingdao' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-chengdu' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-zhangjiakou' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-huhehaote' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-heyuan' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-wulanchabu' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'ap-southeast-3' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'ap-southeast-5' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'eu-west-1' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'us-west-1' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'us-east-1' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'eu-central-1' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'me-east-1' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'ap-south-1' => 'wafopenapi.ap-southeast-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + 'cn-north-2-gov-1' => 'wafopenapi.cn-hangzhou.aliyuncs.com', + ], + 'xianzhi' => + [ + 'cn-hangzhou' => 'xianzhi.aliyuncs.com', + ], + 'sas' => + [ + 'cn-hangzhou' => 'tds.aliyuncs.com', + 'ap-southeast-3' => 'tds.ap-southeast-3.aliyuncs.com', + ], + 'cloudauth' => + [ + 'cn-hangzhou' => 'cloudauth.aliyuncs.com', + ], + 'dmsenterprise' => + [ + 'cn-hangzhou' => 'dms-enterprise.aliyuncs.com', + 'cn-shanghai' => 'dms-enterprise.aliyuncs.com', + 'cn-shenzhen' => 'dms-enterprise.aliyuncs.com', + 'cn-beijing' => 'dms-enterprise.aliyuncs.com', + 'cn-qingdao' => 'dms-enterprise.aliyuncs.com', + 'ap-northeast-1' => 'dms-enterprise.aliyuncs.com', + 'ap-southeast-1' => 'dms-enterprise.aliyuncs.com', + ], + 'baas' => + [ + 'cn-hangzhou' => 'baas.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'baas.ap-southeast-1.aliyuncs.com', + 'ap-northeast-1' => 'baas.ap-southeast-1.aliyuncs.com', + 'cn-beijing' => 'baas.aliyuncs.com', + 'cn-shanghai' => 'baas.aliyuncs.com', + 'cn-shenzhen' => 'baas.aliyuncs.com', + 'cn-hongkong' => 'baas.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'baas.ap-southeast-1.aliyuncs.com', + 'us-east-1' => 'baas.ap-southeast-1.aliyuncs.com', + 'eu-central-1' => 'baas.ap-southeast-1.aliyuncs.com', + 'cn-qingdao' => 'baas.aliyuncs.com', + 'cn-zhangjiakou' => 'baas.aliyuncs.com', + 'cn-huhehaote' => 'baas.aliyuncs.com', + 'eu-west-1' => 'baas.ap-southeast-1.aliyuncs.com', + 'us-west-1' => 'baas.ap-southeast-1.aliyuncs.com', + 'ap-south-1' => 'baas.ap-southeast-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'baas.cn-north-2-gov-1.aliyuncs.com', + ], + 'alimt' => + [ + 'cn-hangzhou' => 'mt.cn-hangzhou.aliyuncs.com', + ], + 'dcdn' => + [ + 'cn-hangzhou' => 'dcdn.aliyuncs.com', + ], + 'hcs_mgw' => + [ + 'cn-hangzhou' => 'mgw.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'mgw.cn-shanghai.aliyuncs.com', + 'ap-southeast-1' => 'mgw.ap-southeast-1.aliyuncs.com', + ], + 'linkedmall' => + [ + 'cn-hangzhou' => 'linkedmall.aliyuncs.com', + 'cn-shanghai' => 'linkedmall.aliyuncs.com', + ], + 'cps' => + [ + 'cn-hangzhou' => 'cloudpush.aliyuncs.com', + ], + 'scdn' => + [ + 'cn-hangzhou' => 'scdn.aliyuncs.com', + ], + 'trademark' => + [ + 'cn-hangzhou' => 'trademark.aliyuncs.com', + ], + 'elasticsearch' => + [ + 'cn-hangzhou' => 'elasticsearch.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'elasticsearch.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'elasticsearch.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'elasticsearch.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'elasticsearch.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'elasticsearch.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'elasticsearch.ap-southeast-3.aliyuncs.com', + 'ap-northeast-1' => 'elasticsearch.ap-northeast-1.aliyuncs.com', + 'us-west-1' => 'elasticsearch.us-west-1.aliyuncs.com', + 'eu-central-1' => 'elasticsearch.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'elasticsearch.ap-south-1.aliyuncs.com', + 'cn-qingdao' => 'elasticsearch.cn-qingdao.aliyuncs.com', + 'ap-southeast-5' => 'elasticsearch.ap-southeast-5.aliyuncs.com', + 'cn-beijing' => 'elasticsearch.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'elasticsearch.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou-finance' => 'elasticsearch.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'elasticsearch.cn-shanghai-finance-1.aliyuncs.com', + 'us-east-1' => 'elasticsearch.us-east-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'elasticsearch.cn-north-2-gov-1.aliyuncs.com', + 'eu-west-1' => 'elasticsearch.eu-west-1.aliyuncs.com', + ], + 'luban' => + [ + 'cn-hangzhou' => 'luban.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'luban.cn-shanghai.aliyuncs.com', + ], + 'pcdn' => + [ + 'cn-hangzhou' => 'pcdn.aliyuncs.com', + ], + 'uis' => + [ + 'cn-hangzhou' => 'uis.cn-hangzhou.aliyuncs.com', + 'cn-north-2-gov-1' => 'uis.cn-hangzhou.aliyuncs.com', + ], + 'beebot' => + [ + 'cn-hangzhou' => 'chatbot.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'chatbot.cn-shanghai.aliyuncs.com', + 'cn-north-2-gov-1' => 'chatbot.cn-north-2-gov-1.aliyuncs.com', + ], + 'chatbot' => + [ + 'global' => 'chatbot.cn-shanghai.aliyuncs.com', + 'cn-shanghai' => 'chatbot.cn-shanghai.aliyuncs.com', + ], + 'alidnsgtm' => + [ + 'cn-hangzhou' => 'alidns.aliyuncs.com', + ], + 'sca' => + [ + 'cn-hangzhou' => 'qualitycheck.cn-hangzhou.aliyuncs.com', + ], + 'cccvn' => + [ + 'cn-shanghai' => 'voicenavigator.cn-shanghai.aliyuncs.com', + ], + 'cloudphoto' => + [ + 'cn-shanghai' => 'cloudphoto.cn-shanghai.aliyuncs.com', + ], + 'smartag' => + [ + 'cn-shanghai' => 'smartag.cn-shanghai.aliyuncs.com', + 'cn-hongkong' => 'smartag.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'smartag.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'smartag.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'smartag.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'smartag.ap-southeast-5.aliyuncs.com', + 'eu-central-1' => 'smartag.eu-central-1.aliyuncs.com', + 'ap-northeast-1' => 'smartag.ap-northeast-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'smartag.cn-shanghai-finance-1.aliyuncs.com', + 'cn-hangzhou-internal-test-1' => 'smartag.aliyuncs.com', + 'cn-hangzhou-internal-test-2' => 'smartag.aliyuncs.com', + 'eu-west-1' => 'smartag.eu-west-1.aliyuncs.com', + 'us-east-1' => 'smartag.us-east-1.aliyuncs.com', + ], + 'nlp' => + [ + 'cn-shanghai' => 'nlp.cn-shanghai.aliyuncs.com', + ], + 'nls-cloud-meta' => + [ + 'cn-shanghai' => 'nls-meta.cn-shanghai.aliyuncs.com', + ], + 'nls-filetrans' => + [ + 'cn-shanghai' => 'filetrans.cn-shanghai.aliyuncs.com', + ], + 'linkwan' => + [ + 'cn-shanghai' => 'linkwan.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'linkwan.cn-hangzhou.aliyuncs.com', + ], + 'hdm' => + [ + 'cn-shanghai' => 'hdm-api.aliyuncs.com', + ], + 'iovcc' => + [ + 'cn-shanghai' => 'iovcc.cn-shanghai.aliyuncs.com', + ], + 'ddosdip' => + [ + 'ap-southeast-1' => 'ddosdip.ap-southeast-1.aliyuncs.com', + ], + 'imagesearch' => + [ + 'ap-southeast-1' => 'imagesearch.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'imagesearch.ap-southeast-2.aliyuncs.com', + 'ap-northeast-1' => 'imagesearch.ap-northeast-1.aliyuncs.com', + 'cn-shanghai' => 'imagesearch.cn-shanghai.aliyuncs.com', + ], + 'alidfs' => + [ + 'cn-beijing' => 'dfs.cn-beijing.aliyuncs.com', + 'cn-shanghai' => 'dfs.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'dfs.cn-hangzhou.aliyuncs.com', + 'cn-zhangjiakou' => 'dfs.cn-zhangjiakou.aliyuncs.com', + ], + 'vs' => + [ + 'cn-hangzhou' => 'vs.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'vs.cn-shanghai.aliyuncs.com', + 'cn-qingdao' => 'vs.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'vs.cn-beijing.aliyuncs.com', + 'cn-shenzhen' => 'vs.cn-shenzhen.aliyuncs.com', + ], + 'foas' => + [ + 'cn-qingdao' => 'foas.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'foas.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'foas.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'foas.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'foas.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'foas.cn-shenzhen.aliyuncs.com', + 'ap-northeast-1' => 'foas.ap-northeast-1.aliyuncs.com', + 'ap-southeast-1' => 'foas.ap-southeast-1.aliyuncs.com', + 'ap-southeast-3' => 'foas.ap-southeast-3.aliyuncs.com', + 'cn-hangzhou-finance' => 'foas.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'foas.cn-shanghai-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'foas.cn-north-2-gov-1.aliyuncs.com', + 'cn-hongkong' => 'foas.cn-hongkong.aliyuncs.com', + 'eu-central-1' => 'foas.eu-central-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'foas.cn-shenzhen-finance-1.aliyuncs.com', + ], + 'iotid' => + [ + 'cn-hangzhou' => 'iotid.cn-hangzhou.aliyuncs.com', + ], + 'drdspost' => + [ + 'ap-southeast-1' => 'drds.ap-southeast-1.aliyuncs.com', + 'cn-shanghai' => 'drds.cn-shanghai.aliyuncs.com', + 'cn-hongkong' => 'drds.cn-hangzhou.aliyuncs.com', + 'cn-huhehaote' => 'drds.cn-huhehaote.aliyuncs.com', + 'us-east-1' => 'drds.us-east-1.aliyuncs.com', + ], + 'drdspre' => + [ + 'cn-qingdao' => 'drds.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'drds.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'drds.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'drds.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'drds.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'drds.cn-hangzhou.aliyuncs.com', + 'cn-huhehaote' => 'drds.cn-huhehaote.aliyuncs.com', + 'us-east-1' => 'drds.us-east-1.aliyuncs.com', + ], + 'acr' => + [ + 'cn-qingdao' => 'cr.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'cr.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'cr.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'cr.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'cr.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'cr.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'cr.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'cr.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'cr.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'cr.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'cr.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'cr.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'cr.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'cr.eu-west-1.aliyuncs.com', + 'us-west-1' => 'cr.us-west-1.aliyuncs.com', + 'us-east-1' => 'cr.us-east-1.aliyuncs.com', + 'eu-central-1' => 'cr.eu-central-1.aliyuncs.com', + 'me-east-1' => 'cr.me-east-1.aliyuncs.com', + 'ap-south-1' => 'cr.ap-south-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'cr.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'cr.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'cr.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'cr.cn-north-2-gov-1.aliyuncs.com', + 'cn-chengdu' => 'cr.cn-chengdu.aliyuncs.com', + ], + 'faas' => + [ + 'cn-beijing' => 'faas.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'faas.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'faas.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'faas.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'faas.cn-shenzhen.aliyuncs.com', + 'ap-southeast-5' => 'faas.ap-southeast-5.aliyuncs.com', + 'cn-shanghai-finance-1' => 'faas.cn-shanghai-finance-1.aliyuncs.com', + 'cn-chengdu' => 'faas.cn-chengdu.aliyuncs.com', + 'cn-heyuan' => 'faas.cn-heyuan.aliyuncs.com', + 'us-west-1' => 'faas.us-west-1.aliyuncs.com', + ], + 'idaas' => + [ + 'cn-hangzhou' => 'idaas.aliyuncs.com', + 'cn-qingdao' => 'idaas.aliyuncs.com', + 'cn-beijing' => 'idaas.aliyuncs.com', + 'cn-chengdu' => 'idaas.aliyuncs.com', + 'cn-zhangjiakou' => 'idaas.aliyuncs.com', + 'cn-huhehaote' => 'idaas.aliyuncs.com', + 'cn-shanghai' => 'idaas.aliyuncs.com', + 'cn-shenzhen' => 'idaas.aliyuncs.com', + 'cn-hongkong' => 'idaas.aliyuncs.com', + 'cn-shanghai-finance-1' => 'idaas.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'idaas.aliyuncs.com', + 'ap-southeast-1' => 'idaas.ap-southeast-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'idaas.aliyuncs.com', + ], + 'privatelink' => + [ + 'cn-hangzhou' => 'privatelink-center.cn-hangzhou.aliyuncs.com', + 'cn-huhehaote' => 'privatelink.cn-huhehaote.aliyuncs.com', + 'eu-west-1' => 'privatelink.eu-west-1.aliyuncs.com', + 'ap-southeast-2' => 'privatelink.ap-southeast-2.aliyuncs.com', + 'ap-southeast-5' => 'privatelink.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'privatelink.ap-northeast-1.aliyuncs.com', + 'ap-south-1' => 'privatelink.ap-south-1.aliyuncs.com', + 'cn-shenzhen' => 'privatelink.cn-shenzhen.aliyuncs.com', + 'eu-central-1' => 'privatelink.eu-central-1.aliyuncs.com', + 'cn-zhangjiakou' => 'privatelink.cn-zhangjiakou.aliyuncs.com', + 'ap-southeast-3' => 'privatelink.ap-southeast-3.aliyuncs.com', + 'cn-hangzhou-internal-test-1' => 'privatelink.aliyuncs.com', + 'cn-hangzhou-test-306' => 'privatelink-center.cn-hangzhou.aliyuncs.com', + 'cn-chengdu' => 'privatelink.cn-chengdu.aliyuncs.com', + 'ap-southeast-1' => 'privatelink.ap-southeast-1.aliyuncs.com', + ], + 'batchcomputenew' => + [ + 'cn-hongkong' => 'batchcompute.cn-hongkong.aliyuncs.com', + ], + 'vcs' => + [ + 'cn-hangzhou' => 'vcs.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'vcs.cn-shanghai.aliyuncs.com', + ], + 'vds' => + [ + 'cn-hangzhou' => 'vds.aliyuncs.com', + 'cn-shanghai' => 'vds.cn-shanghai.aliyuncs.com', + ], + 'vcsbasic' => + [ + 'cn-hangzhou' => 'vcs.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'vcs.cn-hangzhou.aliyuncs.com', + ], + 'hbr' => + [ + 'cn-qingdao' => 'hbr.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'hbr.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'hbr.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'hbr.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'hbr.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'hbr.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'hbr.cn-shenzhen.aliyuncs.com', + 'ap-southeast-1' => 'hbr.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'hbr.ap-southeast-2.aliyuncs.com', + 'cn-hongkong' => 'hbr.cn-hongkong.aliyuncs.com', + 'ap-southeast-5' => 'hbr.ap-southeast-5.aliyuncs.com', + 'ap-southeast-3' => 'hbr.ap-southeast-3.aliyuncs.com', + 'us-west-1' => 'hbr.us-west-1.aliyuncs.com', + 'eu-central-1' => 'hbr.eu-central-1.aliyuncs.com', + 'ap-northeast-1' => 'hbr.ap-northeast-1.aliyuncs.com', + 'cn-chengdu' => 'hbr.cn-chengdu.aliyuncs.com', + 'us-east-1' => 'hbr.us-east-1.aliyuncs.com', + 'ap-south-1' => 'hbr.ap-south-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'hbr.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'hbr.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'hbr.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'hbr.cn-north-2-gov-1.aliyuncs.com', + ], + 'image' => + [ + 'cn-shanghai' => 'image.cn-shanghai.aliyuncs.com', + ], + 'webx' => + [ + 'cn-shenzhen' => 'webplus.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'webplus.cn-hangzhou.aliyuncs.com', + 'cn-zhangjiakou' => 'webplus.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'webplus.cn-hangzhou.aliyuncs.com', + 'cn-hangzhou' => 'webplus.cn-hangzhou.aliyuncs.com', + ], + 'sddp' => + [ + 'cn-zhangjiakou' => 'sddp.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'sddp.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'sddp.ap-southeast-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'sddp.cn-north-2-gov-1.aliyuncs.com', + ], + 'oos' => + [ + 'cn-hangzhou' => 'oos.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'oos.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'oos.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'oos.cn-hongkong.aliyuncs.com', + 'us-east-1' => 'oos.us-east-1.aliyuncs.com', + 'cn-beijing' => 'oos.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'oos.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'oos.cn-huhehaote.aliyuncs.com', + 'eu-west-1' => 'oos.eu-west-1.aliyuncs.com', + 'eu-central-1' => 'oos.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'oos.ap-south-1.aliyuncs.com', + 'cn-chengdu' => 'oos.cn-chengdu.aliyuncs.com', + 'ap-southeast-1' => 'oos.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'oos.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'oos.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'oos.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'oos.ap-northeast-1.aliyuncs.com', + ], + 'fnf' => + [ + 'cn-hangzhou' => 'cn-hangzhou.fnf.aliyuncs.com', + 'cn-shanghai' => 'cn-shanghai.fnf.aliyuncs.com', + 'cn-shenzhen' => 'cn-shenzhen.fnf.aliyuncs.com', + 'cn-beijing' => 'cn-beijing.fnf.aliyuncs.com', + ], + 'smc' => + [ + 'cn-huhehaote' => 'smc.aliyuncs.com', + 'cn-hangzhou' => 'smc.aliyuncs.com', + 'cn-qingdao' => 'smc.aliyuncs.com', + 'cn-beijing' => 'smc.aliyuncs.com', + 'cn-zhangjiakou' => 'smc.aliyuncs.com', + 'cn-shanghai' => 'smc.aliyuncs.com', + 'cn-shenzhen' => 'smc.aliyuncs.com', + 'cn-hongkong' => 'smc.aliyuncs.com', + 'ap-southeast-1' => 'smc.aliyuncs.com', + 'ap-southeast-2' => 'smc.aliyuncs.com', + 'ap-southeast-3' => 'smc.aliyuncs.com', + 'ap-southeast-5' => 'smc.aliyuncs.com', + 'ap-northeast-1' => 'smc.aliyuncs.com', + 'eu-west-1' => 'smc.aliyuncs.com', + 'us-west-1' => 'smc.aliyuncs.com', + 'us-east-1' => 'smc.aliyuncs.com', + 'eu-central-1' => 'smc.aliyuncs.com', + 'me-east-1' => 'smc.aliyuncs.com', + 'ap-south-1' => 'smc.aliyuncs.com', + 'cn-chengdu' => 'smc.aliyuncs.com', + ], + 'foasconsole' => + [ + 'cn-beijing' => 'foasconsole.aliyuncs.com', + 'cn-zhangjiakou' => 'foasconsole.aliyuncs.com', + 'cn-hangzhou' => 'foasconsole.aliyuncs.com', + 'cn-shanghai' => 'foasconsole.aliyuncs.com', + 'cn-shenzhen' => 'foasconsole.aliyuncs.com', + 'cn-hongkong' => 'foasconsole.aliyuncs.com', + 'ap-southeast-1' => 'foasconsole.aliyuncs.com', + 'ap-southeast-3' => 'foasconsole.aliyuncs.com', + 'ap-northeast-1' => 'foasconsole.aliyuncs.com', + 'cn-hangzhou-finance' => 'foasconsole.aliyuncs.com', + 'cn-shanghai-finance-1' => 'foasconsole.aliyuncs.com', + 'cn-north-2-gov-1' => 'foasconsole.aliyuncs.com', + 'eu-central-1' => 'foasconsole.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'foasconsole.aliyuncs.com', + ], + 'serverless' => + [ + 'cn-beijing' => 'sae.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'sae.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'sae.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'sae.cn-shenzhen.aliyuncs.com', + 'us-west-1' => 'sae.us-west-1.aliyuncs.com', + ], + 'ivpd' => + [ + 'cn-huhehaote' => 'ivpd.cn-huhehaote.aliyuncs.com', + 'cn-shanghai' => 'ivpd.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'ivpd.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'ivpd.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'ivpd.cn-zhangjiakou.aliyuncs.com', + 'cn-hongkong' => 'ivpd.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'ivpd.ap-southeast-1.aliyuncs.com', + ], + 'hivisengine' => + [ + 'cn-huhehaote' => 'hivisengine.aliyuncs.com', + 'cn-shanghai' => 'hivisengine.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'hivisengine.cn-hangzhou.aliyuncs.com', + ], + 'hiknoengine' => + [ + 'cn-huhehaote' => 'hiknoengine.aliyuncs.com', + 'cn-shanghai' => 'hiknoengine.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'hiknoengine.cn-hangzhou.aliyuncs.com', + ], + 'clouddev' => + [ + 'cn-hangzhou' => 'mpserverless.aliyuncs.com', + 'cn-shanghai' => 'mpserverless.aliyuncs.com', + ], + 'premiumpics' => + [ + 'cn-hangzhou' => 'premiumpics.aliyuncs.com', + ], + 'composer' => + [ + 'cn-hangzhou' => 'composer.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'composer.cn-shanghai.aliyuncs.com', + 'us-east-1' => 'composer.us-east-1.aliyuncs.com', + 'ap-southeast-1' => 'composer.ap-southeast-1.aliyuncs.com', + ], + 'cloudesl' => + [ + 'cn-hangzhou' => 'cloudesl.cn-hangzhou.aliyuncs.com', + ], + 'amscloudapp' => + [ + 'cn-hangzhou' => 'mpca.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'mpca.cn-shanghai.aliyuncs.com', + ], + 'mse' => + [ + 'cn-hangzhou' => 'mse.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'mse.cn-shanghai.aliyuncs.com', + 'cn-beijing' => 'mse.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'mse.cn-zhangjiakou.aliyuncs.com', + 'cn-shenzhen' => 'mse.cn-shenzhen.aliyuncs.com', + 'us-east-1' => 'mse.us-east-1.aliyuncs.com', + 'ap-southeast-1' => 'mse.ap-southeast-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'msefinance-share.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'msefinance-share.cn-shenzhen-finance-1.aliyuncs.com', + ], + 'dg' => + [ + 'cn-hangzhou' => 'dg.cn-hangzhou.aliyuncs.com', + ], + 'graphcompute' => + [ + 'cn-shanghai' => 'gcs.cn-shanghai.aliyuncs.com', + ], + 'cds' => + [ + 'ap-southeast-1' => 'cassandra.aliyuncs.com', + 'cn-qingdao' => 'cassandra.aliyuncs.com', + 'cn-beijing' => 'cassandra.aliyuncs.com', + 'cn-hangzhou' => 'cassandra.aliyuncs.com', + 'cn-shanghai' => 'cassandra.aliyuncs.com', + 'cn-shenzhen' => 'cassandra.aliyuncs.com', + 'cn-hongkong' => 'cassandra.aliyuncs.com', + 'cn-chengdu' => 'cassandra.aliyuncs.com', + 'cn-zhangjiakou' => 'cassandra.aliyuncs.com', + 'cn-huhehaote' => 'cassandra.aliyuncs.com', + 'ap-southeast-2' => 'cassandra.aliyuncs.com', + 'ap-southeast-3' => 'cassandra.aliyuncs.com', + 'ap-southeast-5' => 'cassandra.aliyuncs.com', + 'eu-west-1' => 'cassandra.aliyuncs.com', + 'us-west-1' => 'cassandra.aliyuncs.com', + 'us-east-1' => 'cassandra.aliyuncs.com', + 'eu-central-1' => 'cassandra.aliyuncs.com', + 'me-east-1' => 'cassandra.aliyuncs.com', + 'ap-south-1' => 'cassandra.aliyuncs.com', + 'ap-northeast-1' => 'cassandra.aliyuncs.com', + ], + 'ads' => + [ + 'cn-qingdao' => 'adb.aliyuncs.com', + 'cn-beijing' => 'adb.aliyuncs.com', + 'cn-zhangjiakou' => 'adb.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'adb.aliyuncs.com', + 'cn-shanghai' => 'adb.aliyuncs.com', + 'cn-shenzhen' => 'adb.aliyuncs.com', + 'cn-hongkong' => 'adb.aliyuncs.com', + 'ap-southeast-1' => 'adb.aliyuncs.com', + 'ap-northeast-1' => 'adb.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'adb.eu-west-1.aliyuncs.com', + 'us-west-1' => 'adb.aliyuncs.com', + 'us-east-1' => 'adb.aliyuncs.com', + 'ap-southeast-2' => 'adb.ap-southeast-2.aliyuncs.com', + 'eu-central-1' => 'adb.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'adb.ap-south-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'adb.aliyuncs.com', + 'cn-chengdu' => 'adb.cn-chengdu.aliyuncs.com', + 'cn-huhehaote' => 'adb.cn-huhehaote.aliyuncs.com', + 'ap-southeast-3' => 'adb.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'adb.ap-southeast-5.aliyuncs.com', + 'cn-hangzhou-finance' => 'adb.aliyuncs.com', + 'cn-shanghai-finance-1' => 'adb.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'adb.aliyuncs.com', + ], + 'csb' => + [ + 'cn-beijing' => 'csb.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'csb.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'csb.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'csb.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'csb.cn-hongkong.aliyuncs.com', + 'cn-north-2-gov-1' => 'csb.cn-north-2-gov-1.aliyuncs.com', + ], + 'cityvisual' => + [ + 'cn-hangzhou' => 'cityvisual.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'cityvisual.cn-shanghai.aliyuncs.com', + ], + 'dbaudit' => + [ + 'cn-hangzhou' => 'yundun-dbaudit.aliyuncs.com', + 'cn-qingdao' => 'yundun-dbaudit.aliyuncs.com', + 'cn-beijing' => 'yundun-dbaudit.aliyuncs.com', + 'cn-zhangjiakou' => 'yundun-dbaudit.aliyuncs.com', + 'cn-huhehaote' => 'yundun-dbaudit.aliyuncs.com', + 'cn-shanghai' => 'yundun-dbaudit.aliyuncs.com', + 'cn-shenzhen' => 'yundun-dbaudit.aliyuncs.com', + 'cn-hongkong' => 'yundun-dbaudit.aliyuncs.com', + 'ap-southeast-1' => 'yundun-dbaudit.aliyuncs.com', + 'ap-southeast-2' => 'yundun-dbaudit.aliyuncs.com', + 'ap-southeast-3' => 'yundun-dbaudit.aliyuncs.com', + 'ap-southeast-5' => 'yundun-dbaudit.aliyuncs.com', + 'ap-northeast-1' => 'yundun-dbaudit.aliyuncs.com', + 'us-west-1' => 'yundun-dbaudit.aliyuncs.com', + 'us-east-1' => 'yundun-dbaudit.aliyuncs.com', + 'eu-central-1' => 'yundun-dbaudit.aliyuncs.com', + 'me-east-1' => 'yundun-dbaudit.aliyuncs.com', + 'ap-south-1' => 'yundun-dbaudit.aliyuncs.com', + 'cn-shanghai-finance-1' => 'yundun-dbaudit.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'yundun-dbaudit.aliyuncs.com', + 'cn-north-2-gov-1' => 'yundun-dbaudit.aliyuncs.com', + 'cn-chengdu' => 'yundun-dbaudit.aliyuncs.com', + 'eu-west-1' => 'yundun-dbaudit.aliyuncs.com', + 'cn-huhehaote-nebula-1' => 'yundun-dbaudit.aliyuncs.com', + ], + 'bssopenapi' => + [ + 'cn-hangzhou' => 'business.aliyuncs.com', + 'cn-shanghai' => 'business.aliyuncs.com', + 'ap-southeast-1' => 'business.ap-southeast-1.aliyuncs.com', + ], + 'indvi' => + [ + 'cn-hangzhou' => 'indvi.cn-hangzhou.aliyuncs.com', + ], + 'swcopyright' => + [ + 'cn-hangzhou' => 'copyright.aliyuncs.com', + ], + 'multimediaai' => + [ + 'cn-beijing' => 'multimediaai.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'multimediaai.cn-hangzhou.aliyuncs.com', + ], + 'rsimganalys' => + [ + 'cn-hangzhou' => 'rsimganalys.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'rsimganalys.cn-shanghai.aliyuncs.com', + ], + 'tdsr' => + [ + 'cn-hangzhou' => 'lyj.cn-hangzhou.aliyuncs.com', + ], + 'eslogstash' => + [ + 'cn-qingdao' => 'elasticsearch.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'elasticsearch.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'elasticsearch.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'elasticsearch.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'elasticsearch.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'elasticsearch.cn-shenzhen.aliyuncs.com', + ], + 'vcoverimage' => + [ + 'cn-beijing' => 'vcoverimage.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'vcoverimage.cn-hangzhou.aliyuncs.com', + ], + 'ahas' => + [ + 'cn-beijing' => 'ahas.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'ahas.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ahas.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'ahas.cn-shenzhen.aliyuncs.com', + 'cn-zhangjiakou' => 'ahas.cn-zhangjiakou.aliyuncs.com', + ], + 'vstruction' => + [ + 'cn-beijing' => 'vstruction.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'vstruction.cn-hangzhou.aliyuncs.com', + ], + 'vcovergif' => + [ + 'cn-beijing' => 'vcovergif.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'vcovergif.cn-hangzhou.aliyuncs.com', + ], + 'aiccs' => + [ + 'cn-hangzhou' => 'aiccs.aliyuncs.com', + ], + 'nls' => + [ + 'cn-shanghai' => 'nls-slp.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'nls-slp.cn-shanghai.aliyuncs.com', + ], + 'antcloudauth' => + [ + 'cn-shanghai' => 'antcloudauth.cn-shanghai.aliyuncs.com', + ], + 'prepaid_ads' => + [ + 'cn-hangzhou-finance' => 'ads.cn-hangzhou-finance.aliyuncs.com', + 'cn-beijing' => 'ads.cn-beijing.aliyuncs.com', + 'cn-chengdu' => 'ads.cn-chengdu.aliyuncs.com', + 'cn-zhangjiakou' => 'ads.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'ads.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'ads.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'ads.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'ads.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'ads.ap-southeast-1.aliyuncs.com', + 'ap-southeast-3' => 'ads.ap-southeast-3.aliyuncs.com', + 'ap-northeast-1' => 'ads-share.ap-northeast-1.aliyuncs.com', + 'us-west-1' => 'ads.us-west-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'ads.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'ads.cn-north-2-gov-1.aliyuncs.com', + ], + 'hdr' => + [ + 'cn-qingdao' => 'hdr.cn-shanghai.aliyuncs.com', + 'cn-beijing' => 'hdr.cn-shanghai.aliyuncs.com', + 'cn-zhangjiakou' => 'hdr.cn-shanghai.aliyuncs.com', + 'cn-hangzhou' => 'hdr.cn-shanghai.aliyuncs.com', + 'cn-shanghai' => 'hdr.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'hdr.cn-shanghai.aliyuncs.com', + 'cn-hongkong' => 'hdr.cn-shanghai.aliyuncs.com', + 'cn-chengdu' => 'hdr.cn-shanghai.aliyuncs.com', + ], + 'cbs' => + [ + 'cn-qingdao' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-beijing' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-zhangjiakou' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-huhehaote' => 'dbs-api.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-hongkong' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'dbs-api.ap-southeast-1.aliyuncs.com', + 'ap-northeast-1' => 'dbs-api.ap-northeast-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-shanghai-finance-1' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'cn-chengdu' => 'dbs-api.cn-chengdu.aliyuncs.com', + 'ap-southeast-2' => 'dbs-api.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'dbs-api.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'dbs-api.ap-southeast-5.aliyuncs.com', + 'us-west-1' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'us-east-1' => 'dbs-api.cn-hangzhou.aliyuncs.com', + 'eu-central-1' => 'dbs-api.eu-central-1.aliyuncs.com', + ], + 'datag' => + [ + 'cn-beijing' => 'datag.cn-beijing.aliyuncs.com', + ], + 'retailir' => + [ + 'cn-hangzhou' => 'retailir.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'retailir.cn-shanghai.aliyuncs.com', + ], + 'mpaas' => + [ + 'cn-hangzhou' => 'mpaas.aliyuncs.com', + ], + 'iqa' => + [ + 'cn-hangzhou' => 'iqa.cn-hangzhou.aliyuncs.com', + ], + 'sofa' => + [ + 'cn-hangzhou' => 'sofa.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'sofa.cn-shanghai.aliyuncs.com', + 'cn-hangzhou-finance' => 'sofa.cn-shanghai.aliyuncs.com', + ], + 'edas' => + [ + 'cn-hangzhou' => 'edas.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'edas.cn-shanghai.aliyuncs.com', + 'cn-qingdao' => 'edas.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'edas.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'edas.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'edas.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'edas.cn-shanghai.aliyuncs.com', + 'ap-southeast-1' => 'edas.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'edas.ap-southeast-1.aliyuncs.com', + 'us-east-1' => 'edas.ap-southeast-1.aliyuncs.com', + 'eu-central-1' => 'edas.ap-southeast-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'edas.cn-shanghai.aliyuncs.com', + ], + 'gwsservice' => + [ + 'cn-shanghai' => 'gws.cn-shanghai.aliyuncs.com', + 'cn-beijing' => 'gws.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'gws.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'gws.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'gws.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen' => 'gws.cn-shenzhen.aliyuncs.com', + 'cn-chengdu' => 'gws.cn-chengdu.aliyuncs.com', + 'ap-southeast-1' => 'gws.ap-southeast-1.aliyuncs.com', + 'cn-hongkong' => 'gws.cn-hongkong.aliyuncs.com', + 'ap-southeast-2' => 'gws.ap-southeast-2.aliyuncs.com', + 'us-west-1' => 'gws.us-west-1.aliyuncs.com', + 'us-east-1' => 'gws.us-east-1.aliyuncs.com', + 'eu-central-1' => 'gws.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'gws.ap-south-1.aliyuncs.com', + 'cn-qingdao' => 'gws.cn-qingdao.aliyuncs.com', + 'ap-southeast-3' => 'gws.ap-northeast-3.aliyuncs.com', + 'ap-southeast-5' => 'gws.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'gws.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'gws.eu-west-1.aliyuncs.com', + ], + 'gds' => + [ + 'ap-southeast-1' => 'gdb-api.aliyuncs.com', + 'cn-beijing' => 'gdb-api.aliyuncs.com', + 'cn-zhangjiakou' => 'gdb-api.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'gdb-api.aliyuncs.com', + 'cn-shanghai' => 'gdb-api.aliyuncs.com', + 'cn-shenzhen' => 'gdb-api.aliyuncs.com', + 'ap-southeast-5' => 'gdb-api.ap-southeast-5.aliyuncs.com', + 'cn-qingdao' => 'gdb-api.aliyuncs.com', + 'cn-chengdu' => 'gdb-api.cn-chengdu.aliyuncs.com', + 'cn-huhehaote' => 'gdb-api.cn-huhehaote.aliyuncs.com', + 'cn-hongkong' => 'gdb-api.aliyuncs.com', + 'ap-southeast-2' => 'gdb-api.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'gdb-api.ap-southeast-3.aliyuncs.com', + 'eu-west-1' => 'gdb-api.eu-west-1.aliyuncs.com', + 'us-west-1' => 'gdb-api.aliyuncs.com', + 'us-east-1' => 'gdb-api.aliyuncs.com', + 'eu-central-1' => 'gdb-api.eu-central-1.aliyuncs.com', + 'me-east-1' => 'gdb-api.me-east-1.aliyuncs.com', + 'ap-south-1' => 'gdb-api.ap-south-1.aliyuncs.com', + ], + 'eais' => + [ + 'cn-beijing' => 'eais.cn-beijing.aliyuncs.com', + 'cn-shenzhen' => 'eais.cn-shenzhen.aliyuncs.com', + ], + 'clickhouse' => + [ + 'cn-beijing' => 'clickhouse.aliyuncs.com', + 'cn-hangzhou' => 'clickhouse.aliyuncs.com', + 'cn-shanghai' => 'clickhouse.aliyuncs.com', + 'cn-shenzhen' => 'clickhouse.aliyuncs.com', + 'ap-southeast-1' => 'clickhouse.aliyuncs.com', + ], + 'msepost' => + [ + 'cn-beijing' => 'mse.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'mse.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'mse.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'mse.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'mse.cn-shenzhen.aliyuncs.com', + 'us-east-1' => 'mse.us-east-1.aliyuncs.com', + ], + 'visionai' => + [ + 'cn-beijing' => 'visionai.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'visionai.cn-hangzhou.aliyuncs.com', + ], + 'mseprepaid' => + [ + 'cn-beijing' => 'mse.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'mse.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'mse.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'mse.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'mse.cn-shenzhen.aliyuncs.com', + 'us-east-1' => 'mse.us-east-1.aliyuncs.com', + ], + 'adam' => + [ + 'cn-beijing' => 'adam.cn-beijing.aliyuncs.com', + ], + 'onsmqtt' => + [ + 'cn-beijing' => 'onsmqtt.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'onsmqtt.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'onsmqtt.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'onsmqtt.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'onsmqtt.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'onsmqtt.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'onsmqtt.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'onsmqtt.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'onsmqtt.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'onsmqtt.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'onsmqtt.ap-southeast-5.aliyuncs.com', + 'us-west-1' => 'onsmqtt.us-west-1.aliyuncs.com', + 'eu-central-1' => 'onsmqtt.eu-central-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'onsmqtt.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'onsmqtt.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-qingdao' => 'onsmqtt.cn-qingdao.aliyuncs.com', + 'ap-northeast-1' => 'onsmqtt.ap-northeast-1.aliyuncs.com', + 'cn-chengdu' => 'onsmqtt.cn-chengdu.aliyuncs.com', + 'us-east-1' => 'onsmqtt.us-east-1.aliyuncs.com', + 'ap-south-1' => 'onsmqtt.ap-south-1.aliyuncs.com', + ], + 'dypls' => + [ + 'cn-hangzhou' => 'dyplsapi.aliyuncs.com', + ], + 'resourcemanager' => + [ + 'cn-hangzhou' => 'resourcemanager.aliyuncs.com', + 'cn-shanghai' => 'resourcemanager.aliyuncs.com', + ], + 'nlpautoml' => + [ + 'cn-hangzhou' => 'nlp-automl.cn-hangzhou.aliyuncs.com', + ], + 'companyreg' => + [ + 'cn-hangzhou' => 'companyreg.aliyuncs.com', + ], + 'aliyuncvc' => + [ + 'cn-hangzhou' => 'aliyuncvc.cn-hangzhou.aliyuncs.com', + ], + 'alimtautoml' => + [ + 'cn-hangzhou' => 'alimtautoml.cn-hangzhou.aliyuncs.com', + ], + 'dbfs' => + [ + 'cn-hangzhou' => 'dbfs.cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'dbfs.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'dbfs.cn-beijing.aliyuncs.com', + 'cn-chengdu' => 'dbfs.cn-chengdu.aliyuncs.com', + 'cn-zhangjiakou' => 'dbfs.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'dbfs.cn-huhehaote.aliyuncs.com', + 'cn-shanghai' => 'dbfs.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'dbfs.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'dbfs.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'dbfs.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'dbfs.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'dbfs.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'dbfs.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'dbfs.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'dbfs.eu-west-1.aliyuncs.com', + 'us-west-1' => 'dbfs.us-west-1.aliyuncs.com', + 'us-east-1' => 'dbfs.us-east-1.aliyuncs.com', + 'eu-central-1' => 'dbfs.eu-central-1.aliyuncs.com', + 'me-east-1' => 'dbfs.me-east-1.aliyuncs.com', + 'ap-south-1' => 'dbfs.ap-south-1.aliyuncs.com', + 'cn-heyuan' => 'dbfs.cn-heyuan.aliyuncs.com', + ], + 'addrp' => + [ + 'cn-hangzhou' => 'address-purification.cn-hangzhou.aliyuncs.com', + ], + 'gaplus' => + [ + 'cn-hangzhou' => 'ga.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'ga.cn-hangzhou.aliyuncs.com', + ], + 'datav' => + [ + 'cn-hangzhou' => 'datav.cn-hangzhou.aliyuncs.com', + ], + 'ocr' => + [ + 'cn-shanghai' => 'ocr.cn-shanghai.aliyuncs.com', + ], + 'objectdet' => + [ + 'cn-shanghai' => 'objectdet.cn-shanghai.aliyuncs.com', + ], + 'assetservice' => + [ + 'cn-shanghai' => 'assettech.cn-shanghai.aliyuncs.com', + ], + 'imageenhan' => + [ + 'cn-shanghai' => 'imageenhan.cn-shanghai.aliyuncs.com', + ], + 'imageaudit' => + [ + 'cn-shanghai' => 'imageaudit.cn-shanghai.aliyuncs.com', + ], + 'imagerecog' => + [ + 'cn-shanghai' => 'imagerecog.cn-shanghai.aliyuncs.com', + ], + 'imageseg' => + [ + 'cn-shanghai' => 'imageseg.cn-shanghai.aliyuncs.com', + ], + 'goodstech' => + [ + 'cn-shanghai' => 'goodstech.cn-shanghai.aliyuncs.com', + ], + 'facebody' => + [ + 'cn-shanghai' => 'facebody.cn-shanghai.aliyuncs.com', + ], + 'voicebot' => + [ + 'cn-hangzhou' => 'voicenavigator.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'voicenavigator.cn-shanghai.aliyuncs.com', + ], + 'dyiot' => + [ + 'cn-hangzhou' => 'dyiotapi.aliyuncs.com', + ], + 'drp' => + [ + 'cn-hangzhou' => 'drp-share.cn-hangzhou.aliyuncs.com', + ], + 'uem' => + [ + 'cn-hangzhou' => 'uem.aliyuncs.com', + ], + 'outboundbot' => + [ + 'cn-hangzhou' => 'outboundbot.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'outboundbot.cn-shanghai.aliyuncs.com', + ], + 'hcs_hgw' => + [ + 'cn-shanghai' => 'hgw.cn-shanghai.aliyuncs.com', + ], + 'acms' => + [ + 'cn-qingdao' => 'acm.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'acm.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'acm.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'acm.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'acm.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'acm.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'acm.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'acm.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'acm.ap-southeast-2.aliyuncs.com', + 'us-west-1' => 'acm.us-west-1.aliyuncs.com', + 'us-east-1' => 'acm.us-east-1.aliyuncs.com', + 'eu-central-1' => 'acm.eu-central-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'acm.cn-hangzhou-finance.aliyuncs.com', + 'cn-shanghai-finance-1' => 'acm.cn-shanghai-finance-1.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'acm.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'acm.cn-north-2-gov-1.aliyuncs.com', + 'ap-south-1' => 'acm.ap-south-1.aliyuncs.com', + ], + 'onsproxy' => + [ + 'cn-qingdao' => 'amqp-open.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'amqp-open.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'amqp-open.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'amqp-open.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'amqp-open.cn-shenzhen.aliyuncs.com', + 'cn-zhangjiakou' => 'amqp-open.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'amqp-open.cn-huhehaote.aliyuncs.com', + 'cn-hongkong' => 'amqp-open.cn-hongkong.aliyuncs.com', + ], + 'drdsro' => + [ + 'cn-qingdao' => 'drds.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'drds.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'drds.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'drds.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'drds.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'drds.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'drds.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'drds.cn-hangzhou.aliyuncs.com', + 'ap-southeast-1' => 'drds.ap-southeast-1.aliyuncs.com', + 'us-east-1' => 'drds.us-east-1.aliyuncs.com', + 'cn-shanghai-finance-1' => 'drds.cn-hangzhou.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'drds.cn-hangzhou.aliyuncs.com', + 'cn-north-2-gov-1' => 'drds.cn-hangzhou.aliyuncs.com', + ], + 'opensearch' => + [ + 'cn-qingdao' => 'opensearch.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'opensearch.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'opensearch.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'opensearch.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'opensearch.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'opensearch.cn-shenzhen.aliyuncs.com', + 'ap-southeast-1' => 'opensearch.ap-southeast-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'opensearch.cn-north-2-gov-1.aliyuncs.com', + ], + 'edasschedulerx' => + [ + 'cn-beijing' => 'schedulerx.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'schedulerx.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'schedulerx.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'schedulerx.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'schedulerx.cn-shenzhen.aliyuncs.com', + 'us-east-1' => 'schedulerx.us-east-1.aliyuncs.com', + ], + 'tag' => + [ + 'cn-beijing' => 'tag.aliyuncs.com', + 'cn-shenzhen' => 'tag.aliyuncs.com', + 'cn-qingdao' => 'tag.aliyuncs.com', + 'cn-chengdu' => 'tag.cn-chengdu.aliyuncs.com', + 'cn-zhangjiakou' => 'tag.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'tag.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'tag.aliyuncs.com', + 'cn-shanghai' => 'tag.aliyuncs.com', + 'cn-hongkong' => 'tag.aliyuncs.com', + 'ap-southeast-1' => 'tag.aliyuncs.com', + 'ap-southeast-2' => 'tag.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'tag.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'tag.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'tag.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'tag.eu-west-1.aliyuncs.com', + 'us-west-1' => 'tag.aliyuncs.com', + 'us-east-1' => 'tag.aliyuncs.com', + 'eu-central-1' => 'tag.eu-central-1.aliyuncs.com', + 'me-east-1' => 'tag.me-east-1.aliyuncs.com', + 'ap-south-1' => 'tag.ap-south-1.aliyuncs.com', + 'cn-hangzhou-finance' => 'tag.aliyuncs.com', + 'cn-shanghai-finance-1' => 'tag.aliyuncs.com', + 'cn-shenzhen-finance-1' => 'tag.cn-shenzhen-finance-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'tag.cn-north-2-gov-1.aliyuncs.com', + 'cn-fujian' => 'tag.aliyuncs.com', + 'cn-haidian-cm12-c01' => 'tag.aliyuncs.com', + 'cn-hangzhou-internal-test-2' => 'tag.aliyuncs.com', + 'cn-hangzhou-internal-test-3' => 'tag.aliyuncs.com', + 'cn-hangzhou-test-306' => 'tag.aliyuncs.com', + 'cn-shanghai-et15-b01' => 'tag.aliyuncs.com', + 'cn-zhangbei-na61-b01' => 'tag.aliyuncs.com', + 'eu-west-1-oxs' => 'tag.cn-shenzhen-cloudstone.aliyuncs.com', + 'cn-heyuan' => 'tag.cn-heyuan.aliyuncs.com', + 'cn-wulanchabu' => 'tag.cn-wulanchabu.aliyuncs.com', + ], + 'servicemesh' => + [ + 'cn-beijing' => 'servicemesh.aliyuncs.com', + 'cn-zhangjiakou' => 'servicemesh.aliyuncs.com', + 'cn-hangzhou' => 'servicemesh.aliyuncs.com', + 'cn-shanghai' => 'servicemesh.aliyuncs.com', + 'cn-shenzhen' => 'servicemesh.aliyuncs.com', + 'ap-southeast-1' => 'servicemesh.aliyuncs.com', + 'us-west-1' => 'servicemesh.aliyuncs.com', + ], + 'rdc' => + [ + 'cn-beijing' => 'rdc.cn-beijing.aliyuncs.com', + ], + 'sddprsrc' => + [ + 'cn-zhangjiakou' => 'sddp-rsrc.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'sddprsrc.cn-hangzhou.aliyuncs.com', + 'cn-north-2-gov-1' => 'sddprsrc.cn-north-2-gov-1.aliyuncs.com', + ], + 'polardbx' => + [ + 'cn-hangzhou' => 'polardbx.cn-hangzhou.aliyuncs.com', + 'cn-qingdao' => 'polardbx.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'polardbx.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'polardbx.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'polardbx.cn-huhehaote.aliyuncs.com', + 'cn-shanghai' => 'polardbx.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'polardbx.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'polardbx.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'polardbx.ap-southeast-1.aliyuncs.com', + ], + 'dytns' => + [ + 'cn-hangzhou' => 'dytnsapi.aliyuncs.com', + ], + 'datahub' => + [ + 'cn-hangzhou' => 'datahub.aliyuncs.com', + 'cn-shanghai' => 'datahub.aliyuncs.com', + ], + 'geoip' => + [ + 'cn-hangzhou' => 'geoip.aliyuncs.com', + ], + 'digitalstore' => + [ + 'cn-hangzhou' => 'digitalstore.cn-hangzhou.aliyuncs.com', + ], + 'quickbi' => + [ + 'cn-hangzhou' => 'quickbi-public-share.aliyuncs.com', + 'cn-hongkong' => 'quickbi-public-share.aliyuncs.com', + 'ap-southeast-1' => 'quickbi-public-share.aliyuncs.com', + 'ap-southeast-3' => 'quickbi-public-share.aliyuncs.com', + 'eu-central-1' => 'quickbi-public-share.aliyuncs.com', + ], + 'alimtdt' => + [ + 'cn-hangzhou' => 'mt.cn-hangzhou.aliyuncs.com', + ], + 'sofamq' => + [ + 'cn-shanghai' => 'sofa.cn-shanghai.aliyuncs.com', + 'cn-hangzhou-finance' => 'sofa.cn-hangzhou-finance.aliyuncs.com', + ], + 'sofaodp' => + [ + 'cn-shanghai' => 'sofa.cn-shanghai.aliyuncs.com', + 'cn-hangzhou-finance' => 'sofa.cn-hangzhou-finance.aliyuncs.com', + ], + 'dascharge' => + [ + 'cn-shanghai' => 'das.aliyuncs.com', + 'cn-hangzhou' => 'das.aliyuncs.com', + ], + 'sofadst' => + [ + 'cn-shanghai' => 'sofa.cn-shanghai.aliyuncs.com', + ], + 'springcloud' => + [ + 'cn-qingdao' => 'ms.aliyuncs.com', + 'cn-beijing' => 'ms.aliyuncs.com', + 'cn-zhangjiakou' => 'ms.aliyuncs.com', + 'cn-hangzhou' => 'ms.aliyuncs.com', + 'cn-shanghai' => 'ms.aliyuncs.com', + 'cn-shenzhen' => 'ms.aliyuncs.com', + ], + 'edasmsc' => + [ + 'cn-qingdao' => 'edasmsc.aliyuncs.com', + 'cn-beijing' => 'edasmsc.aliyuncs.com', + 'cn-zhangjiakou' => 'edasmsc.aliyuncs.com', + 'cn-hangzhou' => 'edasmsc.aliyuncs.com', + 'cn-shanghai' => 'edasmsc.aliyuncs.com', + 'cn-shenzhen' => 'edasmsc.aliyuncs.com', + 'cn-hongkong' => 'edasmsc.aliyuncs.com', + ], + 'polarx' => + [ + 'cn-qingdao' => 'polardbx-share.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'polardbx-share.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'polardbx-share.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'polardbx-share.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'polardbx-share.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'polardbx-share.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'polardbx-share.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'polardbx-share.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'polardbx-share.ap-southeast-1.aliyuncs.com', + ], + 'cddc' => + [ + 'cn-qingdao' => 'cddc.aliyuncs.com', + 'cn-beijing' => 'cddc.aliyuncs.com', + 'cn-chengdu' => 'cddc.cn-chengdu.aliyuncs.com', + 'cn-zhangjiakou' => 'cddc.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'cddc.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'cddc.aliyuncs.com', + 'cn-shanghai' => 'cddc.aliyuncs.com', + 'cn-shenzhen' => 'cddc.aliyuncs.com', + 'cn-hongkong' => 'cddc.aliyuncs.com', + 'ap-southeast-1' => 'cddc.aliyuncs.com', + 'ap-southeast-2' => 'cddc.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'cddc.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'cddc.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'cddc.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'cddc.eu-west-1.aliyuncs.com', + 'us-west-1' => 'cddc.aliyuncs.com', + 'us-east-1' => 'cddc.aliyuncs.com', + 'eu-central-1' => 'cddc.eu-central-1.aliyuncs.com', + 'me-east-1' => 'cddc.me-east-1.aliyuncs.com', + 'ap-south-1' => 'cddc.ap-south-1.aliyuncs.com', + 'cn-heyuan' => 'cddc.aliyuncs.com', + ], + 'dlasparkpre' => + [ + 'cn-qingdao' => 'dlaspark.aliyuncs.com', + 'cn-beijing' => 'dlaspark.aliyuncs.com', + 'cn-zhangjiakou' => 'dlaspark.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'dlaspark.aliyuncs.com', + 'cn-shanghai' => 'dlaspark.aliyuncs.com', + 'cn-shenzhen' => 'dlaspark.aliyuncs.com', + ], + 'spark' => + [ + 'cn-qingdao' => 'ddi.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'ddi.aliyuncs.com', + 'cn-chengdu' => 'ddi.cn-chengdu.aliyuncs.com', + 'cn-zhangjiakou' => 'ddi.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'ddi.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'ddi.aliyuncs.com', + 'cn-shanghai' => 'ddi.aliyuncs.com', + 'cn-shenzhen' => 'ddi.aliyuncs.com', + 'cn-hongkong' => 'ddi.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'ddi.aliyuncs.com', + 'ap-southeast-2' => 'ddi.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'ddi.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'ddi.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'ddi.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'ddi.eu-west-1.aliyuncs.com', + 'us-west-1' => 'ddi.aliyuncs.com', + 'us-east-1' => 'ddi.us-east-1.aliyuncs.com', + 'eu-central-1' => 'ddi.eu-central-1.aliyuncs.com', + 'me-east-1' => 'ddi.me-east-1.aliyuncs.com', + 'ap-south-1' => 'ddi.ap-south-1.aliyuncs.com', + 'cn-heyuan' => 'ddi.aliyuncs.com', + ], + 'multisearch' => + [ + 'cn-beijing' => 'multisearch.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'multisearch.cn-hangzhou.aliyuncs.com', + ], + 'pai' => + [ + 'cn-beijing' => 'pai.cn-beijing.aliyuncs.com', + 'cn-hangzhou' => 'pai.cn-hangzhou.data.aliyun.com', + 'cn-shanghai' => 'pai.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'pai.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'pai.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'pai.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'pai.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'pai.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'pai.ap-southeast-5.aliyuncs.com', + 'us-west-1' => 'pai.us-west-1.aliyuncs.com', + 'us-east-1' => 'pai.us-east-1.aliyuncs.com', + 'eu-central-1' => 'pai.eu-central-1.aliyuncs.com', + 'me-east-1' => 'pai.me-east-1.aliyuncs.com', + 'ap-south-1' => 'pai.ap-south-1.aliyuncs.com', + ], + 'fcpre' => + [ + 'cn-chengdu' => 'cn-chengdu.fc.aliyuncs.com', + 'ap-southeast-3' => 'ap-southeast-3.fc.aliyuncs.com', + 'eu-west-1' => 'eu-west-1.fc.aliyuncs.com', + 'cn-hangzhou-finance' => 'cn-hangzhou-finance.fc.aliyuncs.com', + ], + 'ahaschaospre' => + [ + 'cn-zhangjiakou' => 'ahas.cn-zhangjiakou.aliyuncs.com', + ], + 'sasti' => + [ + 'cn-zhangjiakou' => 'sasti.aliyuncs.com', + ], + 'config' => + [ + 'cn-hangzhou' => 'config.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'config.cn-shanghai.aliyuncs.com', + ], + 'ledgerdb' => + [ + 'cn-hangzhou' => 'ledgerdb.cn-hangzhou.aliyuncs.com', + ], + 'nlpvision' => + [ + 'cn-hangzhou' => 'nlp-vision.cn-hangzhou.aliyuncs.com', + ], + 'alimtld' => + [ + 'cn-hangzhou' => 'mt.cn-hangzhou.aliyuncs.com', + ], + 'databot' => + [ + 'cn-hangzhou' => 'databot.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'databot.cn-shanghai.aliyuncs.com', + ], + 'livinglink' => + [ + 'cn-hangzhou' => 'livinglink.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'livinglink.cn-shanghai.aliyuncs.com', + 'ap-southeast-1' => 'livinglink.ap-southeast-1.aliyuncs.com', + 'us-east-1' => 'livinglink.us-east-1.aliyuncs.com', + 'eu-central-1' => 'livinglink.eu-central-1.aliyuncs.com', + ], + 'eipanycast' => + [ + 'cn-hangzhou' => 'eipanycast.cn-hangzhou.aliyuncs.com', + ], + 'alimtct' => + [ + 'cn-hangzhou' => 'mt.cn-hangzhou.aliyuncs.com', + ], + 'videorecog' => + [ + 'cn-shanghai' => 'videorecog.cn-shanghai.aliyuncs.com', + ], + 'imageprocess' => + [ + 'cn-shanghai' => 'imageprocess.cn-shanghai.aliyuncs.com', + ], + 'sofats' => + [ + 'cn-shanghai' => 'sofa.cn-shanghai.aliyuncs.com', + 'cn-hangzhou-finance' => 'sofa.cn-hangzhou-finance.aliyuncs.com', + ], + 'videoenhan' => + [ + 'cn-shanghai' => 'videoenhan.cn-shanghai.aliyuncs.com', + ], + 'imgsearch' => + [ + 'cn-shanghai' => 'imgsearch.cn-shanghai.aliyuncs.com', + ], + 'videoseg' => + [ + 'cn-shanghai' => 'videoseg.cn-shanghai.aliyuncs.com', + ], + 'sofacaferms' => + [ + 'cn-hangzhou-finance' => 'sofa.cn-hangzhou-finance.aliyuncs.com', + ], + 'retailadvqa' => + [ + 'cn-zhangjiakou' => 'quicka-public.cn-zhangjiakou.aliyuncs.com', + 'cn-shanghai' => 'quicka-public.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'quicka-public.cn-shenzhen.aliyuncs.com', + ], + 'linkanalytics' => + [ + 'cn-hangzhou' => 'linkanalytics.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'linkanalytics.cn-shanghai.aliyuncs.com', + ], + 'swas' => + [ + 'cn-qingdao' => 'swas.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'swas.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'swas.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'swas.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'swas.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'swas.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'swas.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'swas.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'swas.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'swas.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'swas.ap-southeast-3.aliyuncs.com', + 'ap-southeast-5' => 'swas.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'swas.ap-northeast-1.aliyuncs.com', + 'eu-west-1' => 'swas.eu-west-1.aliyuncs.com', + 'us-west-1' => 'swas.us-west-1.aliyuncs.com', + 'us-east-1' => 'swas.us-east-1.aliyuncs.com', + 'eu-central-1' => 'swas.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'swas.ap-south-1.aliyuncs.com', + ], + 'gws' => + [ + 'cn-qingdao' => 'gws.cn-qingdao.aliyuncs.com', + 'cn-beijing' => 'gws.cn-beijing.aliyuncs.com', + 'cn-chengdu' => 'gws.cn-chengdu.aliyuncs.com', + 'cn-zhangjiakou' => 'gws.cn-zhangjiakou.aliyuncs.com', + 'cn-huhehaote' => 'gws.cn-huhehaote.aliyuncs.com', + 'cn-hangzhou' => 'gws.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'gws.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'gws.cn-shenzhen.aliyuncs.com', + 'cn-hongkong' => 'gws.cn-hongkong.aliyuncs.com', + 'ap-southeast-1' => 'gws.ap-southeast-1.aliyuncs.com', + 'ap-southeast-2' => 'gws.ap-southeast-2.aliyuncs.com', + 'ap-southeast-3' => 'gws.ap-northeast-3.aliyuncs.com', + 'ap-southeast-5' => 'gws.ap-southeast-5.aliyuncs.com', + 'ap-northeast-1' => 'gws.ap-northeast-1.aliyuncs.com', + 'us-west-1' => 'gws.us-west-1.aliyuncs.com', + 'us-east-1' => 'gws.us-east-1.aliyuncs.com', + 'eu-central-1' => 'gws.eu-central-1.aliyuncs.com', + 'ap-south-1' => 'gws.ap-south-1.aliyuncs.com', + ], + 'dlacupost' => + [ + 'cn-beijing' => 'openanalytics.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'openanalytics.cn-hongkong.aliyuncs.com', + 'cn-hangzhou' => 'openanalytics.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'openanalytics.cn-shanghai.aliyuncs.com', + 'cn-shenzhen' => 'openanalytics.cn-beijing.aliyuncs.com', + 'cn-hongkong' => 'openanalytics.cn-hongkong.aliyuncs.com', + ], + 'ressharing' => + [ + 'cn-beijing' => 'resourcesharing.cn-beijing.aliyuncs.com', + 'cn-zhangjiakou' => 'resourcesharing.cn-zhangjiakou.aliyuncs.com', + 'cn-hangzhou' => 'resourcesharing.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'resourcesharing.cn-shanghai.aliyuncs.com', + 'ap-southeast-1' => 'resourcesharing.ap-southeast-1.aliyuncs.com', + 'cn-north-2-gov-1' => 'resourcesharing.cn-north-2-gov-1.aliyuncs.com', + ], + 'uisplus' => + [ + 'cn-huhehaote' => 'uisplus.cn-huhehaote.aliyuncs.com', + 'cn-shenzhen' => 'uisplus.cn-shenzhen.aliyuncs.com', + ], + 'idrsservice' => + [ + 'cn-hangzhou' => 'idrsservice.cn-hangzhou.aliyuncs.com', + ], + 'alinlp' => + [ + 'cn-hangzhou' => 'alinlp.cn-hangzhou.aliyuncs.com', + ], + 'miniapplcdp' => + [ + 'cn-hangzhou' => 'miniapplcdp.aliyuncs.com', + 'cn-shanghai' => 'miniapplcdp.aliyuncs.com', + ], + 'baasdis' => + [ + 'cn-hangzhou' => 'baasdis.cn-hangzhou.aliyuncs.com', + ], + 'baasodats' => + [ + 'cn-hangzhou' => 'baasodats.cn-hangzhou.aliyuncs.com', + ], + 'baascccs' => + [ + 'cn-hangzhou' => 'baascccs.cn-hangzhou.aliyuncs.com', + ], + 'pam' => + [ + 'cn-hangzhou' => 'pam.cn-hangzhou.aliyuncs.com', + ], + 'alimtec' => + [ + 'cn-hangzhou' => 'mt.cn-hangzhou.aliyuncs.com', + ], + 'cloudgame' => + [ + 'cn-hangzhou' => 'cloudgame.cn-hangzhou.aliyuncs.com', + 'cn-shanghai' => 'cloudgame.cn-shanghai.aliyuncs.com', + ], + 'csas' => + [ + 'cn-hangzhou' => 'csas.aliyuncs.com', + ], + 'facebodyqps' => + [ + 'cn-shanghai' => 'facebody.cn-shanghai.aliyuncs.com', + ], + 'face' => + [ + 'cn-shanghai' => 'face.cn-shanghai.aliyuncs.com', + ], + 'cams' => + [ + 'ap-southeast-1' => 'cams.ap-southeast-1.aliyuncs.com', + ], + 'mpaasfin' => + [ + 'cn-hangzhou-finance' => 'mpaas.cn-hangzhou-finance.aliyuncs.com', + ], + 'mpaasgov' => + [ + 'cn-north-2-gov-1' => 'mpaas.cn-north-2-gov-1.aliyuncs.com', + ], + ], +]; diff --git a/vendor/alibabacloud/client/src/Credentials/AccessKeyCredential.php b/vendor/alibabacloud/client/src/Credentials/AccessKeyCredential.php new file mode 100644 index 0000000..bacaecc --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/AccessKeyCredential.php @@ -0,0 +1,65 @@ +accessKeyId = $accessKeyId; + $this->accessKeySecret = $accessKeySecret; + } + + /** + * @return string + */ + public function getAccessKeyId() + { + return $this->accessKeyId; + } + + /** + * @return string + */ + public function getAccessKeySecret() + { + return $this->accessKeySecret; + } + + /** + * @return string + */ + public function __toString() + { + return "$this->accessKeyId#$this->accessKeySecret"; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/BearerTokenCredential.php b/vendor/alibabacloud/client/src/Credentials/BearerTokenCredential.php new file mode 100644 index 0000000..db69a7c --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/BearerTokenCredential.php @@ -0,0 +1,66 @@ +bearerToken = $bearerToken; + } + + /** + * @return string + */ + public function getBearerToken() + { + return $this->bearerToken; + } + + /** + * @return string + */ + public function getAccessKeyId() + { + return ''; + } + + /** + * @return string + */ + public function getAccessKeySecret() + { + return ''; + } + + /** + * @return string + */ + public function __toString() + { + return "bearerToken#$this->bearerToken"; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/CredentialsInterface.php b/vendor/alibabacloud/client/src/Credentials/CredentialsInterface.php new file mode 100644 index 0000000..96ee50a --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/CredentialsInterface.php @@ -0,0 +1,18 @@ +roleName = $roleName; + } + + /** + * @return string + */ + public function getRoleName() + { + return $this->roleName; + } + + /** + * @return string + */ + public function __toString() + { + return "roleName#$this->roleName"; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Ini/CreateTrait.php b/vendor/alibabacloud/client/src/Credentials/Ini/CreateTrait.php new file mode 100644 index 0000000..2ec7511 --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Ini/CreateTrait.php @@ -0,0 +1,181 @@ +missingRequired('type', $clientName); + } + + return $this->createClientByType($clientName, $credential)->name($clientName); + } + + /** + * @param string $clientName + * @param array $credential + * + * @return AccessKeyClient|BearerTokenClient|EcsRamRoleClient|RamRoleArnClient|RsaKeyPairClient + * @throws ClientException + */ + private function createClientByType($clientName, array $credential) + { + switch (\strtolower($credential['type'])) { + case 'access_key': + return $this->accessKeyClient($clientName, $credential); + case 'ecs_ram_role': + return $this->ecsRamRoleClient($clientName, $credential); + case 'ram_role_arn': + return $this->ramRoleArnClient($clientName, $credential); + case 'bearer_token': + return $this->bearerTokenClient($clientName, $credential); + case 'rsa_key_pair': + return $this->rsaKeyPairClient($clientName, $credential); + default: + throw new ClientException( + "Invalid type '{$credential['type']}' for '$clientName' in {$this->filename}", + SDK::INVALID_CREDENTIAL + ); + } + } + + /** + * @param array $credential + * @param string $clientName + * + * @return AccessKeyClient + * @throws ClientException + */ + private function accessKeyClient($clientName, array $credential) + { + if (!isset($credential['access_key_id'])) { + $this->missingRequired('access_key_id', $clientName); + } + + if (!isset($credential['access_key_secret'])) { + $this->missingRequired('access_key_secret', $clientName); + } + + return new AccessKeyClient( + $credential['access_key_id'], + $credential['access_key_secret'] + ); + } + + /** + * @param string $clientName + * @param array $credential + * + * @return EcsRamRoleClient + * @throws ClientException + */ + private function ecsRamRoleClient($clientName, array $credential) + { + if (!isset($credential['role_name'])) { + $this->missingRequired('role_name', $clientName); + } + + return new EcsRamRoleClient($credential['role_name']); + } + + /** + * @param string $clientName + * @param array $credential + * + * @return RamRoleArnClient + * @throws ClientException + */ + private function ramRoleArnClient($clientName, array $credential) + { + if (!isset($credential['access_key_id'])) { + $this->missingRequired('access_key_id', $clientName); + } + + if (!isset($credential['access_key_secret'])) { + $this->missingRequired('access_key_secret', $clientName); + } + + if (!isset($credential['role_arn'])) { + $this->missingRequired('role_arn', $clientName); + } + + if (!isset($credential['role_session_name'])) { + $this->missingRequired('role_session_name', $clientName); + } + + return new RamRoleArnClient( + $credential['access_key_id'], + $credential['access_key_secret'], + $credential['role_arn'], + $credential['role_session_name'] + ); + } + + /** + * @param string $clientName + * @param array $credential + * + * @return BearerTokenClient + * @throws ClientException + */ + private function bearerTokenClient($clientName, array $credential) + { + if (!isset($credential['bearer_token'])) { + $this->missingRequired('bearer_token', $clientName); + } + + return new BearerTokenClient($credential['bearer_token']); + } + + /** + * @param array $credential + * @param string $clientName + * + * @return RsaKeyPairClient + * @throws ClientException + */ + private function rsaKeyPairClient($clientName, array $credential) + { + if (!isset($credential['public_key_id'])) { + $this->missingRequired('public_key_id', $clientName); + } + + if (!isset($credential['private_key_file'])) { + $this->missingRequired('private_key_file', $clientName); + } + + return new RsaKeyPairClient( + $credential['public_key_id'], + $credential['private_key_file'] + ); + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Ini/IniCredential.php b/vendor/alibabacloud/client/src/Credentials/Ini/IniCredential.php new file mode 100644 index 0000000..94ec7fb --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Ini/IniCredential.php @@ -0,0 +1,209 @@ +filename = $filename ?: $this->getDefaultFile(); + } + + /** + * Get the default credential file. + * + * @return string + */ + public function getDefaultFile() + { + return self::getHomeDirectory() . DIRECTORY_SEPARATOR . '.alibabacloud' . DIRECTORY_SEPARATOR . 'credentials'; + } + + /** + * Gets the environment's HOME directory. + * + * @return null|string + */ + private static function getHomeDirectory() + { + if (getenv('HOME')) { + return getenv('HOME'); + } + + return (getenv('HOMEDRIVE') && getenv('HOMEPATH')) + ? getenv('HOMEDRIVE') . getenv('HOMEPATH') + : null; + } + + /** + * Clear credential cache. + * + * @return void + */ + public static function forgetLoadedCredentialsFile() + { + self::$hasLoaded = []; + } + + /** + * Get the credential file. + * + * @return string + */ + public function getFilename() + { + return $this->filename; + } + + /** + * @param array $array + * @param string $key + * + * @return bool + */ + protected static function isNotEmpty(array $array, $key) + { + return isset($array[$key]) && !empty($array[$key]); + } + + /** + * @param string $key + * @param string $clientName + * + * @throws ClientException + */ + public function missingRequired($key, $clientName) + { + throw new ClientException( + "Missing required '$key' option for '$clientName' in " . $this->getFilename(), + SDK::INVALID_CREDENTIAL + ); + } + + /** + * @return array|mixed + * @throws ClientException + */ + public function load() + { + // If it has been loaded, assign the client directly. + if (isset(self::$hasLoaded[$this->filename])) { + /** + * @var $client Client + */ + foreach (self::$hasLoaded[$this->filename] as $projectName => $client) { + $client->name($projectName); + } + + return self::$hasLoaded[$this->filename]; + } + + return $this->loadFile(); + } + + /** + * Exceptions will be thrown if the file is unreadable and not the default file. + * + * @return array|mixed + * @throws ClientException + */ + private function loadFile() + { + if (!\AlibabaCloud\Client\inOpenBasedir($this->filename)) { + return []; + } + + if (!\is_readable($this->filename) || !\is_file($this->filename)) { + if ($this->filename === $this->getDefaultFile()) { + // @codeCoverageIgnoreStart + return []; + // @codeCoverageIgnoreEnd + } + throw new ClientException( + 'Credential file is not readable: ' . $this->getFilename(), + SDK::INVALID_CREDENTIAL + ); + } + + return $this->parseFile(); + } + + /** + * Decode the ini file into an array. + * + * @return array|mixed + * @throws ClientException + */ + private function parseFile() + { + try { + $file = \parse_ini_file($this->filename, true); + if (\is_array($file) && $file !== []) { + return $this->initClients($file); + } + throw new ClientException( + 'Format error: ' . $this->getFilename(), + SDK::INVALID_CREDENTIAL + ); + } catch (\Exception $e) { + throw new ClientException( + $e->getMessage(), + SDK::INVALID_CREDENTIAL, + $e + ); + } + } + + /** + * Initialize clients. + * + * @param array $array + * + * @return array|mixed + * @throws ClientException + */ + private function initClients($array) + { + foreach (\array_change_key_case($array) as $clientName => $configures) { + $configures = \array_change_key_case($configures); + $clientInstance = $this->createClient($clientName, $configures); + if ($clientInstance instanceof Client) { + self::$hasLoaded[$this->filename][$clientName] = $clientInstance; + self::setClientAttributes($configures, $clientInstance); + self::setCert($configures, $clientInstance); + self::setProxy($configures, $clientInstance); + } + } + + return isset(self::$hasLoaded[$this->filename]) + ? self::$hasLoaded[$this->filename] + : []; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Ini/OptionsTrait.php b/vendor/alibabacloud/client/src/Credentials/Ini/OptionsTrait.php new file mode 100644 index 0000000..192d494 --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Ini/OptionsTrait.php @@ -0,0 +1,111 @@ +regionId($configures['region_id']); + } + + if (isset($configures['debug'])) { + $client->options( + [ + 'debug' => (bool)$configures['debug'], + ] + ); + } + + if (self::isNotEmpty($configures, 'timeout')) { + $client->options( + [ + 'timeout' => $configures['timeout'], + ] + ); + } + + if (self::isNotEmpty($configures, 'connect_timeout')) { + $client->options( + [ + 'connect_timeout' => $configures['connect_timeout'], + ] + ); + } + } + + /** + * @param array $configures + * @param Client $client + */ + private static function setProxy($configures, Client $client) + { + if (self::isNotEmpty($configures, 'proxy')) { + $client->options( + [ + 'proxy' => $configures['proxy'], + ] + ); + } + $proxy = []; + if (self::isNotEmpty($configures, 'proxy_http')) { + $proxy['http'] = $configures['proxy_http']; + } + if (self::isNotEmpty($configures, 'proxy_https')) { + $proxy['https'] = $configures['proxy_https']; + } + if (self::isNotEmpty($configures, 'proxy_no')) { + $proxy['no'] = \explode(',', $configures['proxy_no']); + } + if ($proxy !== []) { + $client->options( + [ + 'proxy' => $proxy, + ] + ); + } + } + + /** + * @param array $configures + * @param Client $client + */ + private static function setCert($configures, Client $client) + { + if (self::isNotEmpty($configures, 'cert_file') && !self::isNotEmpty($configures, 'cert_password')) { + $client->options( + [ + 'cert' => $configures['cert_file'], + ] + ); + } + + if (self::isNotEmpty($configures, 'cert_file') && self::isNotEmpty($configures, 'cert_password')) { + $client->options( + [ + 'cert' => [ + $configures['cert_file'], + $configures['cert_password'], + ], + ] + ); + } + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Providers/CredentialsProvider.php b/vendor/alibabacloud/client/src/Credentials/Providers/CredentialsProvider.php new file mode 100644 index 0000000..21aec9b --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Providers/CredentialsProvider.php @@ -0,0 +1,170 @@ +asDefaultClient(); + } + }; + } + + /** + * @return Closure + */ + public static function ini() + { + return static function () { + $ini = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE'); + + if ($ini) { + AlibabaCloud::load($ini); + } else { + // @codeCoverageIgnoreStart + AlibabaCloud::load(); + // @codeCoverageIgnoreEnd + } + + self::compatibleWithGlobal(); + }; + } + + /** + * @codeCoverageIgnore + * + * Compatible with global + * + * @throws ClientException + */ + private static function compatibleWithGlobal() + { + if (AlibabaCloud::has('global') && !AlibabaCloud::has(self::getDefaultName())) { + AlibabaCloud::get('global')->name(self::getDefaultName()); + } + } + + /** + * @return array|false|string + * @throws ClientException + */ + public static function getDefaultName() + { + $name = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_PROFILE'); + + if ($name) { + return $name; + } + + return 'default'; + } + + /** + * @return Closure + */ + public static function instance() + { + return static function () { + $instance = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_ECS_METADATA'); + if ($instance) { + AlibabaCloud::ecsRamRoleClient($instance)->asDefaultClient(); + } + }; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Providers/EcsRamRoleProvider.php b/vendor/alibabacloud/client/src/Credentials/Providers/EcsRamRoleProvider.php new file mode 100644 index 0000000..0515ca6 --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Providers/EcsRamRoleProvider.php @@ -0,0 +1,128 @@ +getCredentialsInCache(); + + if ($result === null) { + $result = $this->request(); + + if (!isset($result['AccessKeyId'], $result['AccessKeySecret'], $result['SecurityToken'])) { + throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL); + } + + $this->cache($result->toArray()); + } + + return new StsCredential( + $result['AccessKeyId'], + $result['AccessKeySecret'], + $result['SecurityToken'] + ); + } + + /** + * Get credentials by request. + * + * @return Result + * @throws ClientException + * @throws ServerException + */ + public function request() + { + $result = $this->getResponse(); + + if ($result->getStatusCode() === 404) { + $message = 'The role was not found in the instance'; + throw new ClientException($message, SDK::INVALID_CREDENTIAL); + } + + if (!$result->isSuccess()) { + $message = 'Error retrieving credentials from result'; + throw new ServerException($result, $message, SDK::INVALID_CREDENTIAL); + } + + return $result; + } + + /** + * Get data from meta. + * + * @return mixed|ResponseInterface + * @throws ClientException + * @throws Exception + */ + public function getResponse() + { + /** + * @var EcsRamRoleCredential $credential + */ + $credential = $this->client->getCredential(); + $url = $this->uri . $credential->getRoleName(); + + $options = [ + 'http_errors' => false, + 'timeout' => 1, + 'connect_timeout' => 1, + 'debug' => $this->client->isDebug(), + ]; + + try { + return RpcRequest::createClient()->request('GET', $url, $options); + } catch (GuzzleException $exception) { + if (Stringy::contains($exception->getMessage(), 'timed')) { + $message = 'Timeout or instance does not belong to Alibaba Cloud'; + } else { + $message = $exception->getMessage(); + } + + throw new ClientException( + $message, + SDK::SERVER_UNREACHABLE, + $exception + ); + } + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Providers/Provider.php b/vendor/alibabacloud/client/src/Credentials/Providers/Provider.php new file mode 100644 index 0000000..b64dab8 --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Providers/Provider.php @@ -0,0 +1,88 @@ +client = $client; + } + + /** + * Get the credentials from the cache in the validity period. + * + * @return array|null + */ + public function getCredentialsInCache() + { + if (isset(self::$credentialsCache[$this->key()])) { + $result = self::$credentialsCache[$this->key()]; + if (\strtotime($result['Expiration']) - \time() >= $this->expirationSlot) { + return $result; + } + unset(self::$credentialsCache[$this->key()]); + } + + return null; + } + + /** + * Get the toString of the credentials as the key. + * + * @return string + */ + protected function key() + { + return (string)$this->client->getCredential(); + } + + /** + * Cache credentials. + * + * @param array $credential + */ + protected function cache(array $credential) + { + self::$credentialsCache[$this->key()] = $credential; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Providers/RamRoleArnProvider.php b/vendor/alibabacloud/client/src/Credentials/Providers/RamRoleArnProvider.php new file mode 100644 index 0000000..ce4de41 --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Providers/RamRoleArnProvider.php @@ -0,0 +1,84 @@ +getCredentialsInCache(); + + if (null === $credential) { + $result = $this->request($timeout, $connectTimeout); + + if (!isset($result['Credentials']['AccessKeyId'], + $result['Credentials']['AccessKeySecret'], + $result['Credentials']['SecurityToken'])) { + throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL); + } + + $credential = $result['Credentials']; + $this->cache($credential); + } + + return new StsCredential( + $credential['AccessKeyId'], + $credential['AccessKeySecret'], + $credential['SecurityToken'] + ); + } + + /** + * Get credentials by request. + * + * @param $timeout + * @param $connectTimeout + * + * @return Result + * @throws ClientException + * @throws ServerException + */ + private function request($timeout, $connectTimeout) + { + $clientName = __CLASS__ . \uniqid('ak', true); + $credential = $this->client->getCredential(); + + AlibabaCloud::accessKeyClient( + $credential->getAccessKeyId(), + $credential->getAccessKeySecret() + )->name($clientName); + + return (new AssumeRole($credential)) + ->client($clientName) + ->timeout($timeout) + ->connectTimeout($connectTimeout) + ->debug($this->client->isDebug()) + ->request(); + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Providers/RsaKeyPairProvider.php b/vendor/alibabacloud/client/src/Credentials/Providers/RsaKeyPairProvider.php new file mode 100644 index 0000000..e78fc1c --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Providers/RsaKeyPairProvider.php @@ -0,0 +1,86 @@ +getCredentialsInCache(); + + if ($credential === null) { + $result = $this->request($timeout, $connectTimeout); + + if (!isset($result['SessionAccessKey']['SessionAccessKeyId'], + $result['SessionAccessKey']['SessionAccessKeySecret'])) { + throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL); + } + + $credential = $result['SessionAccessKey']; + $this->cache($credential); + } + + return new StsCredential( + $credential['SessionAccessKeyId'], + $credential['SessionAccessKeySecret'] + ); + } + + /** + * Get credentials by request. + * + * @param $timeout + * @param $connectTimeout + * + * @return Result + * @throws ClientException + * @throws ServerException + */ + private function request($timeout, $connectTimeout) + { + $clientName = __CLASS__ . \uniqid('rsa', true); + $credential = $this->client->getCredential(); + + AlibabaCloud::client( + new AccessKeyCredential( + $credential->getPublicKeyId(), + $credential->getPrivateKey() + ), + new ShaHmac256WithRsaSignature() + )->name($clientName); + + return (new GenerateSessionAccessKey($credential->getPublicKeyId())) + ->client($clientName) + ->timeout($timeout) + ->connectTimeout($connectTimeout) + ->debug($this->client->isDebug()) + ->request(); + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/RamRoleArnCredential.php b/vendor/alibabacloud/client/src/Credentials/RamRoleArnCredential.php new file mode 100644 index 0000000..6bdf5be --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/RamRoleArnCredential.php @@ -0,0 +1,110 @@ +accessKeyId = $accessKeyId; + $this->accessKeySecret = $accessKeySecret; + $this->roleArn = $roleArn; + $this->roleSessionName = $roleSessionName; + $this->policy = $policy; + } + + /** + * @return string + */ + public function getAccessKeyId() + { + return $this->accessKeyId; + } + + /** + * @return string + */ + public function getAccessKeySecret() + { + return $this->accessKeySecret; + } + + /** + * @return string + */ + public function getRoleArn() + { + return $this->roleArn; + } + + /** + * @return string + */ + public function getRoleSessionName() + { + return $this->roleSessionName; + } + + /** + * @return string + */ + public function getPolicy() + { + return $this->policy; + } + + /** + * @return string + */ + public function __toString() + { + return "$this->accessKeyId#$this->accessKeySecret#$this->roleArn#$this->roleSessionName"; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Requests/AssumeRole.php b/vendor/alibabacloud/client/src/Credentials/Requests/AssumeRole.php new file mode 100644 index 0000000..a3935aa --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Requests/AssumeRole.php @@ -0,0 +1,47 @@ +product('Sts'); + $this->version('2015-04-01'); + $this->action('AssumeRole'); + $this->host('sts.aliyuncs.com'); + $this->scheme('https'); + $this->regionId('cn-hangzhou'); + $this->options['verify'] = false; + $this->options['query']['RoleArn'] = $arnCredential->getRoleArn(); + $this->options['query']['RoleSessionName'] = $arnCredential->getRoleSessionName(); + $this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS; + if ($arnCredential->getPolicy()) { + if (is_array($arnCredential->getPolicy())) { + $this->options['query']['Policy'] = json_encode($arnCredential->getPolicy()); + } + if (is_string($arnCredential->getPolicy())) { + $this->options['query']['Policy'] = $arnCredential->getPolicy(); + } + } + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/Requests/GenerateSessionAccessKey.php b/vendor/alibabacloud/client/src/Credentials/Requests/GenerateSessionAccessKey.php new file mode 100644 index 0000000..4ac1ee1 --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/Requests/GenerateSessionAccessKey.php @@ -0,0 +1,37 @@ +product('Sts'); + $this->version('2015-04-01'); + $this->action('GenerateSessionAccessKey'); + $this->host('sts.ap-northeast-1.aliyuncs.com'); + $this->scheme('https'); + $this->regionId('cn-hangzhou'); + $this->options['verify'] = false; + $this->options['query']['PublicKeyId'] = $publicKeyId; + $this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/RsaKeyPairCredential.php b/vendor/alibabacloud/client/src/Credentials/RsaKeyPairCredential.php new file mode 100644 index 0000000..876909e --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/RsaKeyPairCredential.php @@ -0,0 +1,75 @@ +publicKeyId = $publicKeyId; + try { + $this->privateKey = file_get_contents($privateKeyFile); + } catch (Exception $exception) { + throw new ClientException( + $exception->getMessage(), + SDK::INVALID_CREDENTIAL + ); + } + } + + /** + * @return mixed + */ + public function getPrivateKey() + { + return $this->privateKey; + } + + /** + * @return string + */ + public function getPublicKeyId() + { + return $this->publicKeyId; + } + + /** + * @return string + */ + public function __toString() + { + return "publicKeyId#$this->publicKeyId"; + } +} diff --git a/vendor/alibabacloud/client/src/Credentials/StsCredential.php b/vendor/alibabacloud/client/src/Credentials/StsCredential.php new file mode 100644 index 0000000..d333fa8 --- /dev/null +++ b/vendor/alibabacloud/client/src/Credentials/StsCredential.php @@ -0,0 +1,80 @@ +accessKeyId = $accessKeyId; + $this->accessKeySecret = $accessKeySecret; + $this->securityToken = $securityToken; + } + + /** + * @return string + */ + public function getAccessKeyId() + { + return $this->accessKeyId; + } + + /** + * @return string + */ + public function getAccessKeySecret() + { + return $this->accessKeySecret; + } + + /** + * @return string + */ + public function getSecurityToken() + { + return $this->securityToken; + } + + /** + * @return string + */ + public function __toString() + { + return "$this->accessKeyId#$this->accessKeySecret#$this->securityToken"; + } +} diff --git a/vendor/alibabacloud/client/src/DefaultAcsClient.php b/vendor/alibabacloud/client/src/DefaultAcsClient.php new file mode 100644 index 0000000..ff5ecd7 --- /dev/null +++ b/vendor/alibabacloud/client/src/DefaultAcsClient.php @@ -0,0 +1,55 @@ +randClientName = \uniqid('', true); + $client->name($this->randClientName); + } + + /** + * @param Request|Result $request + * + * @return Result|string + * @throws ClientException + * @throws ServerException + */ + public function getAcsResponse($request) + { + if ($request instanceof Result) { + return $request; + } + + return $request->client($this->randClientName)->request(); + } +} diff --git a/vendor/alibabacloud/client/src/Encode.php b/vendor/alibabacloud/client/src/Encode.php new file mode 100644 index 0000000..203ceb4 --- /dev/null +++ b/vendor/alibabacloud/client/src/Encode.php @@ -0,0 +1,68 @@ +data = $data; + } + + /** + * @return bool|string + */ + public function toString() + { + $string = ''; + foreach ($this->data as $key => $value) { + $encode = rawurlencode($value); + if ($encode === '') { + $string .= "$key&"; + } else { + $string .= "$key=$encode&"; + } + } + + if (0 < count($this->data)) { + $string = substr($string, 0, -1); + } + + return $string; + } + + /** + * @return $this + */ + public function ksort() + { + ksort($this->data); + + return $this; + } +} diff --git a/vendor/alibabacloud/client/src/Exception/AlibabaCloudException.php b/vendor/alibabacloud/client/src/Exception/AlibabaCloudException.php new file mode 100644 index 0000000..cee21d8 --- /dev/null +++ b/vendor/alibabacloud/client/src/Exception/AlibabaCloudException.php @@ -0,0 +1,70 @@ +errorCode; + } + + /** + * @codeCoverageIgnore + * @deprecated + */ + public function setErrorCode() + { + throw new RuntimeException('deprecated since 2.0.'); + } + + /** + * @return string + */ + public function getErrorMessage() + { + return $this->errorMessage; + } + + /** + * @codeCoverageIgnore + * + * @param $errorMessage + * + * @deprecated + */ + public function setErrorMessage($errorMessage) + { + $this->errorMessage = $errorMessage; + } + + /** + * @codeCoverageIgnore + * @deprecated + */ + public function setErrorType() + { + } +} diff --git a/vendor/alibabacloud/client/src/Exception/ClientException.php b/vendor/alibabacloud/client/src/Exception/ClientException.php new file mode 100644 index 0000000..0877e87 --- /dev/null +++ b/vendor/alibabacloud/client/src/Exception/ClientException.php @@ -0,0 +1,38 @@ +errorMessage = $errorMessage; + $this->errorCode = $errorCode; + } + + /** + * @codeCoverageIgnore + * @deprecated + */ + public function getErrorType() + { + return 'Client'; + } +} diff --git a/vendor/alibabacloud/client/src/Exception/ServerException.php b/vendor/alibabacloud/client/src/Exception/ServerException.php new file mode 100644 index 0000000..4be26e8 --- /dev/null +++ b/vendor/alibabacloud/client/src/Exception/ServerException.php @@ -0,0 +1,158 @@ +result = $result; + $this->errorMessage = $errorMessage; + $this->errorCode = $errorCode; + $this->resolvePropertiesByReturn(); + $this->distinguishSignatureErrors(); + $this->bodyAsErrorMessage(); + + parent::__construct( + $this->getMessageString(), + $this->result->getStatusCode() + ); + } + + /** + * Resolve the error message based on the return of the server. + * + * @return void + */ + private function resolvePropertiesByReturn() + { + if (isset($this->result['message'])) { + $this->errorMessage = $this->result['message']; + $this->errorCode = $this->result['code']; + } + if (isset($this->result['Message'])) { + $this->errorMessage = $this->result['Message']; + $this->errorCode = $this->result['Code']; + } + if (isset($this->result['errorMsg'])) { + $this->errorMessage = $this->result['errorMsg']; + $this->errorCode = $this->result['errorCode']; + } + if (isset($this->result['requestId'])) { + $this->requestId = $this->result['requestId']; + } + if (isset($this->result['RequestId'])) { + $this->requestId = $this->result['RequestId']; + } + } + + /** + * If the string to be signed are the same with server's, it is considered a credential error. + */ + private function distinguishSignatureErrors() + { + if ($this->result->getRequest() + && Stringy::contains($this->errorMessage, $this->result->getRequest()->stringToSign())) { + $this->errorCode = 'InvalidAccessKeySecret'; + $this->errorMessage = 'Specified Access Key Secret is not valid.'; + } + } + + /** + * If the error message matches the default message and + * the server has returned content, use the return content + */ + private function bodyAsErrorMessage() + { + $body = (string)$this->result->getBody(); + if ($this->errorMessage === SDK::RESPONSE_EMPTY && $body) { + $this->errorMessage = $body; + } + } + + /** + * Get standard exception message. + * + * @return string + */ + private function getMessageString() + { + $message = "$this->errorCode: $this->errorMessage RequestId: $this->requestId"; + + if ($this->getResult()->getRequest()) { + $method = $this->getResult()->getRequest()->method; + $uri = (string)$this->getResult()->getRequest()->uri; + $message .= " $method \"$uri\""; + if ($this->result) { + $message .= ' ' . $this->result->getStatusCode(); + } + } + + return $message; + } + + /** + * @return Result + */ + public function getResult() + { + return $this->result; + } + + /** + * @return string + */ + public function getRequestId() + { + return $this->requestId; + } + + /** + * @codeCoverageIgnore + * @deprecated + */ + public function getErrorType() + { + return 'Server'; + } + + /** + * @codeCoverageIgnore + * @deprecated + */ + public function getHttpStatus() + { + return $this->getResult()->getStatusCode(); + } +} diff --git a/vendor/alibabacloud/client/src/Filter/ApiFilter.php b/vendor/alibabacloud/client/src/Filter/ApiFilter.php new file mode 100644 index 0000000..f6d26f2 --- /dev/null +++ b/vendor/alibabacloud/client/src/Filter/ApiFilter.php @@ -0,0 +1,259 @@ +br(); + if ($flank !== null) { + cliMate()->backgroundRed()->flank($flank, $char, $length); + cliMate()->br(); + } + cliMate()->backgroundRed($string); + cliMate()->br(); +} + +/** + * @param string $string + * @param string|null $flank + * @param string|null $char + * @param int|null $length + * + * @return void + */ +function backgroundGreen($string, $flank = null, $char = null, $length = null) +{ + cliMate()->br(); + if ($flank !== null) { + cliMate()->backgroundGreen()->flank($flank, $char, $length); + } + cliMate()->backgroundGreen($string); + cliMate()->br(); +} + +/** + * @param string $string + * @param string|null $flank + * @param string|null $char + * @param int|null $length + * + * @return void + */ +function backgroundBlue($string, $flank = null, $char = null, $length = null) +{ + cliMate()->br(); + if ($flank !== null) { + cliMate()->backgroundBlue()->flank($flank, $char, $length); + } + cliMate()->backgroundBlue($string); + cliMate()->br(); +} + +/** + * @param string $string + * @param string|null $flank + * @param string|null $char + * @param int|null $length + * + * @return void + */ +function backgroundMagenta($string, $flank = null, $char = null, $length = null) +{ + cliMate()->br(); + if ($flank !== null) { + cliMate()->backgroundMagenta()->flank($flank, $char, $length); + } + cliMate()->backgroundMagenta($string); + cliMate()->br(); +} + +/** + * @param array $array + */ +function json(array $array) +{ + cliMate()->br(); + cliMate()->backgroundGreen()->json($array); + cliMate()->br(); +} + +/** + * @param array $array + * + * @return void + */ +function redTable($array) +{ + /** + * @noinspection PhpUndefinedMethodInspection + */ + cliMate()->redTable($array); +} + +/** + * @param mixed $result + * @param string $title + * + * @return void + */ +function block($result, $title) +{ + cliMate()->backgroundGreen()->flank($title, '--', 20); + dump($result); +} + +/** + * Gets the value of an environment variable. + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ +function env($key, $default = null) +{ + $value = getenv($key); + + if ($value === false) { + return value($default); + } + + if (envSubstr($value)) { + return substr($value, 1, -1); + } + + return envConversion($value); +} + +/** + * @param $value + * + * @return bool|string|null + */ +function envConversion($value) +{ + $key = strtolower($value); + + if ($key === 'null' || $key === '(null)') { + return null; + } + + $list = [ + 'true' => true, + '(true)' => true, + 'false' => false, + '(false)' => false, + 'empty' => '', + '(empty)' => '', + ]; + + return isset($list[$key]) ? $list[$key] : $value; +} + +/** + * @param $key + * + * @return bool|mixed + * @throws ClientException + */ +function envNotEmpty($key) +{ + $value = env($key, false); + if ($value !== false && !$value) { + throw new ClientException( + "Environment variable '$key' cannot be empty", + SDK::INVALID_ARGUMENT + ); + } + if ($value) { + return $value; + } + + return false; +} + +/** + * @param $value + * + * @return bool + */ +function envSubstr($value) +{ + return ($valueLength = strlen($value)) > 1 && strpos($value, '"') === 0 && $value[$valueLength - 1] === '"'; +} + +/** + * Return the default value of the given value. + * + * @param mixed $value + * + * @return mixed + */ +function value($value) +{ + return $value instanceof Closure ? $value() : $value; +} diff --git a/vendor/alibabacloud/client/src/Log/LogFormatter.php b/vendor/alibabacloud/client/src/Log/LogFormatter.php new file mode 100644 index 0000000..a33185b --- /dev/null +++ b/vendor/alibabacloud/client/src/Log/LogFormatter.php @@ -0,0 +1,79 @@ +template = $template; + $timezone = new DateTimeZone(date_default_timezone_get() ?: 'UTC'); + if (PHP_VERSION_ID < 70100) { + self::$ts = DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), $timezone); + } else { + self::$ts = new DateTime('now', $timezone); + } + } + + /** + * Returns a formatted message string. + * + * @param RequestInterface $request Request that was sent + * @param ResponseInterface $response Response that was received + * @param Exception $error Exception that was received + * + * @return string + */ + public function format( + RequestInterface $request, + ResponseInterface $response = null, + Exception $error = null + ) { + $this->template = str_replace('{pid}', getmypid(), $this->template); + $this->template = str_replace('{cost}', self::getCost(), $this->template); + $this->template = str_replace('{start_time}', self::$ts->format('Y-m-d H:i:s.u'), $this->template); + + return (new MessageFormatter($this->template))->format($request, $response, $error); + } + + /** + * @return float|mixed + */ + private static function getCost() + { + return microtime(true) - self::$logStartTime; + } +} diff --git a/vendor/alibabacloud/client/src/Profile/DefaultProfile.php b/vendor/alibabacloud/client/src/Profile/DefaultProfile.php new file mode 100644 index 0000000..b1b3707 --- /dev/null +++ b/vendor/alibabacloud/client/src/Profile/DefaultProfile.php @@ -0,0 +1,74 @@ +regionId($regionId); + } + + /** + * @param string $regionId + * @param string $accessKeyId + * @param string $accessKeySecret + * @param string $roleArn + * @param string $roleSessionName + * + * @return Client + * @throws ClientException + */ + public static function getRamRoleArnProfile($regionId, $accessKeyId, $accessKeySecret, $roleArn, $roleSessionName) + { + return AlibabaCloud::ramRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName) + ->regionId($regionId); + } + + /** + * @param string $regionId + * @param string $roleName + * + * @return Client + * @throws ClientException + */ + public static function getEcsRamRoleProfile($regionId, $roleName) + { + return AlibabaCloud::ecsRamRoleClient($roleName) + ->regionId($regionId); + } + + /** + * @param string $regionId + * @param string $bearerToken + * + * @return Client + * @throws ClientException + */ + public static function getBearerTokenProfile($regionId, $bearerToken) + { + return AlibabaCloud::bearerTokenClient($bearerToken) + ->regionId($regionId); + } +} diff --git a/vendor/alibabacloud/client/src/Regions/EndpointProvider.php b/vendor/alibabacloud/client/src/Regions/EndpointProvider.php new file mode 100644 index 0000000..5e8e555 --- /dev/null +++ b/vendor/alibabacloud/client/src/Regions/EndpointProvider.php @@ -0,0 +1,18 @@ +request = $request; + } + + /** + * @param Request $request + * @param string $domain + * + * @return string + * @throws ClientException + * @throws ServerException + * @deprecated + * @codeCoverageIgnore + */ + public static function findProductDomain(Request $request, $domain = 'location.aliyuncs.com') + { + return self::resolveHost($request, $domain); + } + + /** + * @param $regionId + * @param $product + * @param $domain + * + * @throws ClientException + * @deprecated + * @codeCoverageIgnore + */ + public static function addEndPoint($regionId, $product, $domain) + { + self::addHost($product, $domain, $regionId); + } + + + /** + * @param Request $request + * @param string $domain + * + * @return string + * @throws ClientException + * @throws ServerException + */ + public static function resolveHost(Request $request, $domain = 'location.aliyuncs.com') + { + $locationService = new static($request); + $product = $locationService->request->product; + $regionId = $locationService->request->realRegionId(); + + if (!isset(self::$hosts[$product][$regionId])) { + self::$hosts[$product][$regionId] = self::getResult($locationService, $domain); + } + + return self::$hosts[$product][$regionId]; + } + + /** + * @param static $locationService + * @param string $domain + * + * @return string + * @throws ClientException + * @throws ServerException + */ + private static function getResult($locationService, $domain) + { + $locationRequest = new LocationServiceRequest($locationService->request, $domain); + + $result = $locationRequest->request(); + + if (!isset($result['Endpoints']['Endpoint'][0]['Endpoint'])) { + throw new ClientException( + 'Not found Region ID in ' . $domain, + SDK::INVALID_REGION_ID + ); + } + + return $result['Endpoints']['Endpoint'][0]['Endpoint']; + } + + /** + * @param string $product + * @param string $host + * @param string $regionId + * + * @throws ClientException + */ + public static function addHost($product, $host, $regionId = self::GLOBAL_REGION) + { + ApiFilter::product($product); + + HttpFilter::host($host); + + ClientFilter::regionId($regionId); + + self::$hosts[$product][$regionId] = $host; + } + + /** + * Update endpoints from OSS. + * + * @codeCoverageIgnore + * @throws Exception + */ + public static function updateEndpoints() + { + $ossUrl = 'https://openapi-endpoints.oss-cn-hangzhou.aliyuncs.com/endpoints.json'; + $json = \file_get_contents($ossUrl); + $list = \json_decode($json, true); + + foreach ($list['endpoints'] as $endpoint) { + Config::set( + "endpoints.{$endpoint['service']}.{$endpoint['regionid']}", + \strtolower($endpoint['endpoint']) + ); + } + } +} diff --git a/vendor/alibabacloud/client/src/Regions/LocationServiceRequest.php b/vendor/alibabacloud/client/src/Regions/LocationServiceRequest.php new file mode 100644 index 0000000..94a267d --- /dev/null +++ b/vendor/alibabacloud/client/src/Regions/LocationServiceRequest.php @@ -0,0 +1,46 @@ +product('Location'); + $this->version('2015-06-12'); + $this->action('DescribeEndpoints'); + $this->regionId('cn-hangzhou'); + $this->format('JSON'); + $this->options['query']['Id'] = $request->realRegionId(); + $this->options['query']['ServiceCode'] = $request->serviceCode; + $this->options['query']['Type'] = $request->endpointType; + $this->client($request->client); + $this->host($domain); + if (isset($request->options['timeout'])) { + $this->timeout($request->options['timeout']); + } + + if (isset($request->options['connect_timeout'])) { + $this->connectTimeout($request->options['connect_timeout']); + } + } +} diff --git a/vendor/alibabacloud/client/src/Release.php b/vendor/alibabacloud/client/src/Release.php new file mode 100644 index 0000000..0be9c1b --- /dev/null +++ b/vendor/alibabacloud/client/src/Release.php @@ -0,0 +1,112 @@ +getArguments(); + if (count($arguments) <= 1) { + echo 'Missing ChangeLog'; + + return; + } + self::updateChangelogFile($arguments[0], $arguments[1]); + self::changeVersionInCode($arguments[0]); + } + + /** + * @param $version + * @param $changeLog + */ + private static function updateChangelogFile($version, $changeLog) + { + $content = preg_replace( + '/# CHANGELOG/', + '# CHANGELOG' + . "\n" + . "\n" + . "## $version - " . date('Y-m-d') + . self::log($changeLog), + self::getChangeLogContent() + ); + + file_put_contents(self::getChangeLogFile(), $content); + } + + /** + * @param $changeLog + * + * @return string + */ + private static function log($changeLog) + { + $logs = explode('|', $changeLog); + $string = "\n"; + foreach ($logs as $log) { + if ($log) { + $string .= "- $log." . "\n"; + } + } + + return $string; + } + + /** + * @return string + */ + private static function getChangeLogContent() + { + return file_get_contents(self::getChangeLogFile()); + } + + /** + * @return string + */ + private static function getChangeLogFile() + { + return __DIR__ . '/../CHANGELOG.md'; + } + + /** + * @param $version + */ + private static function changeVersionInCode($version) + { + $content = preg_replace( + "/const VERSION = \'(.*)\';/", + "const VERSION = '" . $version . "';", + self::getCodeContent() + ); + + file_put_contents(self::getCodeFile(), $content); + } + + /** + * @return string + */ + private static function getCodeContent() + { + return file_get_contents(self::getCodeFile()); + } + + /** + * @return string + */ + private static function getCodeFile() + { + return __DIR__ . '/AlibabaCloud.php'; + } +} diff --git a/vendor/alibabacloud/client/src/Request/Request.php b/vendor/alibabacloud/client/src/Request/Request.php new file mode 100644 index 0000000..e18532e --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/Request.php @@ -0,0 +1,451 @@ +client = CredentialsProvider::getDefaultName(); + $this->uri = new Uri(); + $this->uri = $this->uri->withScheme($this->scheme); + $this->options['http_errors'] = false; + $this->options['connect_timeout'] = self::CONNECT_TIMEOUT; + $this->options['timeout'] = self::TIMEOUT; + + // Turn on debug mode based on environment variable. + if (null !== \AlibabaCloud\Client\env('DEBUG') && strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') { + $this->options['debug'] = true; + } + + // Rewrite configuration if the user has a configuration. + if ($options !== []) { + $this->options($options); + } + } + + /** + * @param string $name + * @param string $value + * + * @return $this + * @throws ClientException + */ + public function appendUserAgent($name, $value) + { + $filter_name = Filter::name($name); + + if (!UserAgent::isGuarded($filter_name)) { + $this->userAgent[$filter_name] = Filter::value($value); + } + + return $this; + } + + /** + * @param array $userAgent + * + * @return $this + */ + public function withUserAgent(array $userAgent) + { + $this->userAgent = UserAgent::clean($userAgent); + + return $this; + } + + /** + * Set Accept format. + * + * @param string $format + * + * @return $this + * @throws ClientException + */ + public function format($format) + { + $this->format = ApiFilter::format($format); + + return $this; + } + + /** + * @param $contentType + * + * @return $this + * @throws ClientException + */ + public function contentType($contentType) + { + $this->options['headers']['Content-Type'] = HttpFilter::contentType($contentType); + + return $this; + } + + /** + * @param string $accept + * + * @return $this + * @throws ClientException + */ + public function accept($accept) + { + $this->options['headers']['Accept'] = HttpFilter::accept($accept); + + return $this; + } + + /** + * Set the request body. + * + * @param string $body + * + * @return $this + * @throws ClientException + */ + public function body($body) + { + $this->options['body'] = HttpFilter::body($body); + + return $this; + } + + /** + * Set the json as body. + * + * @param array|object $content + * + * @return $this + * @throws ClientException + */ + public function jsonBody($content) + { + if (!\is_array($content) && !\is_object($content)) { + throw new ClientException( + 'jsonBody only accepts an array or object', + SDK::INVALID_ARGUMENT + ); + } + + return $this->body(\json_encode($content)); + } + + /** + * Set the request scheme. + * + * @param string $scheme + * + * @return $this + * @throws ClientException + */ + public function scheme($scheme) + { + $this->scheme = HttpFilter::scheme($scheme); + $this->uri = $this->uri->withScheme($scheme); + + return $this; + } + + /** + * Set the request host. + * + * @param string $host + * + * @return $this + * @throws ClientException + */ + public function host($host) + { + $this->uri = $this->uri->withHost(HttpFilter::host($host)); + + return $this; + } + + /** + * @param string $method + * + * @return $this + * @throws ClientException + */ + public function method($method) + { + $this->method = HttpFilter::method($method); + + return $this; + } + + /** + * @param string $clientName + * + * @return $this + * @throws ClientException + */ + public function client($clientName) + { + $this->client = ClientFilter::clientName($clientName); + + return $this; + } + + /** + * @return bool + * @throws ClientException + */ + public function isDebug() + { + if (isset($this->options['debug'])) { + return $this->options['debug'] === true; + } + + if (isset($this->httpClient()->options['debug'])) { + return $this->httpClient()->options['debug'] === true; + } + + return false; + } + + /** + * @throws ClientException + * @throws ServerException + */ + public function resolveOption() + { + $this->options['headers']['User-Agent'] = UserAgent::toString($this->userAgent); + + $this->cleanQuery(); + $this->cleanFormParams(); + $this->resolveHost(); + $this->resolveParameter(); + + if (isset($this->options['form_params'])) { + if (function_exists('\GuzzleHttp\Psr7\parse_query')) { + $this->options['form_params'] = \GuzzleHttp\Psr7\parse_query( + Encode::create($this->options['form_params'])->toString() + ); + } else { + $this->options['form_params'] = \GuzzleHttp\Psr7\Query::parse( + Encode::create($this->options['form_params'])->toString() + ); + } + } + + $this->mergeOptionsIntoClient(); + } + + /** + * @return Result + * @throws ClientException + * @throws ServerException + */ + public function request() + { + $this->resolveOption(); + $result = $this->response(); + + if ($this->shouldServerRetry($result)) { + return $this->request(); + } + + if (!$result->isSuccess()) { + throw new ServerException($result); + } + + return $result; + } + + /*** + * @return PromiseInterface + * @throws Exception + */ + public function requestAsync() + { + $this->resolveOption(); + + return self::createClient($this)->requestAsync( + $this->method, + (string)$this->uri, + $this->options + ); + } + + /** + * @param Request $request + * + * @return Client + * @throws Exception + */ + public static function createClient(Request $request = null) + { + if (AlibabaCloud::hasMock()) { + $stack = HandlerStack::create(AlibabaCloud::getMock()); + } else { + $stack = HandlerStack::create(); + } + + if (AlibabaCloud::isRememberHistory()) { + $stack->push(Middleware::history(AlibabaCloud::referenceHistory())); + } + + if (AlibabaCloud::getLogger()) { + $stack->push(Middleware::log( + AlibabaCloud::getLogger(), + new MessageFormatter(AlibabaCloud::getLogFormat()) + )); + } + + $stack->push(Middleware::mapResponse(static function (ResponseInterface $response) use ($request) { + return new Result($response, $request); + })); + + self::$config['handler'] = $stack; + + return new Client(self::$config); + } + + /** + * @throws ClientException + * @throws Exception + */ + private function response() + { + try { + return self::createClient($this)->request( + $this->method, + (string)$this->uri, + $this->options + ); + } catch (GuzzleException $exception) { + if ($this->shouldClientRetry($exception)) { + return $this->response(); + } + throw new ClientException( + $exception->getMessage(), + SDK::SERVER_UNREACHABLE, + $exception + ); + } + } + + /** + * Remove redundant Query + * + * @codeCoverageIgnore + */ + private function cleanQuery() + { + if (isset($this->options['query']) && $this->options['query'] === []) { + unset($this->options['query']); + } + } + + /** + * Remove redundant Headers + * + * @codeCoverageIgnore + */ + private function cleanFormParams() + { + if (isset($this->options['form_params']) && $this->options['form_params'] === []) { + unset($this->options['form_params']); + } + } +} diff --git a/vendor/alibabacloud/client/src/Request/RoaRequest.php b/vendor/alibabacloud/client/src/Request/RoaRequest.php new file mode 100644 index 0000000..2993f14 --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/RoaRequest.php @@ -0,0 +1,333 @@ +resolveQuery(); + $this->resolveHeaders(); + $this->resolveBody(); + $this->resolveUri(); + $this->resolveSignature(); + } + + private function resolveQuery() + { + if (!isset($this->options['query']['Version'])) { + $this->options['query']['Version'] = $this->version; + } + } + + private function resolveBody() + { + // If the body has already been specified, it will not be resolved. + if (isset($this->options['body'])) { + return; + } + + if (!isset($this->options['form_params'])) { + return; + } + + // Merge data, compatible with parameters set from constructor. + $params = Arrays::merge( + [ + $this->data, + $this->options['form_params'] + ] + ); + + $this->encodeBody($params); + + unset($this->options['form_params']); + } + + /** + * Determine the body format based on the Content-Type and calculate the MD5 value. + * + * @param array $params + */ + private function encodeBody(array $params) + { + if (Stringy::contains($this->options['headers']['Content-Type'], 'application/json', false)) { + $this->options['body'] = json_encode($params); + $this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true)); + + return; + } + + $this->options['body'] = Encode::create($params)->ksort()->toString(); + $this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true)); + $this->options['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; + } + + /** + * @throws ClientException + * @throws ServerException + * @throws Exception + */ + private function resolveHeaders() + { + $this->options['headers']['x-acs-version'] = $this->version; + $this->options['headers']['x-acs-region-id'] = $this->realRegionId(); + $this->options['headers']['Date'] = gmdate($this->dateTimeFormat); + + $signature = $this->httpClient()->getSignature(); + $this->options['headers']['x-acs-signature-method'] = $signature->getMethod(); + $this->options['headers']['x-acs-signature-nonce'] = Sign::uuid($this->product . $this->action); + $this->options['headers']['x-acs-signature-version'] = $signature->getVersion(); + if ($signature->getType()) { + $this->options['headers']['x-acs-signature-type'] = $signature->getType(); + } + + $this->resolveAccept(); + $this->resolveContentType(); + $this->resolveSecurityToken(); + $this->resolveBearerToken(); + } + + /** + * @throws ClientException + * @throws Exception + */ + private function resolveSignature() + { + $this->options['headers']['Authorization'] = $this->signature(); + } + + /** + * If accept is not specified, it is determined by format. + */ + private function resolveAccept() + { + if (!isset($this->options['headers']['Accept'])) { + $this->options['headers']['Accept'] = Accept::create($this->format)->toString(); + } + } + + /** + * If the Content-Type is not specified, it is determined according to accept. + */ + private function resolveContentType() + { + if (!isset($this->options['headers']['Content-Type'])) { + $this->options['headers']['Content-Type'] = "{$this->options['headers']['Accept']}; charset=utf-8"; + } + } + + /** + * @throws ClientException + * @throws ServerException + */ + private function resolveSecurityToken() + { + if (!$this->credential() instanceof StsCredential) { + return; + } + + if (!$this->credential()->getSecurityToken()) { + return; + } + + $this->options['headers']['x-acs-security-token'] = $this->credential()->getSecurityToken(); + } + + /** + * @throws ClientException + * @throws ServerException + */ + private function resolveBearerToken() + { + if ($this->credential() instanceof BearerTokenCredential) { + $this->options['headers']['x-acs-bearer-token'] = $this->credential()->getBearerToken(); + } + } + + /** + * Sign the request message. + * + * @return string + * @throws ClientException + * @throws ServerException + */ + private function signature() + { + /** + * @var AccessKeyCredential $credential + */ + $credential = $this->credential(); + $access_key_id = $credential->getAccessKeyId(); + $signature = $this->httpClient() + ->getSignature() + ->sign( + $this->stringToSign(), + $credential->getAccessKeySecret() + ); + + return "acs $access_key_id:$signature"; + } + + /** + * @return void + */ + private function resolveUri() + { + $path = Path::assign($this->pathPattern, $this->pathParameters); + + $this->uri = $this->uri->withPath($path) + ->withQuery( + $this->queryString() + ); + } + + /** + * @return string + */ + public function stringToSign() + { + $request = new \GuzzleHttp\Psr7\Request( + $this->method, + $this->uri, + $this->options['headers'] + ); + + return Sign::roaString($request); + } + + /** + * @return bool|string + */ + private function queryString() + { + $query = isset($this->options['query']) + ? $this->options['query'] + : []; + + return Encode::create($query)->ksort()->toString(); + } + + /** + * Set path parameter by name. + * + * @param string $name + * @param string $value + * + * @return RoaRequest + * @throws ClientException + */ + public function pathParameter($name, $value) + { + Filter::name($name); + + if ($value === '') { + throw new ClientException( + 'Value cannot be empty', + SDK::INVALID_ARGUMENT + ); + } + + $this->pathParameters[$name] = $value; + + return $this; + } + + /** + * Set path pattern. + * + * @param string $pattern + * + * @return self + * @throws ClientException + */ + public function pathPattern($pattern) + { + ApiFilter::pattern($pattern); + + $this->pathPattern = $pattern; + + return $this; + } + + /** + * Magic method for set or get request parameters. + * + * @param string $name + * @param mixed $arguments + * + * @return $this + */ + public function __call($name, $arguments) + { + if (strncmp($name, 'get', 3) === 0) { + $parameter_name = \mb_strcut($name, 3); + + return $this->__get($parameter_name); + } + + if (strncmp($name, 'with', 4) === 0) { + $parameter_name = \mb_strcut($name, 4); + $this->__set($parameter_name, $arguments[0]); + $this->pathParameters[$parameter_name] = $arguments[0]; + + return $this; + } + + if (strncmp($name, 'set', 3) === 0) { + $parameter_name = \mb_strcut($name, 3); + $with_method = "with$parameter_name"; + + throw new RuntimeException("Please use $with_method instead of $name"); + } + + throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()'); + } +} diff --git a/vendor/alibabacloud/client/src/Request/RpcRequest.php b/vendor/alibabacloud/client/src/Request/RpcRequest.php new file mode 100644 index 0000000..389c949 --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/RpcRequest.php @@ -0,0 +1,203 @@ +resolveBoolInParameters(); + $this->resolveCommonParameters(); + $this->repositionParameters(); + } + + /** + * Convert a Boolean value to a string + */ + private function resolveBoolInParameters() + { + if (isset($this->options['query'])) { + $this->options['query'] = array_map( + static function ($value) { + return self::boolToString($value); + }, + $this->options['query'] + ); + } + } + + /** + * Convert a Boolean value to a string. + * + * @param bool|string $value + * + * @return string + */ + public static function boolToString($value) + { + if (is_bool($value)) { + return $value ? 'true' : 'false'; + } + + return $value; + } + + /** + * Resolve Common Parameters. + * + * @throws ClientException + * @throws Exception + */ + private function resolveCommonParameters() + { + $signature = $this->httpClient()->getSignature(); + $this->options['query']['RegionId'] = $this->realRegionId(); + $this->options['query']['Format'] = $this->format; + $this->options['query']['SignatureMethod'] = $signature->getMethod(); + $this->options['query']['SignatureVersion'] = $signature->getVersion(); + $this->options['query']['SignatureNonce'] = Sign::uuid($this->product . $this->action); + $this->options['query']['Timestamp'] = gmdate($this->dateTimeFormat); + $this->options['query']['Action'] = $this->action; + if ($this->credential()->getAccessKeyId()) { + $this->options['query']['AccessKeyId'] = $this->credential()->getAccessKeyId(); + } + if ($signature->getType()) { + $this->options['query']['SignatureType'] = $signature->getType(); + } + if (!isset($this->options['query']['Version'])) { + $this->options['query']['Version'] = $this->version; + } + $this->resolveSecurityToken(); + $this->resolveBearerToken(); + $this->options['query']['Signature'] = $this->signature(); + } + + /** + * @throws ClientException + * @throws ServerException + */ + private function resolveSecurityToken() + { + if (!$this->credential() instanceof StsCredential) { + return; + } + + if (!$this->credential()->getSecurityToken()) { + return; + } + + $this->options['query']['SecurityToken'] = $this->credential()->getSecurityToken(); + } + + /** + * @throws ClientException + * @throws ServerException + */ + private function resolveBearerToken() + { + if ($this->credential() instanceof BearerTokenCredential) { + $this->options['query']['BearerToken'] = $this->credential()->getBearerToken(); + } + } + + /** + * Sign the parameters. + * + * @return mixed + * @throws ClientException + * @throws ServerException + */ + private function signature() + { + return $this->httpClient() + ->getSignature() + ->sign( + $this->stringToSign(), + $this->credential()->getAccessKeySecret() . '&' + ); + } + + /** + * @return string + */ + public function stringToSign() + { + $query = isset($this->options['query']) ? $this->options['query'] : []; + $form_params = isset($this->options['form_params']) ? $this->options['form_params'] : []; + $parameters = Arrays::merge([$query, $form_params]); + + return Sign::rpcString($this->method, $parameters); + } + + /** + * Adjust parameter position + */ + private function repositionParameters() + { + if ($this->method === 'POST' || $this->method === 'PUT') { + foreach ($this->options['query'] as $api_key => $api_value) { + $this->options['form_params'][$api_key] = $api_value; + } + unset($this->options['query']); + } + } + + /** + * Magic method for set or get request parameters. + * + * @param string $name + * @param mixed $arguments + * + * @return $this + */ + public function __call($name, $arguments) + { + if (strncmp($name, 'get', 3) === 0) { + $parameter_name = \mb_strcut($name, 3); + + return $this->__get($parameter_name); + } + + if (strncmp($name, 'with', 4) === 0) { + $parameter_name = \mb_strcut($name, 4); + $this->__set($parameter_name, $arguments[0]); + $this->options['query'][$parameter_name] = $arguments[0]; + + return $this; + } + + if (strncmp($name, 'set', 3) === 0) { + $parameter_name = \mb_strcut($name, 3); + $with_method = "with$parameter_name"; + + throw new RuntimeException("Please use $with_method instead of $name"); + } + + throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()'); + } +} diff --git a/vendor/alibabacloud/client/src/Request/Traits/AcsTrait.php b/vendor/alibabacloud/client/src/Request/Traits/AcsTrait.php new file mode 100644 index 0000000..5b2dd6b --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/Traits/AcsTrait.php @@ -0,0 +1,259 @@ +action = ApiFilter::action($action); + + return $this; + } + + /** + * @codeCoverageIgnore + * + * @param string $endpointSuffix + * + * @return AcsTrait + * @throws ClientException + */ + public function endpointSuffix($endpointSuffix) + { + $this->endpointSuffix = ApiFilter::endpointSuffix($endpointSuffix); + + return $this; + } + + /** + * @param string $network + */ + public function network($network) + { + $this->network = ApiFilter::network($network); + + return $this; + } + + /** + * @param string $version + * + * @return $this + * @throws ClientException + */ + public function version($version) + { + $this->version = ApiFilter::version($version); + + return $this; + } + + /** + * @param string $product + * + * @return $this + * @throws ClientException + */ + public function product($product) + { + $this->product = ApiFilter::product($product); + + return $this; + } + + /** + * @param string $endpointType + * + * @return $this + * @throws ClientException + */ + public function endpointType($endpointType) + { + $this->endpointType = ApiFilter::endpointType($endpointType); + + return $this; + } + + /** + * @param string $serviceCode + * + * @return $this + * @throws ClientException + */ + public function serviceCode($serviceCode) + { + $this->serviceCode = ApiFilter::serviceCode($serviceCode); + + return $this; + } + + /** + * Resolve Host. + * + * @throws ClientException + * @throws ServerException + */ + public function resolveHost() + { + // Return if specified + if ($this->uri->getHost() !== 'localhost') { + return; + } + + $region_id = $this->realRegionId(); + $host = ''; + + $this->resolveHostWays($host, $region_id); + + if (!$host) { + throw new ClientException( + "No host found for {$this->product} in the {$region_id}, you can specify host by host() method. " . + 'Like $request->host(\'xxx.xxx.aliyuncs.com\')', + SDK::HOST_NOT_FOUND + ); + } + + $this->uri = $this->uri->withHost($host); + } + + /** + * @param string $host + * @param string $region_id + * + * @throws ClientException + * @throws ServerException + */ + private function resolveHostWays(&$host, $region_id) + { + $host = AlibabaCloud::resolveHostByStatic($this->product, $region_id); + + // 1. Find host by map. + if (!$host && $this->network === 'public' && isset($this->endpointMap[$region_id])) { + $host = $this->endpointMap[$region_id]; + } + + if (!$host) { + $this->hostResolver($host, $region_id); + } + } + + /** + * @codeCoverageIgnore + * + * @param string $host + * @param string $region_id + * + * @throws ClientException + * @throws ServerException + */ + private function hostResolver(&$host, $region_id) + { + // 2. Find host by rules. + if ($this->endpointRegional !== null) { + $host = AlibabaCloud::resolveHostByRule($this); + } + + // 3. Find in the local array file. + if (!$host) { + $host = AlibabaCloud::resolveHost($this->product, $region_id); + } + + // 4. Find in the Location service. + if (!$host && $this->serviceCode) { + $host = LocationService::resolveHost($this); + } + } + + /** + * @return string + * @throws ClientException + */ + public function realRegionId() + { + if ($this->regionId !== null) { + return $this->regionId; + } + + if ($this->httpClient()->regionId !== null) { + return $this->httpClient()->regionId; + } + + if (AlibabaCloud::getDefaultRegionId() !== null) { + return AlibabaCloud::getDefaultRegionId(); + } + + if ($this->product && AlibabaCloud::isGlobalProduct($this->product)) { + return 'global'; + } + + throw new ClientException("Missing required 'RegionId' for Request", SDK::INVALID_REGION_ID); + } +} diff --git a/vendor/alibabacloud/client/src/Request/Traits/ClientTrait.php b/vendor/alibabacloud/client/src/Request/Traits/ClientTrait.php new file mode 100644 index 0000000..37a2d22 --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/Traits/ClientTrait.php @@ -0,0 +1,98 @@ +httpClient()->getCredential(); + } + + $timeout = isset($this->options['timeout']) + ? $this->options['timeout'] + : Request::TIMEOUT; + + $connectTimeout = isset($this->options['connect_timeout']) + ? $this->options['connect_timeout'] + : Request::CONNECT_TIMEOUT; + + return $this->httpClient()->getSessionCredential($timeout, $connectTimeout); + } + + /** + * Get the client based on the request's settings. + * + * @return Client + * @throws ClientException + */ + public function httpClient() + { + if (!AlibabaCloud::all()) { + if (CredentialsProvider::hasCustomChain()) { + CredentialsProvider::customProvider($this->client); + } else { + CredentialsProvider::defaultProvider($this->client); + } + } + + return AlibabaCloud::get($this->client); + } + + /** + * Merged with the client's options, the same name will be overwritten. + * + * @throws ClientException + */ + public function mergeOptionsIntoClient() + { + $this->options = Arrays::merge( + [ + $this->httpClient()->options, + $this->options + ] + ); + } +} diff --git a/vendor/alibabacloud/client/src/Request/Traits/DeprecatedRoaTrait.php b/vendor/alibabacloud/client/src/Request/Traits/DeprecatedRoaTrait.php new file mode 100644 index 0000000..ee64e52 --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/Traits/DeprecatedRoaTrait.php @@ -0,0 +1,55 @@ +pathParameter($name, $value); + } + + /** + * @param $pathPattern + * + * @return $this + * @deprecated + * @codeCoverageIgnore + */ + public function setUriPattern($pathPattern) + { + return $this->pathPattern($pathPattern); + } + + /** + * @return string + * @deprecated + * @codeCoverageIgnore + */ + public function getUriPattern() + { + return $this->pathPattern; + } + + /** + * @return array + * @deprecated + * @codeCoverageIgnore + */ + public function getPathParameters() + { + return $this->pathParameters; + } +} diff --git a/vendor/alibabacloud/client/src/Request/Traits/DeprecatedTrait.php b/vendor/alibabacloud/client/src/Request/Traits/DeprecatedTrait.php new file mode 100644 index 0000000..406e6ed --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/Traits/DeprecatedTrait.php @@ -0,0 +1,246 @@ +body($content); + } + + /** + * @param $method + * + * @return $this + * @throws ClientException + * @deprecated + * @codeCoverageIgnore + */ + public function setMethod($method) + { + return $this->method($method); + } + + /** + * @param $scheme + * + * @return $this + * @throws ClientException + * @deprecated + * @codeCoverageIgnore + */ + public function setProtocol($scheme) + { + return $this->scheme($scheme); + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getProtocolType() + { + return $this->uri->getScheme(); + } + + /** + * @param $scheme + * + * @return $this + * @throws ClientException + * @deprecated + * @codeCoverageIgnore + */ + public function setProtocolType($scheme) + { + return $this->scheme($scheme); + } + + /** + * @param $actionName + * + * @return $this + * @throws ClientException + * @deprecated + * @codeCoverageIgnore + */ + public function setActionName($actionName) + { + return $this->action($actionName); + } + + /** + * @param $format + * + * @return $this + * @throws ClientException + * @deprecated + * @codeCoverageIgnore + */ + public function setAcceptFormat($format) + { + return $this->format($format); + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getProtocol() + { + return $this->uri->getScheme(); + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getContent() + { + return isset($this->options['body']) + ? $this->options['body'] + : null; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getMethod() + { + return $this->method; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getHeaders() + { + return isset($this->options['headers']) + ? $this->options['headers'] + : []; + } + + /** + * @param $headerKey + * @param $headerValue + * + * @return $this + * @deprecated + * @codeCoverageIgnore + */ + public function addHeader($headerKey, $headerValue) + { + $this->options['headers'][$headerKey] = $headerValue; + + return $this; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getQueryParameters() + { + return isset($this->options['query']) + ? $this->options['query'] + : []; + } + + /** + * @param $name + * @param $value + * + * @return $this + * @deprecated + * @codeCoverageIgnore + */ + public function setQueryParameters($name, $value) + { + $this->options['query'][$name] = $value; + + return $this; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getDomainParameter() + { + return isset($this->options['form_params']) + ? $this->options['form_params'] + : []; + } + + /** + * @param $name + * @param $value + * + * @return $this + * @deprecated + * @codeCoverageIgnore + */ + public function putDomainParameters($name, $value) + { + $this->options['form_params'][$name] = $value; + + return $this; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getActionName() + { + return $this->action; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getAcceptFormat() + { + return $this->format; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getLocationEndpointType() + { + return $this->endpointType; + } + + /** + * @deprecated + * @codeCoverageIgnore + */ + public function getLocationServiceCode() + { + return $this->serviceCode; + } +} diff --git a/vendor/alibabacloud/client/src/Request/Traits/RetryTrait.php b/vendor/alibabacloud/client/src/Request/Traits/RetryTrait.php new file mode 100644 index 0000000..be1d002 --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/Traits/RetryTrait.php @@ -0,0 +1,149 @@ +serverRetry = ClientFilter::retry($times); + $this->serverRetryStrings = $strings; + $this->serverRetryStatusCodes = $statusCodes; + + return $this; + } + + /** + * @param int $times + * @param array $strings + * @param array $codes + * + * @return $this + * @throws ClientException + */ + public function retryByClient($times, array $strings, array $codes = []) + { + $this->clientRetry = ClientFilter::retry($times); + $this->clientRetryStrings = $strings; + $this->clientRetryStatusCodes = $codes; + + return $this; + } + + /** + * @param Result $result + * + * @return bool + */ + private function shouldServerRetry(Result $result) + { + if ($this->serverRetry <= 0) { + return false; + } + + if (in_array($result->getStatusCode(), $this->serverRetryStatusCodes)) { + $this->serverRetry--; + + return true; + } + + foreach ($this->serverRetryStrings as $message) { + if (Stringy::contains($result->getBody(), $message)) { + $this->serverRetry--; + + return true; + } + } + + return false; + } + + /** + * @param Exception $exception + * + * @return bool + */ + private function shouldClientRetry(Exception $exception) + { + if ($this->clientRetry <= 0) { + return false; + } + + if (in_array($exception->getCode(), $this->clientRetryStatusCodes, true)) { + $this->clientRetry--; + + return true; + } + + foreach ($this->clientRetryStrings as $message) { + if (Stringy::contains($exception->getMessage(), $message)) { + $this->clientRetry--; + + return true; + } + } + + return false; + } +} diff --git a/vendor/alibabacloud/client/src/Request/UserAgent.php b/vendor/alibabacloud/client/src/Request/UserAgent.php new file mode 100644 index 0000000..beb3283 --- /dev/null +++ b/vendor/alibabacloud/client/src/Request/UserAgent.php @@ -0,0 +1,142 @@ + $value) { + if ($value === null) { + $newUserAgent[] = $key; + continue; + } + $newUserAgent[] = "$key/$value"; + } + + return $userAgent . \implode(' ', $newUserAgent); + } + + /** + * UserAgent constructor. + */ + private static function defaultFields() + { + if (self::$userAgent === []) { + self::$userAgent = [ + 'Client' => AlibabaCloud::VERSION, + 'PHP' => \PHP_VERSION, + ]; + } + } + + /** + * @param array $append + * + * @return array + */ + public static function clean(array $append) + { + foreach ($append as $key => $value) { + if (self::isGuarded($key)) { + unset($append[$key]); + continue; + } + } + + return $append; + } + + /** + * @param $name + * + * @return bool + */ + public static function isGuarded($name) + { + return in_array(strtolower($name), self::$guard, true); + } + + /** + * set User Agent of Alibaba Cloud. + * + * @param string $name + * @param string $value + * + * @throws ClientException + */ + public static function append($name, $value) + { + Filter::name($name); + Filter::value($value); + + self::defaultFields(); + + if (!self::isGuarded($name)) { + self::$userAgent[$name] = $value; + } + } + + /** + * @param array $userAgent + */ + public static function with(array $userAgent) + { + self::$userAgent = self::clean($userAgent); + } + + /** + * Clear all of the User Agent. + */ + public static function clear() + { + self::$userAgent = []; + } +} diff --git a/vendor/alibabacloud/client/src/Resolver/ActionResolverTrait.php b/vendor/alibabacloud/client/src/Resolver/ActionResolverTrait.php new file mode 100644 index 0000000..f375567 --- /dev/null +++ b/vendor/alibabacloud/client/src/Resolver/ActionResolverTrait.php @@ -0,0 +1,50 @@ +action) { + $array = explode('\\', get_class($this)); + $this->action = array_pop($array); + } + } + + /** + * Append SDK version into User-Agent + * + * @throws ClientException + * @throws ReflectionException + */ + private function appendSdkUA() + { + if (!(new ReflectionClass(AlibabaCloud::class))->hasMethod('appendUserAgent')) { + return; + } + + if (!class_exists('AlibabaCloud\Release')) { + return; + } + + AlibabaCloud::appendUserAgent('SDK', \AlibabaCloud\Release::VERSION); + } +} diff --git a/vendor/alibabacloud/client/src/Resolver/ApiResolver.php b/vendor/alibabacloud/client/src/Resolver/ApiResolver.php new file mode 100644 index 0000000..7a2bc2b --- /dev/null +++ b/vendor/alibabacloud/client/src/Resolver/ApiResolver.php @@ -0,0 +1,113 @@ +__call($name, $arguments); + } + + /** + * @param $api + * @param $arguments + * + * @return mixed + * @throws ClientException + */ + public function __call($api, $arguments) + { + $product_name = $this->getProductName(); + $class = $this->getNamespace() . '\\' . \ucfirst($api); + + if (\class_exists($class)) { + if (isset($arguments[0])) { + return $this->warpEndpoint(new $class($arguments[0])); + } + + return $this->warpEndpoint(new $class()); + } + + throw new ClientException( + "{$product_name} contains no $api", + 'SDK.ApiNotFound' + ); + } + + /** + * @param Request $request + * + * @return Request + */ + public function warpEndpoint(Request $request) + { + $reflect = new ReflectionObject($request); + $product_dir = dirname(dirname($reflect->getFileName())); + $endpoints_json = "$product_dir/endpoints.json"; + if (file_exists($endpoints_json)) { + $endpoints = json_decode(file_get_contents($endpoints_json), true); + if (isset($endpoints['endpoint_map'])) { + $request->endpointMap = $endpoints['endpoint_map']; + } + if (isset($endpoints['endpoint_regional'])) { + $request->endpointRegional = $endpoints['endpoint_regional']; + } + } + + return $request; + } + + /** + * @return mixed + * @throws ClientException + */ + private function getProductName() + { + $array = \explode('\\', \get_class($this)); + if (isset($array[3])) { + return str_replace('ApiResolver', '', $array[3]); + } + throw new ClientException( + 'Service name not found.', + 'SDK.ServiceNotFound' + ); + } + + /** + * @return string + * @throws ClientException + */ + private function getNamespace() + { + $array = \explode('\\', \get_class($this)); + + if (!isset($array[3])) { + throw new ClientException( + 'Get namespace error.', + 'SDK.ParseError' + ); + } + + unset($array[3]); + + return \implode('\\', $array); + } +} diff --git a/vendor/alibabacloud/client/src/Resolver/CallTrait.php b/vendor/alibabacloud/client/src/Resolver/CallTrait.php new file mode 100644 index 0000000..520c03b --- /dev/null +++ b/vendor/alibabacloud/client/src/Resolver/CallTrait.php @@ -0,0 +1,66 @@ +__get($parameter); + } + + if (strncmp($name, 'with', 4) === 0) { + $parameter = \mb_strcut($name, 4); + + $value = $this->getCallArguments($name, $arguments); + $this->data[$parameter] = $value; + $this->parameterPosition()[$parameter] = $value; + + return $this; + } + + if (strncmp($name, 'set', 3) === 0) { + $parameter = \mb_strcut($name, 3); + $with_method = "with$parameter"; + + return $this->$with_method($this->getCallArguments($name, $arguments)); + } + + throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()'); + } + + /** + * @param string $name + * @param array $arguments + * @param int $index + * + * @return mixed + */ + private function getCallArguments($name, array $arguments, $index = 0) + { + if (!isset($arguments[$index])) { + throw new \InvalidArgumentException("Missing arguments to method $name"); + } + + return $arguments[$index]; + } +} diff --git a/vendor/alibabacloud/client/src/Resolver/Roa.php b/vendor/alibabacloud/client/src/Resolver/Roa.php new file mode 100644 index 0000000..719cb0a --- /dev/null +++ b/vendor/alibabacloud/client/src/Resolver/Roa.php @@ -0,0 +1,43 @@ +resolveActionName(); + $this->appendSdkUA(); + } + + /** + * @return mixed + */ + private function ¶meterPosition() + { + return $this->pathParameters; + } +} diff --git a/vendor/alibabacloud/client/src/Resolver/Rpc.php b/vendor/alibabacloud/client/src/Resolver/Rpc.php new file mode 100644 index 0000000..0926ca4 --- /dev/null +++ b/vendor/alibabacloud/client/src/Resolver/Rpc.php @@ -0,0 +1,41 @@ +resolveActionName(); + $this->appendSdkUA(); + } + + /** + * @return mixed + */ + private function ¶meterPosition() + { + return $this->options['query']; + } +} diff --git a/vendor/alibabacloud/client/src/Resolver/VersionResolver.php b/vendor/alibabacloud/client/src/Resolver/VersionResolver.php new file mode 100644 index 0000000..5662718 --- /dev/null +++ b/vendor/alibabacloud/client/src/Resolver/VersionResolver.php @@ -0,0 +1,74 @@ +__call($name, $arguments); + } + + /** + * @param string $version + * @param array $arguments + * + * @return mixed + * @throws ClientException + */ + public function __call($version, $arguments) + { + $version = \ucfirst($version); + $product = $this->getProductName(); + + $position = strpos($product, 'Version'); + if ($position !== false && $position !== 0) { + $product = \str_replace('Version', '', $product); + } + + $class = "AlibabaCloud\\{$product}\\$version\\{$product}ApiResolver"; + + if (\class_exists($class)) { + return new $class(); + } + + throw new ClientException( + "$product Versions contains no {$version}", + 'SDK.VersionNotFound' + ); + } + + /** + * @return mixed + * @throws ClientException + */ + private function getProductName() + { + $array = \explode('\\', \get_class($this)); + + if (is_array($array) && isset($array[1])) { + return $array[1]; + } + + throw new ClientException( + 'Service name not found.', + 'SDK.ServiceNotFound' + ); + } +} diff --git a/vendor/alibabacloud/client/src/Result/Result.php b/vendor/alibabacloud/client/src/Result/Result.php new file mode 100644 index 0000000..7c2910e --- /dev/null +++ b/vendor/alibabacloud/client/src/Result/Result.php @@ -0,0 +1,151 @@ +getStatusCode(), + $response->getHeaders(), + $response->getBody(), + $response->getProtocolVersion(), + $response->getReasonPhrase() + ); + + $this->request = $request; + + $this->resolveData(); + } + + private function resolveData() + { + $content = $this->getBody()->getContents(); + + switch ($this->getRequestFormat()) { + case 'JSON': + $result_data = $this->jsonToArray($content); + break; + case 'XML': + $result_data = $this->xmlToArray($content); + break; + case 'RAW': + $result_data = $this->jsonToArray($content); + break; + default: + $result_data = $this->jsonToArray($content); + } + + if (!$result_data) { + $result_data = []; + } + + $this->dot($result_data); + } + + /** + * @return string + */ + private function getRequestFormat() + { + return ($this->request instanceof Request) + ? \strtoupper($this->request->format) + : 'JSON'; + } + + /** + * @param string $response + * + * @return array + */ + private function jsonToArray($response) + { + try { + return \GuzzleHttp\json_decode($response, true); + } catch (InvalidArgumentException $exception) { + return []; + } + } + + /** + * @param string $string + * + * @return array + */ + private function xmlToArray($string) + { + try { + return json_decode(json_encode(simplexml_load_string($string)), true); + } catch (Exception $exception) { + return []; + } + } + + /** + * @return string + */ + public function __toString() + { + return (string)$this->getBody(); + } + + /** + * @return Request + */ + public function getRequest() + { + return $this->request; + } + + /** + * @codeCoverageIgnore + * @return Response + * @deprecated + */ + public function getResponse() + { + return $this; + } + + /** + * @return bool + */ + public function isSuccess() + { + return 200 <= $this->getStatusCode() + && 300 > $this->getStatusCode(); + } +} diff --git a/vendor/alibabacloud/client/src/SDK.php b/vendor/alibabacloud/client/src/SDK.php new file mode 100644 index 0000000..8976cd0 --- /dev/null +++ b/vendor/alibabacloud/client/src/SDK.php @@ -0,0 +1,57 @@ +getMessage(), + SDK::INVALID_CREDENTIAL + ); + } + + return base64_encode($binarySignature); + } +} diff --git a/vendor/alibabacloud/client/src/Signature/Signature.php b/vendor/alibabacloud/client/src/Signature/Signature.php new file mode 100644 index 0000000..3b01e69 --- /dev/null +++ b/vendor/alibabacloud/client/src/Signature/Signature.php @@ -0,0 +1,49 @@ +sign($string, $accessKeySecret); + + return "acs $accessKeyId:$signature"; + } + + /** + * @codeCoverageIgnore + * + * @param string $accessKeySecret + * @param string $method + * @param array $parameters + * + * @return string + */ + public function rpc($accessKeySecret, $method, array $parameters) + { + $string = Sign::rpcString($method, $parameters); + + return $this->sign($string, $accessKeySecret . '&'); + } +} diff --git a/vendor/alibabacloud/client/src/Signature/SignatureInterface.php b/vendor/alibabacloud/client/src/Signature/SignatureInterface.php new file mode 100644 index 0000000..afa82c8 --- /dev/null +++ b/vendor/alibabacloud/client/src/Signature/SignatureInterface.php @@ -0,0 +1,35 @@ + $value) { + if (is_int($key)) { + $result[] = $value; + continue; + } + + if (isset($result[$key]) && is_array($result[$key])) { + $result[$key] = self::merge( + [$result[$key], $value] + ); + continue; + } + + $result[$key] = $value; + } + } + + return $result; + } +} diff --git a/vendor/alibabacloud/client/src/Support/Path.php b/vendor/alibabacloud/client/src/Support/Path.php new file mode 100644 index 0000000..e1a6464 --- /dev/null +++ b/vendor/alibabacloud/client/src/Support/Path.php @@ -0,0 +1,28 @@ + $value) { + $pattern = str_replace("[$key]", $value, $pattern); + } + + return $pattern; + } +} diff --git a/vendor/alibabacloud/client/src/Support/Sign.php b/vendor/alibabacloud/client/src/Support/Sign.php new file mode 100644 index 0000000..1310d3d --- /dev/null +++ b/vendor/alibabacloud/client/src/Support/Sign.php @@ -0,0 +1,143 @@ + $headerValue) { + $key = strtolower($headerKey); + if (strncmp($key, 'x-acs-', 6) === 0) { + $array[$key] = $headerValue; + } + } + ksort($array); + $string = ''; + foreach ($array as $sortMapKey => $sortMapValue) { + $string .= $sortMapKey . ':' . $sortMapValue[0] . self::$headerSeparator; + } + + return $string; + } + + /** + * @param UriInterface $uri + * + * @return string + */ + private static function resourceString(UriInterface $uri) + { + return $uri->getPath() . '?' . rawurldecode($uri->getQuery()); + } + + /** + * @param string $method + * @param array $headers + * + * @return string + */ + private static function headerString($method, array $headers) + { + $string = $method . self::$headerSeparator; + if (isset($headers['Accept'][0])) { + $string .= $headers['Accept'][0]; + } + $string .= self::$headerSeparator; + + if (isset($headers['Content-MD5'][0])) { + $string .= $headers['Content-MD5'][0]; + } + $string .= self::$headerSeparator; + + if (isset($headers['Content-Type'][0])) { + $string .= $headers['Content-Type'][0]; + } + $string .= self::$headerSeparator; + + if (isset($headers['Date'][0])) { + $string .= $headers['Date'][0]; + } + $string .= self::$headerSeparator; + + $string .= self::acsHeaderString($headers); + + return $string; + } + + /** + * @param string $string + * + * @return null|string|string[] + */ + private static function percentEncode($string) + { + $result = urlencode($string); + $result = str_replace(['+', '*'], ['%20', '%2A'], $result); + $result = preg_replace('/%7E/', '~', $result); + + return $result; + } + + /** + * @param string $method + * @param array $parameters + * + * @return string + */ + public static function rpcString($method, array $parameters) + { + ksort($parameters); + $canonicalized = ''; + foreach ($parameters as $key => $value) { + if ($value === null || $value === '') { + continue; + } + $canonicalized .= '&' . self::percentEncode($key) . '=' . self::percentEncode($value); + } + + return $method . '&%2F&' . self::percentEncode(substr($canonicalized, 1)); + } + + /** + * @param Request $request + * + * @return string + */ + public static function roaString(Request $request) + { + return self::headerString($request->getMethod(), $request->getHeaders()) . + self::resourceString($request->getUri()); + } + + /** + * @param string $salt + * + * @return string + */ + public static function uuid($salt) + { + return md5($salt . uniqid(md5(microtime(true)), true)) . microtime(); + } +} diff --git a/vendor/alibabacloud/client/src/Support/Stringy.php b/vendor/alibabacloud/client/src/Support/Stringy.php new file mode 100644 index 0000000..f4c1099 --- /dev/null +++ b/vendor/alibabacloud/client/src/Support/Stringy.php @@ -0,0 +1,47 @@ +data[$offset])) { + return $this->data[$offset]; + } + + $value = null; + + return $value; + } + + /** + * @param string $offset + * @param string|mixed $value + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + $this->data[$offset] = $value; + } + + /** + * @param string $offset + * + * @return bool + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + return isset($this->data[$offset]); + } + + /** + * @param string $offset + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + unset($this->data[$offset]); + } +} diff --git a/vendor/alibabacloud/client/src/Traits/ClientTrait.php b/vendor/alibabacloud/client/src/Traits/ClientTrait.php new file mode 100644 index 0000000..2cb5309 --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/ClientTrait.php @@ -0,0 +1,273 @@ +load(); + } + $list = []; + foreach (\func_get_args() as $filename) { + $list[$filename] = (new IniCredential($filename))->load(); + } + + return $list; + } + + /** + * Custom Client. + * + * @param CredentialsInterface $credentials + * @param SignatureInterface $signature + * + * @return Client + */ + public static function client(CredentialsInterface $credentials, SignatureInterface $signature) + { + return new Client($credentials, $signature); + } + + /** + * Use the AccessKey to complete the authentication. + * + * @param string $accessKeyId + * @param string $accessKeySecret + * + * @return AccessKeyClient + * @throws ClientException + */ + public static function accessKeyClient($accessKeyId, $accessKeySecret) + { + if (null === $accessKeyId || strpos($accessKeyId, ' ') !== false) { + throw new ClientException( + 'AccessKey ID format is invalid', + SDK::INVALID_ARGUMENT + ); + } + + if (null === $accessKeySecret || strpos($accessKeySecret, ' ') !== false) { + throw new ClientException( + 'AccessKey Secret format is invalid', + SDK::INVALID_ARGUMENT + ); + } + + return new AccessKeyClient($accessKeyId, $accessKeySecret); + } + + /** + * Use the AssumeRole of the RAM account to complete the authentication. + * + * @param string $accessKeyId + * @param string $accessKeySecret + * @param string $roleArn + * @param string $roleSessionName + * @param string|array $policy + * + * @return RamRoleArnClient + * @throws ClientException + */ + public static function ramRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy = '') + { + return new RamRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy); + } + + /** + * Use the RAM role of an ECS instance to complete the authentication. + * + * @param string $roleName + * + * @return EcsRamRoleClient + * @throws ClientException + */ + public static function ecsRamRoleClient($roleName) + { + return new EcsRamRoleClient($roleName); + } + + /** + * Use the Bearer Token to complete the authentication. + * + * @param string $bearerToken + * + * @return BearerTokenClient + * @throws ClientException + */ + public static function bearerTokenClient($bearerToken) + { + return new BearerTokenClient($bearerToken); + } + + /** + * Use the STS Token to complete the authentication. + * + * @param string $accessKeyId Access key ID + * @param string $accessKeySecret Access Key Secret + * @param string $securityToken Security Token + * + * @return StsClient + * @throws ClientException + */ + public static function stsClient($accessKeyId, $accessKeySecret, $securityToken = '') + { + return new StsClient($accessKeyId, $accessKeySecret, $securityToken); + } + + /** + * Use the RSA key pair to complete the authentication (supported only on Japanese site) + * + * @param string $publicKeyId + * @param string $privateKeyFile + * + * @return RsaKeyPairClient + * @throws ClientException + */ + public static function rsaKeyPairClient($publicKeyId, $privateKeyFile) + { + return new RsaKeyPairClient($publicKeyId, $privateKeyFile); + } +} diff --git a/vendor/alibabacloud/client/src/Traits/DefaultRegionTrait.php b/vendor/alibabacloud/client/src/Traits/DefaultRegionTrait.php new file mode 100644 index 0000000..5d5c75a --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/DefaultRegionTrait.php @@ -0,0 +1,66 @@ +network ?: 'public'; + $suffix = $request->endpointSuffix; + if ($network === 'public') { + $network = ''; + } + + if ($request->endpointRegional === 'regional') { + $regionId = $request->realRegionId(); + return "{$request->product}{$suffix}{$network}.{$regionId}.aliyuncs.com"; + } + + if ($request->endpointRegional === 'central') { + return "{$request->product}{$suffix}{$network}.aliyuncs.com"; + } + + throw new InvalidArgumentException('endpointRegional is invalid.'); + } +} diff --git a/vendor/alibabacloud/client/src/Traits/HasDataTrait.php b/vendor/alibabacloud/client/src/Traits/HasDataTrait.php new file mode 100644 index 0000000..03c4b9d --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/HasDataTrait.php @@ -0,0 +1,324 @@ +dot->all()); + } + + /** + * Delete the contents of a given key or keys + * + * @param array|int|string|null $keys + */ + public function clear($keys = null) + { + $this->dot->clear($keys); + } + + /** + * Flatten an array with the given character as a key delimiter + * + * @param string $delimiter + * @param array|null $items + * @param string $prepend + * + * @return array + */ + public function flatten($delimiter = '.', $items = null, $prepend = '') + { + return $this->dot->flatten($delimiter, $items, $prepend); + } + + /** + * Return the value of a given key + * + * @param int|string|null $key + * @param mixed $default + * + * @return mixed + */ + public function get($key = null, $default = null) + { + return $this->dot->get($key, $default); + } + + /** + * Set a given key / value pair or pairs + * + * @param array|int|string $keys + * @param mixed $value + */ + public function set($keys, $value = null) + { + $this->dot->set($keys, $value); + } + + /** + * Check if a given key or keys are empty + * + * @param array|int|string|null $keys + * + * @return bool + */ + public function isEmpty($keys = null) + { + return $this->dot->isEmpty($keys); + } + + /** + * Replace all items with a given array as a reference + * + * @param array $items + */ + public function setReference(array &$items) + { + $this->dot->setReference($items); + } + + /** + * Return the value of a given key or all the values as JSON + * + * @param mixed $key + * @param int $options + * + * @return string + */ + public function toJson($key = null, $options = 0) + { + return $this->dot->toJson($key, $options); + } + + /** + * @return array + */ + public function toArray() + { + return $this->dot->all(); + } + + /** + * Check if a given key exists + * + * @param int|string $key + * + * @return bool + */ + #[\ReturnTypeWillChange] + public function offsetExists($key) + { + return $this->dot->has($key); + } + + /** + * Return the value of a given key + * + * @param int|string $key + * + * @return mixed + */ + #[\ReturnTypeWillChange] + public function offsetGet($key) + { + return $this->dot->offsetGet($key); + } + + /** + * Set a given value to the given key + * + * @param int|string|null $key + * @param mixed $value + */ + #[\ReturnTypeWillChange] + public function offsetSet($key, $value) + { + $this->dot->offsetSet($key, $value); + } + + /** + * Delete the given key + * + * @param int|string $key + */ + #[\ReturnTypeWillChange] + public function offsetUnset($key) + { + $this->delete($key); + } + + /** + * Delete the given key or keys + * + * @param array|int|string $keys + */ + public function delete($keys) + { + $this->dot->delete($keys); + } + + /* + * -------------------------------------------------------------- + * ArrayAccess interface + * -------------------------------------------------------------- + */ + + /** + * Return the number of items in a given key + * + * @param int|string|null $key + * + * @return int + */ + #[\ReturnTypeWillChange] + public function count($key = null) + { + return $this->dot->count($key); + } + + /** + * Get an iterator for the stored items + * + * @return ArrayIterator + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + return $this->dot->getIterator(); + } + + /** + * Return items for JSON serialization + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->dot->jsonSerialize(); + } + + /** + * @param string $name + * + * @return mixed|null + */ + public function __get($name) + { + if (!isset($this->all()[$name])) { + return null; + } + + return \json_decode(\json_encode($this->all()))->$name; + } + + /* + * -------------------------------------------------------------- + * Countable interface + * -------------------------------------------------------------- + */ + + /** + * Return all the stored items + * + * @return array + */ + public function all() + { + return $this->dot->all(); + } + + /** + * @param string $name + * @param mixed $value + */ + public function __set($name, $value) + { + $this->add($name, $value); + } + + /** + * Set a given key / value pair or pairs + * if the key doesn't exist already + * + * @param array|int|string $keys + * @param mixed $value + */ + public function add($keys, $value = null) + { + $this->dot->add($keys, $value); + } + + + /* + * -------------------------------------------------------------- + * ObjectAccess + * -------------------------------------------------------------- + */ + + /** + * @param string $name + * + * @return bool + */ + public function __isset($name) + { + return $this->has($name); + } + + /** + * Check if a given key or keys exists + * + * @param array|int|string $keys + * + * @return bool + */ + public function has($keys) + { + return $this->dot->has($keys); + } + + /** + * @param $name + * + * @return void + */ + public function __unset($name) + { + $this->delete($name); + } + + /** + * @param array $data + */ + protected function dot(array $data = []) + { + $this->dot = new Dot($data); + } +} diff --git a/vendor/alibabacloud/client/src/Traits/HistoryTrait.php b/vendor/alibabacloud/client/src/Traits/HistoryTrait.php new file mode 100644 index 0000000..f70bb1d --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/HistoryTrait.php @@ -0,0 +1,68 @@ +options['timeout'] = ClientFilter::timeout($seconds); + + return $this; + } + + /** + * @param int $milliseconds + * + * @return $this + * @throws ClientException + */ + public function timeoutMilliseconds($milliseconds) + { + ClientFilter::milliseconds($milliseconds); + $seconds = $milliseconds / 1000; + + return $this->timeout($seconds); + } + + /** + * @param int|float $seconds + * + * @return $this + * @throws ClientException + */ + public function connectTimeout($seconds) + { + $this->options['connect_timeout'] = ClientFilter::connectTimeout($seconds); + + return $this; + } + + /** + * @param int $milliseconds + * + * @return $this + * @throws ClientException + */ + public function connectTimeoutMilliseconds($milliseconds) + { + ClientFilter::milliseconds($milliseconds); + $seconds = $milliseconds / 1000; + + return $this->connectTimeout($seconds); + } + + /** + * @param bool $debug + * + * @return $this + */ + public function debug($debug) + { + $this->options['debug'] = $debug; + + return $this; + } + + /** + * @codeCoverageIgnore + * + * @param array $cert + * + * @return $this + */ + public function cert($cert) + { + $this->options['cert'] = $cert; + + return $this; + } + + /** + * @codeCoverageIgnore + * + * @param array|string $proxy + * + * @return $this + */ + public function proxy($proxy) + { + $this->options['proxy'] = $proxy; + + return $this; + } + + /** + * @param mixed $verify + * + * @return $this + */ + public function verify($verify) + { + $this->options['verify'] = $verify; + + return $this; + } + + /** + * @param array $options + * + * @return $this + */ + public function options(array $options) + { + if ($options !== []) { + $this->options = Arrays::merge([$this->options, $options]); + } + + return $this; + } +} diff --git a/vendor/alibabacloud/client/src/Traits/LogTrait.php b/vendor/alibabacloud/client/src/Traits/LogTrait.php new file mode 100644 index 0000000..0457602 --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/LogTrait.php @@ -0,0 +1,97 @@ +format('Y-m-d H:i:s.u')], + $template + ); + } + + /** + * Apache Common Log Format. + * + * @param string $formatter + * + * @link http://httpd.apache.org/docs/2.4/logs.html#common + * @see \GuzzleHttp\MessageFormatter + */ + public static function setLogFormat($formatter) + { + self::$logFormat = $formatter; + } + + /** + * @return float|mixed + */ + private static function getCost() + { + return microtime(true) - self::$logStartTime; + } +} diff --git a/vendor/alibabacloud/client/src/Traits/MockTrait.php b/vendor/alibabacloud/client/src/Traits/MockTrait.php new file mode 100644 index 0000000..28928d1 --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/MockTrait.php @@ -0,0 +1,97 @@ +data[$name])) { + return null; + } + + return \json_decode(\json_encode($this->data))->$name; + } + + /** + * @param string $name + * @param mixed $value + */ + public function __set($name, $value) + { + $this->data[$name] = $value; + } + + /** + * @param string $name + * + * @return bool + */ + public function __isset($name) + { + return isset($this->data[$name]); + } + + /** + * @param $name + * + * @return void + */ + public function __unset($name) + { + unset($this->data[$name]); + } +} diff --git a/vendor/alibabacloud/client/src/Traits/RegionTrait.php b/vendor/alibabacloud/client/src/Traits/RegionTrait.php new file mode 100644 index 0000000..da6bee4 --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/RegionTrait.php @@ -0,0 +1,33 @@ +regionId = ClientFilter::regionId($regionId); + + return $this; + } +} diff --git a/vendor/alibabacloud/client/src/Traits/RequestTrait.php b/vendor/alibabacloud/client/src/Traits/RequestTrait.php new file mode 100644 index 0000000..afcb9a4 --- /dev/null +++ b/vendor/alibabacloud/client/src/Traits/RequestTrait.php @@ -0,0 +1,90 @@ +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php'); + } +} + +return include __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php'; diff --git a/vendor/bin/jp.php.bat b/vendor/bin/jp.php.bat new file mode 100644 index 0000000..9af045e --- /dev/null +++ b/vendor/bin/jp.php.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/jp.php +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/clagiordano/weblibs-configmanager/.github/workflows/php.yml b/vendor/clagiordano/weblibs-configmanager/.github/workflows/php.yml new file mode 100644 index 0000000..365f400 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/.github/workflows/php.yml @@ -0,0 +1,43 @@ +name: PHP Composer + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ ubuntu-18.04 ] + php: [ '5.4', '5.5', '5.6', '7.1', '7.2', '7.3', '7.4' ] + name: PHP ${{ matrix.php }}@${{ matrix.operating-system }} + + steps: + - uses: actions/checkout@v2 + - uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php }} + extensions: xdebug + + - name: check php version + run: php --version + + - name: check composer version + run: composer --version + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Run test suite + run: ./vendor/bin/phpunit + + - name: Upload coverage results to Coveralls + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + run: ./vendor/bin/coveralls --coverage_clover=build/logs/clover.xml -v diff --git a/vendor/clagiordano/weblibs-configmanager/.gitignore b/vendor/clagiordano/weblibs-configmanager/.gitignore new file mode 100644 index 0000000..521afeb --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/.gitignore @@ -0,0 +1,3 @@ +composer.phar +vendor +testsdata/phpunit_* \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/README.md b/vendor/clagiordano/weblibs-configmanager/README.md new file mode 100644 index 0000000..b200663 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/README.md @@ -0,0 +1,143 @@ +[![PHP Composer](https://github.com/clagiordano/weblibs-configmanager/actions/workflows/php.yml/badge.svg)](https://github.com/clagiordano/weblibs-configmanager/actions/workflows/php.yml) +[![Coverage Status](https://coveralls.io/repos/github/clagiordano/weblibs-configmanager/badge.svg?branch=master)](https://coveralls.io/github/clagiordano/weblibs-configmanager?branch=master) +[![SymfonyInsight](https://insight.symfony.com/projects/54c4e80c-ff15-4235-8bec-a4c71bbe3ba5/mini.svg)](https://insight.symfony.com/projects/54c4e80c-ff15-4235-8bec-a4c71bbe3ba5) + +# weblibs-configmanager +weblibs-configmanager is a tool library for easily read and access to php config array file and direct read/write configuration file / object. + +## Why use weblibs-configmanager ? +The purpose of this project is to propose a simple and lightweight library to manage php hierarchical configuration files. + +## Supported formats + +This package supports config files in the following format: + +Format | Component | Since version | Description +:---: | :---: | :---: | --- +Array | `ConfigManager` | `v0.1.0` | Deprecated, legacy name for the php array reader, only for compatibility support +Array | `ArrayConfigManager` | `v1.2.0` | A file that returns a php array, the original supported format +Yaml | `YamlConfigManager` | `v1.3.0` | A file containing a valid YAML file +JSON | `JsonConfigManager` | `v1.4.0` | A file containing a valid JSON file + +All the supported format are parsed and internally handled in the same way granting the same functionalities. + +## Installation +The recommended way to install weblibs-configmanager is through [Composer](https://getcomposer.org). +```bash +composer require clagiordano/weblibs-configmanager +``` + +## Usage examples (Array format) + +### Write a sample config file like this +```php + 'app_name', + 'db' => + array ( + 'host' => 'localhost', + 'user' => 'sample_user', + 'pass' => 'sample_pass', + 'port' => 3306, + ), + 'other' => + array ( + 'multi' => + array ( + 'deep' => + array ( + 'nested' => 'config_value', + ), + ), + ), +); + +``` + +### Instance ConfigManager object + +```php +use clagiordano\weblibs\configmanager\ConfigManager; + +/** + * Instance object to read argument file + */ +$config = new ConfigManager("configfile.php"); +``` + +### Check if a value exists into config file + +```php +/** + * Check if a value exists into config file + */ +$value = $config->existValue('app'); +``` + +### Read a simple element from config file + +```php +/** + * Read a simple element from config file + */ +$value = $config->getValue('app'); +``` + +### Access to a nested element from config + +```php +/** + * Access to a nested element from config + */ +$nestedValue = $config->getValue('other.multi.deep.nested'); +``` + +### Change config value at runtime + +```php +/** + * Change config value at runtime + */ +$this->config->setValue('other.multi.deep.nested', "SUPERNESTED"); +``` + +### Save config file with original name (OVERWRITE) + +```php +/** + * Save config file with original name (OVERWRITE) + */ +$this->config->saveConfigFile(); +``` + +### Or save config file with a different name + +```php +/** + * Save config file with original name (OVERWRITE) + */ +$this->config->saveConfigFile('/new/file/name/or/path/test.php'); +``` + +### Optionally you can also reload config file from disk after save + +```php +/** + * Optionally you can also reload config file from disk after save + */ +$this->config->saveConfigFile('/new/file/name/or/path/test.php', true); +``` + +### Load another configuration file without reinstance ConfigManager + +```php +/** + * Load another configuration file without reinstance ConfigManager + */ +$this->config->loadConfig('another_config_file.php'); +``` + +## Legal +*Copyright (C) Claudio Giordano * diff --git a/vendor/clagiordano/weblibs-configmanager/composer.json b/vendor/clagiordano/weblibs-configmanager/composer.json new file mode 100644 index 0000000..d1b5156 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/composer.json @@ -0,0 +1,51 @@ +{ + "name": "clagiordano/weblibs-configmanager", + "description": "weblibs-configmanager is a tool library for easily read and access to php config array file and direct read/write configuration file / object", + "type": "library", + "license": "LGPL-3.0-or-later", + "keywords": ["clagiordano", "weblibs", "configuration", "manager", "tool"], + "authors": [ + { + "name": "Claudio Giordano", + "email": "claudio.giordano@autistici.org", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "clagiordano\\weblibs\\configmanager\\": "src/" + } + }, + "require": { + "php": ">=5.4", + "symfony/yaml": "^2.8", + "ext-json": "*" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "clagiordano/phpunit-result-printer": "^1", + "php-coveralls/php-coveralls": "^1.1" + }, + "autoload-dev": { + "psr-4": { + "clagiordano\\weblibs\\configmanager\\tests\\": "tests/", + "clagiordano\\weblibs\\configmanager\\testdata\\": "testdata/" + } + }, + "scripts": { + "test": [ + "Composer\\Config::disableProcessTimeout", + "./vendor/bin/phpunit --no-coverage" + ], + "coverage": [ + "Composer\\Config::disableProcessTimeout", + "php -dzend_extension=xdebug.so ./vendor/bin/phpunit" + ], + "debug": "php -dxdebug.remote_autostart=On -dzend_extension=xdebug.so ./vendor/bin/phpunit" + }, + "config": { + "platform": { + "php": "5.4" + } + } +} diff --git a/vendor/clagiordano/weblibs-configmanager/phpunit.xml b/vendor/clagiordano/weblibs-configmanager/phpunit.xml new file mode 100644 index 0000000..7c07528 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/phpunit.xml @@ -0,0 +1,39 @@ + + + + + ./tests/ + + + + + + src/ + + + + + + + + + + + + + + + + + diff --git a/vendor/clagiordano/weblibs-configmanager/src/AbstractConfigManager.php b/vendor/clagiordano/weblibs-configmanager/src/AbstractConfigManager.php new file mode 100644 index 0000000..121dd2b --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/src/AbstractConfigManager.php @@ -0,0 +1,159 @@ +loadConfig($configFilePath); + } catch (Exception $exception) { + /** + * Allow not existent file name at construct + */ + } + } + + /** + * Get value pointer from config for get/set value + * + * @param string $configPath + * + * @return mixed + */ + protected function & getValuePointer($configPath) + { + $configData =& $this->configData; + $parts = explode('.', $configPath); + $length = count($parts); + + for ($i = 0; $i < $length; $i++) { + if (!isset($configData[ $parts[ $i ] ])) { + $configData[ $parts[ $i ] ] = ($i === $length) ? [] : null; + } + + $configData = &$configData[ $parts[ $i ] ]; + } + + return $configData; + } + + /** + * Get value from config data throught keyValue path + * + * @param string $configPath + * @param mixed $defaultValue + * + * @return mixed + */ + public function getValue($configPath, $defaultValue = null) + { + $stored = $this->getValuePointer($configPath); + + return (is_null($stored) + ? $defaultValue + : $stored); + } + + /** + * Check if exist required config for keyValue + * + * @param string $keyValue + * + * @return mixed + */ + public function existValue($keyValue) + { + return !is_null($this->getValue($keyValue)); + } + + /** + * Set value in config path + * + * @param string $configPath + * @param mixed $newValue + * + * @return IConfigurable + */ + public function setValue($configPath, $newValue) + { + $configData = &$this->getValuePointer($configPath); + $configData = $newValue; + + return $this; + } + + /** + * @inheritDoc + */ + public function getConfig() + { + return $this->configData; + } + + /** + * @inheritDoc + */ + public function setConfig($config) + { + $this->configData = (array)$config; + + return $this; + } + + /** + * @inheritDoc + */ + public function convert(IConfigurable $target) + { + $target->setConfig($this->getConfig()); + + return $target; + } + + /** + * Check if configFilePath exists and is readable + * @return bool + * @throws RuntimeException + */ + protected function checkLoadable() + { + if ($this->configFilePath !== null) { + if (file_exists($this->configFilePath) && is_readable($this->configFilePath)) { + /** + * Readable + */ + return true; + } + + /** + * $configFilePath is not null, but not existent or not readable + */ + throw new RuntimeException("Failed to read config file from path '{$this->configFilePath}'"); + } + + /** + * $configFilePath is null + */ + return false; + } +} diff --git a/vendor/clagiordano/weblibs-configmanager/src/ArrayConfigManager.php b/vendor/clagiordano/weblibs-configmanager/src/ArrayConfigManager.php new file mode 100644 index 0000000..1fd5b11 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/src/ArrayConfigManager.php @@ -0,0 +1,72 @@ +configFilePath = $configFilePath; + if ($this->checkLoadable()) { + $this->configData = require $this->configFilePath; + } + + return $this; + } + + /** + * Prepare and write config file on disk + * + * @param null|string $configFilePath + * @param bool $autoReloadConfig + * + * @return IConfigurable + * @throws RuntimeException + */ + public function saveConfigFile($configFilePath = null, $autoReloadConfig = false) + { + if (is_null($configFilePath)) { + $configFilePath = $this->configFilePath; + } + + $configFileContent = "configData, true); + $configFileContent .= ";\n\n"; + + try { + file_put_contents($configFilePath, $configFileContent); + + if (is_callable('opcache_invalidate')) { + /** + * Invalidate opcache for writed file if opcache is available + */ + opcache_invalidate($configFilePath, true); + } + } catch (Exception $exception) { + throw new RuntimeException( + "Failed to write config file to path '{$configFilePath}'\n{$exception->getMessage()}" + ); + } + + if ($autoReloadConfig) { + $this->loadConfig($configFilePath); + } + + return $this; + } +} diff --git a/vendor/clagiordano/weblibs-configmanager/src/ConfigManager.php b/vendor/clagiordano/weblibs-configmanager/src/ConfigManager.php new file mode 100644 index 0000000..3fe13ed --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/src/ConfigManager.php @@ -0,0 +1,14 @@ +setConfig($source->getConfig()); + } + + /** + * @inheritDoc + */ + public static function convertAndSave(IConfigurable $source, IConfigurable $target) + { + $target->setConfig($source->getConfig()); + + return $target->saveConfigFile(); + } +} diff --git a/vendor/clagiordano/weblibs-configmanager/src/IConfigurable.php b/vendor/clagiordano/weblibs-configmanager/src/IConfigurable.php new file mode 100644 index 0000000..ebf662d --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/src/IConfigurable.php @@ -0,0 +1,84 @@ +configFilePath = $configFilePath; + if ($this->checkLoadable()) { + if (!is_callable('json_decode')) { + throw new RuntimeException('Missing php-json extension'); + } + + $this->configData = json_decode(file_get_contents($configFilePath), true); + } + + return $this; + } + + /** + * Prepare and write config file on disk + * + * @param null|string $configFilePath + * @param bool $autoReloadConfig + * + * @return IConfigurable + * @throws RuntimeException + */ + public function saveConfigFile($configFilePath = null, $autoReloadConfig = false) + { + if (is_null($configFilePath)) { + $configFilePath = $this->configFilePath; + } + + try { + if (!is_callable('json_encode')) { + throw new RuntimeException('Missing php-json extension'); + } + + file_put_contents($configFilePath, json_encode($this->configData, JSON_UNESCAPED_UNICODE)); + } catch (Exception $exception) { + throw new RuntimeException( + "Failed to write config file to path '{$configFilePath}'\n{$exception->getMessage()}" + ); + } + + if ($autoReloadConfig) { + $this->loadConfig($configFilePath); + } + + return $this; + } +} diff --git a/vendor/clagiordano/weblibs-configmanager/src/YamlConfigManager.php b/vendor/clagiordano/weblibs-configmanager/src/YamlConfigManager.php new file mode 100644 index 0000000..cd6d052 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/src/YamlConfigManager.php @@ -0,0 +1,64 @@ +configFilePath = $configFilePath; + if ($this->checkLoadable()) { + $this->configData = Yaml::parse(file_get_contents($configFilePath)); + } + + return $this; + } + + /** + * Prepare and write config file on disk + * + * @param null|string $configFilePath + * @param bool $autoReloadConfig + * + * @return IConfigurable + * @throws RuntimeException + */ + public function saveConfigFile($configFilePath = null, $autoReloadConfig = false) + { + if (is_null($configFilePath)) { + $configFilePath = $this->configFilePath; + } + + try { + file_put_contents( + $configFilePath, + Yaml::dump($this->configData, 2, 2) + ); + } catch (Exception $exception) { + throw new RuntimeException( + "Failed to write config file to path '{$configFilePath}'\n{$exception->getMessage()}" + ); + } + + if ($autoReloadConfig) { + $this->loadConfig($configFilePath); + } + + return $this; + } +} diff --git a/vendor/clagiordano/weblibs-configmanager/tests/AbstractConfigManagerTest.php b/vendor/clagiordano/weblibs-configmanager/tests/AbstractConfigManagerTest.php new file mode 100644 index 0000000..4446fb3 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/tests/AbstractConfigManagerTest.php @@ -0,0 +1,223 @@ +assertNotNull( + $this->config->getValue('app') + ); + } + + public function testFastUsage() + { + $this->assertNotNull( + $this->config->getValue('app') + ); + } + + public function testFastInvalidKey() + { + $this->assertNull( + $this->config->getValue('invalidKey') + ); + } + + public function testFastInvalidKeyWithDefault() + { + $this->assertEquals( + $this->config->getValue('invalidKey', 'defaultValue'), + 'defaultValue' + ); + } + + public function testFastNestedConfig() + { + $this->assertNotNull( + $this->config->getValue('other.multi.deep.nested') + ); + } + + public function testCheckExistConfig() + { + $this->assertTrue( + $this->config->existValue('other.multi.deep.nested') + ); + } + + public function testCheckNotExistConfig() + { + $this->assertFalse( + $this->config->existValue('invalid.config.path') + ); + } + + public function testSetValue() + { + $this->config->setValue('other.multi.deep.nested', __FUNCTION__); + + $this->assertEquals( + $this->config->getValue('other.multi.deep.nested'), + __FUNCTION__ + ); + } + + public function testFailedSaveConfig() + { + $this->setExpectedException('Exception'); + $this->config->saveConfigFile('/invalid/path'); + } + + public function testSuccessSaveConfigOnTempAndReload() + { + $this->config->setValue('other.multi.deep.nested', "SUPERNESTED"); + $this->config->saveConfigFile("/tmp/testconfig.sample", true); + + $this->assertEquals( + $this->config->getValue('other.multi.deep.nested'), + "SUPERNESTED" + ); + } + + public function testOverwriteSameConfigFile() + { + $this->config->saveConfigFile(); + } + + public function testFailWriteConfig() + { + $this->setExpectedException('\RuntimeException'); + $this->config->saveConfigFile('/invalid/path/test.sample'); + } + + /** + * @test + * @group permissions + */ + public function canRaiseExceptionOnUnreadableFile() + { + /** + * Create new temp file + */ + $testFile = tempnam(__DIR__ . '/../testsdata/temp/', 'phpunit_'); + self::assertFileExists($testFile); + + /** + * Make tempfile unreadable by everyone, but still writeable + */ + $status = chmod($testFile, 0200); + self::assertTrue($status); + + /** + * Check permissions it must be 0200 ( --w------- ) + */ + $filePerms = (fileperms($testFile) & 0777); + self::assertSame(0200, $filePerms); + + /** + * Try to read that file, an exception must be thrown + */ + self::setExpectedException('\RuntimeException'); + $this->config->loadConfig($testFile); + + /** + * Remove temp file + */ + $status = chmod($testFile, 0744); + self::assertTrue($status); + + $filePerms = (fileperms($testFile) & 0777); + self::assertSame(0755, $filePerms); + + $status = unlink($testFile); + self::assertTrue($status); + self::assertFileNotExists($testFile); + } + + /** + * @return array + */ + public function configDataProvider() + { + return [ + [ + __DIR__ . '/../testsdata/sample_config_data.converted.yml', + '\clagiordano\weblibs\configmanager\YamlConfigManager', + ], + [ + __DIR__ . '/../testsdata/sample_config_data.converted.json', + '\clagiordano\weblibs\configmanager\JsonConfigManager', + ], + [ + __DIR__ . '/../testsdata/sample_config_data.converted.php', + '\clagiordano\weblibs\configmanager\ArrayConfigManager', + ], + ]; + } + + /** + * @test + * @dataProvider configDataProvider + * @param mixed $targetConfig + * @param mixed $targetInstance + */ + public function canConvertOneFormatToAnother($targetConfig, $targetInstance) + { + if (file_exists($targetConfig)) { + /** + * Drop target file if already existing + */ + unlink($targetConfig); + } + + self::assertFileNotExists($targetConfig); + + $target = new $targetInstance($targetConfig); + self::assertInstanceOf($targetInstance, $target); + + $converted = $this->config->convert($target); + self::assertInstanceOf($targetInstance, $converted); + + self::assertFileNotExists($targetConfig); + } +} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/tests/ArrayConfigManagerTest.php b/vendor/clagiordano/weblibs-configmanager/tests/ArrayConfigManagerTest.php new file mode 100644 index 0000000..55268ef --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/tests/ArrayConfigManagerTest.php @@ -0,0 +1,25 @@ +config = new ArrayConfigManager("TestConfigData.php"); + $this->assertInstanceOf('clagiordano\weblibs\configmanager\ArrayConfigManager', $this->config); + + $this->assertFileExists($this->configFile); + $this->config->loadConfig($this->configFile); + } +} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/tests/ConfigManagerTest.php b/vendor/clagiordano/weblibs-configmanager/tests/ConfigManagerTest.php new file mode 100644 index 0000000..016d44f --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/tests/ConfigManagerTest.php @@ -0,0 +1,25 @@ +config = new ConfigManager("TestConfigData.php"); + $this->assertInstanceOf('clagiordano\weblibs\configmanager\ConfigManager', $this->config); + + $this->assertFileExists($this->configFile); + $this->config->loadConfig($this->configFile); + } +} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/tests/FileConverterTest.php b/vendor/clagiordano/weblibs-configmanager/tests/FileConverterTest.php new file mode 100644 index 0000000..1522614 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/tests/FileConverterTest.php @@ -0,0 +1,148 @@ +config = new JsonConfigManager("TestConfigData.json"); + $this->assertInstanceOf('clagiordano\weblibs\configmanager\JsonConfigManager', $this->config); + + $this->assertFileExists($this->configFile); + $this->config->loadConfig($this->configFile); + } +} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/tests/YamlConfigManagerTest.php b/vendor/clagiordano/weblibs-configmanager/tests/YamlConfigManagerTest.php new file mode 100644 index 0000000..d5df626 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/tests/YamlConfigManagerTest.php @@ -0,0 +1,25 @@ +config = new YamlConfigManager("TestConfigData.yml"); + $this->assertInstanceOf('clagiordano\weblibs\configmanager\YamlConfigManager', $this->config); + + $this->assertFileExists($this->configFile); + $this->config->loadConfig($this->configFile); + } +} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.empty.converted.yml b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.empty.converted.yml new file mode 100644 index 0000000..6578fd5 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.empty.converted.yml @@ -0,0 +1 @@ +{ } diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json new file mode 100644 index 0000000..126dd63 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json @@ -0,0 +1 @@ +{"app":"name","db":{"host":"localhost","user":"sample_user","pass":"sample_pass","port":"3306"},"other":{"multi":{"deep":{"nested":"config_value"}}}} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json.converted.php b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json.converted.php new file mode 100644 index 0000000..ce32a66 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json.converted.php @@ -0,0 +1,23 @@ + 'name', + 'db' => + array ( + 'host' => 'localhost', + 'user' => 'sample_user', + 'pass' => 'sample_pass', + 'port' => '3306', + ), + 'other' => + array ( + 'multi' => + array ( + 'deep' => + array ( + 'nested' => 'config_value', + ), + ), + ), +); + diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json.converted.yml b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json.converted.yml new file mode 100644 index 0000000..3f1a03e --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.json.converted.yml @@ -0,0 +1,8 @@ +app: name +db: + host: localhost + user: sample_user + pass: sample_pass + port: '3306' +other: + multi: { deep: { nested: config_value } } diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php new file mode 100644 index 0000000..4a99ef0 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php @@ -0,0 +1,23 @@ + 'app_name', + 'db' => + array ( + 'host' => 'localhost', + 'user' => 'sample_user', + 'pass' => 'sample_pass', + 'port' => 3306, + ), + 'other' => + array ( + 'multi' => + array ( + 'deep' => + array ( + 'nested' => 'config_value', + ), + ), + ), +); + diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php.converted.json b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php.converted.json new file mode 100644 index 0000000..5b14b3d --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php.converted.json @@ -0,0 +1 @@ +{"app":"app_name","db":{"host":"localhost","user":"sample_user","pass":"sample_pass","port":3306},"other":{"multi":{"deep":{"nested":"config_value"}}}} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php.converted.yml b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php.converted.yml new file mode 100644 index 0000000..1de87d7 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.php.converted.yml @@ -0,0 +1,8 @@ +app: app_name +db: + host: localhost + user: sample_user + pass: sample_pass + port: 3306 +other: + multi: { deep: { nested: config_value } } diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml new file mode 100644 index 0000000..f67a753 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml @@ -0,0 +1,8 @@ +app: name +db: + host: localhost + user: sample_user + pass: sample_pass + port: 3306 +other: + multi: { deep: { nested: config_value } } diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml.converted.json b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml.converted.json new file mode 100644 index 0000000..f271831 --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml.converted.json @@ -0,0 +1 @@ +{"app":"name","db":{"host":"localhost","user":"sample_user","pass":"sample_pass","port":3306},"other":{"multi":{"deep":{"nested":"config_value"}}}} \ No newline at end of file diff --git a/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml.converted.php b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml.converted.php new file mode 100644 index 0000000..770b0da --- /dev/null +++ b/vendor/clagiordano/weblibs-configmanager/testsdata/sample_config_data.yml.converted.php @@ -0,0 +1,23 @@ + 'name', + 'db' => + array ( + 'host' => 'localhost', + 'user' => 'sample_user', + 'pass' => 'sample_pass', + 'port' => 3306, + ), + 'other' => + array ( + 'multi' => + array ( + 'deep' => + array ( + 'nested' => 'config_value', + ), + ), + ), +); + diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 48d254f..b33aedc 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -11,8 +11,12 @@ return array( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', + 'd767e4fc2dc52fe66584ab8c6684783e' => $vendorDir . '/adbario/php-dot-notation/src/helpers.php', '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', + 'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php', + '66453932bc1be9fb2f910a27947d11b6' => $vendorDir . '/alibabacloud/client/src/Functions.php', 'f0e7e63bbb278a92db02393536748c5f' => $vendorDir . '/overtrue/wechat/src/Kernel/Support/Helpers.php', '6747f579ad6817f318cc3a7e7a0abb93' => $vendorDir . '/overtrue/wechat/src/Kernel/Helpers.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 552138c..796e16c 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -8,14 +8,17 @@ $baseDir = dirname($vendorDir); return array( 'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'), 'think\\' => array($baseDir . '/thinkphp/library/think'), + 'clagiordano\\weblibs\\configmanager\\' => array($vendorDir . '/clagiordano/weblibs-configmanager/src'), 'app\\' => array($baseDir . '/application'), 'ZipStream\\' => array($vendorDir . '/maennchen/zipstream-php/src'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), 'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'), 'Symfony\\Contracts\\Cache\\' => array($vendorDir . '/symfony/cache-contracts'), + 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), 'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'), 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), @@ -34,10 +37,13 @@ return array( 'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'Matrix\\' => array($vendorDir . '/markbaker/matrix/classes/src'), + 'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'EasyWeChat\\' => array($vendorDir . '/overtrue/wechat/src'), 'EasyWeChatComposer\\' => array($vendorDir . '/easywechat-composer/easywechat-composer/src'), 'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'), + 'AlibabaCloud\\Client\\' => array($vendorDir . '/alibabacloud/client/src'), + 'Adbar\\' => array($vendorDir . '/adbario/php-dot-notation/src'), ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index dacd858..0f40fd4 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -12,8 +12,12 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', + 'd767e4fc2dc52fe66584ab8c6684783e' => __DIR__ . '/..' . '/adbario/php-dot-notation/src/helpers.php', '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', + 'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php', + '66453932bc1be9fb2f910a27947d11b6' => __DIR__ . '/..' . '/alibabacloud/client/src/Functions.php', 'f0e7e63bbb278a92db02393536748c5f' => __DIR__ . '/..' . '/overtrue/wechat/src/Kernel/Support/Helpers.php', '6747f579ad6817f318cc3a7e7a0abb93' => __DIR__ . '/..' . '/overtrue/wechat/src/Kernel/Helpers.php', ); @@ -24,6 +28,10 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd 'think\\composer\\' => 15, 'think\\' => 6, ), + 'c' => + array ( + 'clagiordano\\weblibs\\configmanager\\' => 34, + ), 'a' => array ( 'app\\' => 4, @@ -37,9 +45,11 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd 'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Php73\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Polyfill\\Ctype\\' => 23, 'Symfony\\Contracts\\Service\\' => 26, 'Symfony\\Contracts\\EventDispatcher\\' => 34, 'Symfony\\Contracts\\Cache\\' => 24, + 'Symfony\\Component\\Yaml\\' => 23, 'Symfony\\Component\\VarExporter\\' => 30, 'Symfony\\Component\\HttpFoundation\\' => 33, 'Symfony\\Component\\EventDispatcher\\' => 34, @@ -68,6 +78,10 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd 'Monolog\\' => 8, 'Matrix\\' => 7, ), + 'J' => + array ( + 'JmesPath\\' => 9, + ), 'G' => array ( 'GuzzleHttp\\Psr7\\' => 16, @@ -83,6 +97,11 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd array ( 'Complex\\' => 8, ), + 'A' => + array ( + 'AlibabaCloud\\Client\\' => 20, + 'Adbar\\' => 6, + ), ); public static $prefixDirsPsr4 = array ( @@ -94,6 +113,10 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd array ( 0 => __DIR__ . '/../..' . '/thinkphp/library/think', ), + 'clagiordano\\weblibs\\configmanager\\' => + array ( + 0 => __DIR__ . '/..' . '/clagiordano/weblibs-configmanager/src', + ), 'app\\' => array ( 0 => __DIR__ . '/../..' . '/application', @@ -114,6 +137,10 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), 'Symfony\\Contracts\\Service\\' => array ( 0 => __DIR__ . '/..' . '/symfony/service-contracts', @@ -126,6 +153,10 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd array ( 0 => __DIR__ . '/..' . '/symfony/cache-contracts', ), + 'Symfony\\Component\\Yaml\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/yaml', + ), 'Symfony\\Component\\VarExporter\\' => array ( 0 => __DIR__ . '/..' . '/symfony/var-exporter', @@ -199,6 +230,10 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd array ( 0 => __DIR__ . '/..' . '/markbaker/matrix/classes/src', ), + 'JmesPath\\' => + array ( + 0 => __DIR__ . '/..' . '/mtdowling/jmespath.php/src', + ), 'GuzzleHttp\\Psr7\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', @@ -223,6 +258,14 @@ class ComposerStaticInit2bc4f313dba415539e266f7ac2c87dcd array ( 0 => __DIR__ . '/..' . '/markbaker/complex/classes/src', ), + 'AlibabaCloud\\Client\\' => + array ( + 0 => __DIR__ . '/..' . '/alibabacloud/client/src', + ), + 'Adbar\\' => + array ( + 0 => __DIR__ . '/..' . '/adbario/php-dot-notation/src', + ), ); public static $prefixesPsr0 = array ( diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index a94f8c4..294caa2 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,5 +1,206 @@ { "packages": [ + { + "name": "adbario/php-dot-notation", + "version": "2.5.0", + "version_normalized": "2.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/adbario/php-dot-notation.git", + "reference": "081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/adbario/php-dot-notation/zipball/081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae", + "reference": "081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "time": "2022-10-14T20:31:46+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Adbar\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Riku Särkinen", + "email": "riku@adbar.io" + } + ], + "description": "PHP dot notation access to arrays", + "homepage": "https://github.com/adbario/php-dot-notation", + "keywords": [ + "ArrayAccess", + "dotnotation" + ], + "support": { + "issues": "https://github.com/adbario/php-dot-notation/issues", + "source": "https://github.com/adbario/php-dot-notation/tree/2.5.0" + }, + "install-path": "../adbario/php-dot-notation" + }, + { + "name": "alibabacloud/client", + "version": "1.5.32", + "version_normalized": "1.5.32.0", + "source": { + "type": "git", + "url": "https://github.com/aliyun/openapi-sdk-php-client.git", + "reference": "5bc6f6d660797dcee2c3aef29700ab41ee764f4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aliyun/openapi-sdk-php-client/zipball/5bc6f6d660797dcee2c3aef29700ab41ee764f4d", + "reference": "5bc6f6d660797dcee2c3aef29700ab41ee764f4d", + "shasum": "" + }, + "require": { + "adbario/php-dot-notation": "^2.4.1", + "clagiordano/weblibs-configmanager": "^1.0", + "ext-curl": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "ext-xmlwriter": "*", + "guzzlehttp/guzzle": "^6.3|^7.0", + "mtdowling/jmespath.php": "^2.5", + "php": ">=5.5" + }, + "require-dev": { + "composer/composer": "^1.8", + "drupal/coder": "^8.3", + "ext-dom": "*", + "ext-pcre": "*", + "ext-sockets": "*", + "ext-spl": "*", + "league/climate": "^3.2.4", + "mikey179/vfsstream": "^1.6", + "monolog/monolog": "^1.24", + "phpunit/phpunit": "^5.7|^6.6|^7.5|^8.5|^9.5", + "psr/cache": "^1.0", + "symfony/dotenv": "^3.4", + "symfony/var-dumper": "^3.4" + }, + "suggest": { + "ext-sockets": "To use client-side monitoring" + }, + "time": "2022-12-09T04:05:55+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "AlibabaCloud\\Client\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Alibaba Cloud SDK", + "email": "sdk-team@alibabacloud.com", + "homepage": "http://www.alibabacloud.com" + } + ], + "description": "Alibaba Cloud Client for PHP - Use Alibaba Cloud in your PHP project", + "homepage": "https://www.alibabacloud.com/", + "keywords": [ + "alibaba", + "alibabacloud", + "aliyun", + "client", + "cloud", + "library", + "sdk", + "tool" + ], + "support": { + "issues": "https://github.com/aliyun/openapi-sdk-php-client/issues", + "source": "https://github.com/aliyun/openapi-sdk-php-client" + }, + "install-path": "../alibabacloud/client" + }, + { + "name": "clagiordano/weblibs-configmanager", + "version": "v1.5.0", + "version_normalized": "1.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/clagiordano/weblibs-configmanager.git", + "reference": "8802c7396d61a923c9a73e37ead062b24bb1b273" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clagiordano/weblibs-configmanager/zipball/8802c7396d61a923c9a73e37ead062b24bb1b273", + "reference": "8802c7396d61a923c9a73e37ead062b24bb1b273", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.4", + "symfony/yaml": "^2.8" + }, + "require-dev": { + "clagiordano/phpunit-result-printer": "^1", + "php-coveralls/php-coveralls": "^1.1", + "phpunit/phpunit": "^4.8" + }, + "time": "2021-07-12T15:27:21+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "clagiordano\\weblibs\\configmanager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Claudio Giordano", + "email": "claudio.giordano@autistici.org", + "role": "Developer" + } + ], + "description": "weblibs-configmanager is a tool library for easily read and access to php config array file and direct read/write configuration file / object", + "keywords": [ + "clagiordano", + "configuration", + "manager", + "tool", + "weblibs" + ], + "support": { + "issues": "https://github.com/clagiordano/weblibs-configmanager/issues", + "source": "https://github.com/clagiordano/weblibs-configmanager/tree/v1.5.0" + }, + "install-path": "../clagiordano/weblibs-configmanager" + }, { "name": "easywechat-composer/easywechat-composer", "version": "1.4.1", @@ -733,6 +934,75 @@ ], "install-path": "../monolog/monolog" }, + { + "name": "mtdowling/jmespath.php", + "version": "2.8.0", + "version_normalized": "2.8.0.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.33" + }, + "time": "2024-09-04T18:46:31+00:00", + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" + }, + "install-path": "../mtdowling/jmespath.php" + }, { "name": "myclabs/php-enum", "version": "1.8.5", @@ -2161,6 +2431,88 @@ ], "install-path": "../symfony/http-foundation" }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2024-09-09T11:45:10+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-ctype" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.31.0", @@ -2638,6 +2990,62 @@ ], "install-path": "../symfony/var-exporter" }, + { + "name": "symfony/yaml", + "version": "v2.8.52", + "version_normalized": "2.8.52.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "02c1859112aa779d9ab394ae4f3381911d84052b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b", + "reference": "02c1859112aa779d9ab394ae4f3381911d84052b", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" + }, + "time": "2018-11-11T11:18:13+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v2.8.52" + }, + "install-path": "../symfony/yaml" + }, { "name": "topthink/framework", "version": "v5.0.25", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index a333b59..042b670 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,13 +3,40 @@ 'name' => 'topthink/think', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'c9296ecb2ae6905df00593530a8784f2997e182a', + 'reference' => '075de7502013b216a11f34847a1a98600f4eab80', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => true, ), 'versions' => array( + 'adbario/php-dot-notation' => array( + 'pretty_version' => '2.5.0', + 'version' => '2.5.0.0', + 'reference' => '081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae', + 'type' => 'library', + 'install_path' => __DIR__ . '/../adbario/php-dot-notation', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'alibabacloud/client' => array( + 'pretty_version' => '1.5.32', + 'version' => '1.5.32.0', + 'reference' => '5bc6f6d660797dcee2c3aef29700ab41ee764f4d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../alibabacloud/client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'clagiordano/weblibs-configmanager' => array( + 'pretty_version' => 'v1.5.0', + 'version' => '1.5.0.0', + 'reference' => '8802c7396d61a923c9a73e37ead062b24bb1b273', + 'type' => 'library', + 'install_path' => __DIR__ . '/../clagiordano/weblibs-configmanager', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'easywechat-composer/easywechat-composer' => array( 'pretty_version' => '1.4.1', 'version' => '1.4.1.0', @@ -91,6 +118,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'mtdowling/jmespath.php' => array( + 'pretty_version' => '2.8.0', + 'version' => '2.8.0.0', + 'reference' => 'a2a865e05d5f420b50cc2f85bb78d565db12a6bc', + 'type' => 'library', + 'install_path' => __DIR__ . '/../mtdowling/jmespath.php', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'myclabs/php-enum' => array( 'pretty_version' => '1.8.5', 'version' => '1.8.5.0', @@ -334,6 +370,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'symfony/polyfill-ctype' => array( + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'symfony/polyfill-mbstring' => array( 'pretty_version' => 'v1.31.0', 'version' => '1.31.0.0', @@ -388,6 +433,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'symfony/yaml' => array( + 'pretty_version' => 'v2.8.52', + 'version' => '2.8.52.0', + 'reference' => '02c1859112aa779d9ab394ae4f3381911d84052b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/yaml', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'topthink/framework' => array( 'pretty_version' => 'v5.0.25', 'version' => '5.0.25.0', @@ -400,7 +454,7 @@ 'topthink/think' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'c9296ecb2ae6905df00593530a8784f2997e182a', + 'reference' => '075de7502013b216a11f34847a1a98600f4eab80', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/vendor/composer/tmp-0d89f9d50873e2b671afca887218e9a9.zip b/vendor/composer/tmp-0d89f9d50873e2b671afca887218e9a9.zip new file mode 100644 index 0000000..2f44a96 Binary files /dev/null and b/vendor/composer/tmp-0d89f9d50873e2b671afca887218e9a9.zip differ diff --git a/vendor/composer/tmp-11bd46d6ad5fb797d29f33bd14df708f.zip b/vendor/composer/tmp-11bd46d6ad5fb797d29f33bd14df708f.zip new file mode 100644 index 0000000..0a15821 Binary files /dev/null and b/vendor/composer/tmp-11bd46d6ad5fb797d29f33bd14df708f.zip differ diff --git a/vendor/composer/tmp-185e2e1130562592323350064f87dc41.zip b/vendor/composer/tmp-185e2e1130562592323350064f87dc41.zip new file mode 100644 index 0000000..5c888e6 Binary files /dev/null and b/vendor/composer/tmp-185e2e1130562592323350064f87dc41.zip differ diff --git a/vendor/composer/tmp-1cedc34bfc11a3f9d8f81bd371c876b7.zip b/vendor/composer/tmp-1cedc34bfc11a3f9d8f81bd371c876b7.zip new file mode 100644 index 0000000..949c39a Binary files /dev/null and b/vendor/composer/tmp-1cedc34bfc11a3f9d8f81bd371c876b7.zip differ diff --git a/vendor/composer/tmp-338cc0e5dd9ea4bc29607333cd7b4391.zip b/vendor/composer/tmp-338cc0e5dd9ea4bc29607333cd7b4391.zip new file mode 100644 index 0000000..62500d6 Binary files /dev/null and b/vendor/composer/tmp-338cc0e5dd9ea4bc29607333cd7b4391.zip differ diff --git a/vendor/composer/tmp-3ebeb41130f84ba2032b1084e6524a3c.zip b/vendor/composer/tmp-3ebeb41130f84ba2032b1084e6524a3c.zip new file mode 100644 index 0000000..1bb3217 Binary files /dev/null and b/vendor/composer/tmp-3ebeb41130f84ba2032b1084e6524a3c.zip differ diff --git a/vendor/composer/tmp-3f03c748e5fc44451f326e397d84bdda.zip b/vendor/composer/tmp-3f03c748e5fc44451f326e397d84bdda.zip new file mode 100644 index 0000000..868b92d Binary files /dev/null and b/vendor/composer/tmp-3f03c748e5fc44451f326e397d84bdda.zip differ diff --git a/vendor/composer/tmp-6035caee003b977efbee6d168b1d39d6.zip b/vendor/composer/tmp-6035caee003b977efbee6d168b1d39d6.zip new file mode 100644 index 0000000..491e879 Binary files /dev/null and b/vendor/composer/tmp-6035caee003b977efbee6d168b1d39d6.zip differ diff --git a/vendor/composer/tmp-868cb9b266141e3de46d548426dbc528.zip b/vendor/composer/tmp-868cb9b266141e3de46d548426dbc528.zip new file mode 100644 index 0000000..7f5752b Binary files /dev/null and b/vendor/composer/tmp-868cb9b266141e3de46d548426dbc528.zip differ diff --git a/vendor/composer/tmp-9134025c6dbadb951eb046127f1f5364.zip b/vendor/composer/tmp-9134025c6dbadb951eb046127f1f5364.zip new file mode 100644 index 0000000..0bfe2a1 Binary files /dev/null and b/vendor/composer/tmp-9134025c6dbadb951eb046127f1f5364.zip differ diff --git a/vendor/composer/tmp-94532157512dc59bf8b610437634e2a4.zip b/vendor/composer/tmp-94532157512dc59bf8b610437634e2a4.zip new file mode 100644 index 0000000..8031fbb Binary files /dev/null and b/vendor/composer/tmp-94532157512dc59bf8b610437634e2a4.zip differ diff --git a/vendor/composer/tmp-99302efaebda931b517195a791313ef8.zip b/vendor/composer/tmp-99302efaebda931b517195a791313ef8.zip new file mode 100644 index 0000000..563b44f Binary files /dev/null and b/vendor/composer/tmp-99302efaebda931b517195a791313ef8.zip differ diff --git a/vendor/composer/tmp-a6057dce91728e10f22de5e655c6e00e.zip b/vendor/composer/tmp-a6057dce91728e10f22de5e655c6e00e.zip new file mode 100644 index 0000000..cec3736 Binary files /dev/null and b/vendor/composer/tmp-a6057dce91728e10f22de5e655c6e00e.zip differ diff --git a/vendor/composer/tmp-a73fdcdc269de69f83a925078c1a3644.zip b/vendor/composer/tmp-a73fdcdc269de69f83a925078c1a3644.zip new file mode 100644 index 0000000..7d65ffb Binary files /dev/null and b/vendor/composer/tmp-a73fdcdc269de69f83a925078c1a3644.zip differ diff --git a/vendor/composer/tmp-aa47308983a1bc8aeb55dacdc9850d3f.zip b/vendor/composer/tmp-aa47308983a1bc8aeb55dacdc9850d3f.zip new file mode 100644 index 0000000..b7e54b4 Binary files /dev/null and b/vendor/composer/tmp-aa47308983a1bc8aeb55dacdc9850d3f.zip differ diff --git a/vendor/composer/tmp-af09a518796d0690ac8df9e3a0199608.zip b/vendor/composer/tmp-af09a518796d0690ac8df9e3a0199608.zip new file mode 100644 index 0000000..7d9fe5d Binary files /dev/null and b/vendor/composer/tmp-af09a518796d0690ac8df9e3a0199608.zip differ diff --git a/vendor/composer/tmp-b83c750f78e552370e127ad91cd261d7.zip b/vendor/composer/tmp-b83c750f78e552370e127ad91cd261d7.zip new file mode 100644 index 0000000..8bb909b Binary files /dev/null and b/vendor/composer/tmp-b83c750f78e552370e127ad91cd261d7.zip differ diff --git a/vendor/composer/tmp-bef10698d08d7377ba6a9f1ddd51f4a2.zip b/vendor/composer/tmp-bef10698d08d7377ba6a9f1ddd51f4a2.zip new file mode 100644 index 0000000..53e9dfc Binary files /dev/null and b/vendor/composer/tmp-bef10698d08d7377ba6a9f1ddd51f4a2.zip differ diff --git a/vendor/composer/tmp-cd9141dac2afb7b49ce07d6840fae829.zip b/vendor/composer/tmp-cd9141dac2afb7b49ce07d6840fae829.zip new file mode 100644 index 0000000..3dbd269 Binary files /dev/null and b/vendor/composer/tmp-cd9141dac2afb7b49ce07d6840fae829.zip differ diff --git a/vendor/composer/tmp-d7cc8f81e79ee376b003f9d3e3af9377.zip b/vendor/composer/tmp-d7cc8f81e79ee376b003f9d3e3af9377.zip new file mode 100644 index 0000000..646e96c Binary files /dev/null and b/vendor/composer/tmp-d7cc8f81e79ee376b003f9d3e3af9377.zip differ diff --git a/vendor/composer/tmp-ea5cdecfcc51eee59532763ea9174b88.zip b/vendor/composer/tmp-ea5cdecfcc51eee59532763ea9174b88.zip new file mode 100644 index 0000000..32da2dd Binary files /dev/null and b/vendor/composer/tmp-ea5cdecfcc51eee59532763ea9174b88.zip differ diff --git a/vendor/composer/tmp-eca084e2dbf08109c2e37ffa612ea741.zip b/vendor/composer/tmp-eca084e2dbf08109c2e37ffa612ea741.zip new file mode 100644 index 0000000..c816651 Binary files /dev/null and b/vendor/composer/tmp-eca084e2dbf08109c2e37ffa612ea741.zip differ diff --git a/vendor/composer/tmp-eec490a45e0693df49b82d39c08aa787.zip b/vendor/composer/tmp-eec490a45e0693df49b82d39c08aa787.zip new file mode 100644 index 0000000..5df63a5 Binary files /dev/null and b/vendor/composer/tmp-eec490a45e0693df49b82d39c08aa787.zip differ diff --git a/vendor/composer/tmp-f98849c5d167261732a8553ca35822d1.zip b/vendor/composer/tmp-f98849c5d167261732a8553ca35822d1.zip new file mode 100644 index 0000000..ee9e89f Binary files /dev/null and b/vendor/composer/tmp-f98849c5d167261732a8553ca35822d1.zip differ diff --git a/vendor/mtdowling/jmespath.php/CHANGELOG.md b/vendor/mtdowling/jmespath.php/CHANGELOG.md new file mode 100644 index 0000000..4eedf74 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/CHANGELOG.md @@ -0,0 +1,72 @@ +# CHANGELOG + +## 2.8.0 - 2024-09-04 + +* Add support for PHP 8.4. + +## 2.7.0 - 2023-08-15 + +* Fixed flattening in arrays starting with null. +* Drop support for HHVM and PHP earlier than 7.2.5. +* Add support for PHP 8.1, 8.2, and 8.3. + +## 2.6.0 - 2020-07-31 + +* Support for PHP 8.0. + +## 2.5.0 - 2019-12-30 + +* Full support for PHP 7.0-7.4. +* Fixed autoloading when run from within vendor folder. +* Full multibyte (UTF-8) string support. + +## 2.4.0 - 2016-12-03 + +* Added support for floats when interpreting data. +* Added a function_exists check to work around redeclaration issues. + +## 2.3.0 - 2016-01-05 + +* Added support for [JEP-9](https://github.com/jmespath/jmespath.site/blob/master/docs/proposals/improved-filters.rst), + including unary filter expressions, and `&&` filter expressions. +* Fixed various parsing issues, including not removing escaped single quotes + from raw string literals. +* Added support for the `map` function. +* Fixed several issues with code generation. + +## 2.2.0 - 2015-05-27 + +* Added support for [JEP-12](https://github.com/jmespath/jmespath.site/blob/master/docs/proposals/raw-string-literals.rst) + and raw string literals (e.g., `'foo'`). + +## 2.1.0 - 2014-01-13 + +* Added `JmesPath\Env::cleanCompileDir()` to delete any previously compiled + JMESPath expressions. + +## 2.0.0 - 2014-01-11 + +* Moving to a flattened namespace structure. +* Runtimes are now only PHP callables. +* Fixed an error in the way empty JSON literals are parsed so that they now + return an empty string to match the Python and JavaScript implementations. +* Removed functions from runtimes. Instead there is now a function dispatcher + class, FnDispatcher, that provides function implementations behind a single + dispatch function. +* Removed ExprNode in lieu of just using a PHP callable with bound variables. +* Removed debug methods from runtimes and instead into a new Debugger class. +* Heavily cleaned up function argument validation. +* Slice syntax is now properly validated (i.e., colons are followed by the + appropriate value). +* Lots of code cleanup and performance improvements. +* Added a convenient `JmesPath\search()` function. +* **IMPORTANT**: Relocating the project to https://github.com/jmespath/jmespath.php + +## 1.1.1 - 2014-10-08 + +* Added support for using ArrayAccess and Countable as arrays and objects. + +## 1.1.0 - 2014-08-06 + +* Added the ability to search data returned from json_decode() where JSON + objects are returned as stdClass objects. diff --git a/vendor/mtdowling/jmespath.php/LICENSE b/vendor/mtdowling/jmespath.php/LICENSE new file mode 100644 index 0000000..5c970a4 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Michael Dowling, https://github.com/mtdowling + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/mtdowling/jmespath.php/README.rst b/vendor/mtdowling/jmespath.php/README.rst new file mode 100644 index 0000000..bef8db4 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/README.rst @@ -0,0 +1,123 @@ +============ +jmespath.php +============ + +JMESPath (pronounced "jaymz path") allows you to declaratively specify how to +extract elements from a JSON document. *jmespath.php* allows you to use +JMESPath in PHP applications with PHP data structures. It requires PHP 7.2.5 or +greater and can be installed through `Composer `_ +using the ``mtdowling/jmespath.php`` package. + +.. code-block:: php + + require 'vendor/autoload.php'; + + $expression = 'foo.*.baz'; + + $data = [ + 'foo' => [ + 'bar' => ['baz' => 1], + 'bam' => ['baz' => 2], + 'boo' => ['baz' => 3] + ] + ]; + + JmesPath\search($expression, $data); + // Returns: [1, 2, 3] + +- `JMESPath Tutorial `_ +- `JMESPath Grammar `_ +- `JMESPath Python library `_ + +PHP Usage +========= + +The ``JmesPath\search`` function can be used in most cases when using the +library. This function utilizes a JMESPath runtime based on your environment. +The runtime utilized can be configured using environment variables and may at +some point in the future automatically utilize a C extension if available. + +.. code-block:: php + + $result = JmesPath\search($expression, $data); + + // or, if you require PSR-4 compliance. + $result = JmesPath\Env::search($expression, $data); + +Runtimes +-------- + +jmespath.php utilizes *runtimes*. There are currently two runtimes: +AstRuntime and CompilerRuntime. + +AstRuntime is utilized by ``JmesPath\search()`` and ``JmesPath\Env::search()`` +by default. + +AstRuntime +~~~~~~~~~~ + +The AstRuntime will parse an expression, cache the resulting AST in memory, +and interpret the AST using an external tree visitor. AstRuntime provides a +good general approach for interpreting JMESPath expressions that have a low to +moderate level of reuse. + +.. code-block:: php + + $runtime = new JmesPath\AstRuntime(); + $runtime('foo.bar', ['foo' => ['bar' => 'baz']]); + // > 'baz' + +CompilerRuntime +~~~~~~~~~~~~~~~ + +``JmesPath\CompilerRuntime`` provides the most performance for +applications that have a moderate to high level of reuse of JMESPath +expressions. The CompilerRuntime will walk a JMESPath AST and emit PHP source +code, resulting in anywhere from 7x to 60x speed improvements. + +Compiling JMESPath expressions to source code is a slower process than just +walking and interpreting a JMESPath AST (via the AstRuntime). However, +running the compiled JMESPath code results in much better performance than +walking an AST. This essentially means that there is a warm-up period when +using the ``CompilerRuntime``, but after the warm-up period, it will provide +much better performance. + +Use the CompilerRuntime if you know that you will be executing JMESPath +expressions more than once or if you can pre-compile JMESPath expressions +before executing them (for example, server-side applications). + +.. code-block:: php + + // Note: The cache directory argument is optional. + $runtime = new JmesPath\CompilerRuntime('/path/to/compile/folder'); + $runtime('foo.bar', ['foo' => ['bar' => 'baz']]); + // > 'baz' + +Environment Variables +^^^^^^^^^^^^^^^^^^^^^ + +You can utilize the CompilerRuntime in ``JmesPath\search()`` by setting +the ``JP_PHP_COMPILE`` environment variable to "on" or to a directory +on disk used to store cached expressions. + +Testing +======= + +A comprehensive list of test cases can be found at +https://github.com/jmespath/jmespath.php/tree/master/tests/compliance. +These compliance tests are utilized by jmespath.php to ensure consistency with +other implementations, and can serve as examples of the language. + +jmespath.php is tested using PHPUnit. In order to run the tests, you need to +first install the dependencies using Composer as described in the *Installation* +section. Next you just need to run the tests via make: + +.. code-block:: bash + + make test + +You can run a suite of performance tests as well: + +.. code-block:: bash + + make perf diff --git a/vendor/mtdowling/jmespath.php/bin/jp.php b/vendor/mtdowling/jmespath.php/bin/jp.php new file mode 100644 index 0000000..c8433b5 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/bin/jp.php @@ -0,0 +1,74 @@ +#!/usr/bin/env php +check(); +unset($xdebug); + +$dir = isset($argv[1]) ? $argv[1] : __DIR__ . '/../tests/compliance/perf'; +is_dir($dir) or die('Dir not found: ' . $dir); +// Warm up the runner +\JmesPath\Env::search('foo', []); + +$total = 0; +foreach (glob($dir . '/*.json') as $file) { + $total += runSuite($file); +} +echo "\nTotal time: {$total}\n"; + +function runSuite($file) +{ + $contents = file_get_contents($file); + $json = json_decode($contents, true); + $total = 0; + foreach ($json as $suite) { + foreach ($suite['cases'] as $case) { + $total += runCase( + $suite['given'], + $case['expression'], + $case['name'] + ); + } + } + return $total; +} + +function runCase($given, $expression, $name) +{ + $best = 99999; + $runtime = \JmesPath\Env::createRuntime(); + + for ($i = 0; $i < 100; $i++) { + $t = microtime(true); + $runtime($expression, $given); + $tryTime = (microtime(true) - $t) * 1000; + if ($tryTime < $best) { + $best = $tryTime; + } + if (!getenv('CACHE')) { + $runtime = \JmesPath\Env::createRuntime(); + // Delete compiled scripts if not caching. + if ($runtime instanceof \JmesPath\CompilerRuntime) { + array_map('unlink', glob(sys_get_temp_dir() . '/jmespath_*.php')); + } + } + } + + printf("time: %07.4fms name: %s\n", $best, $name); + + return $best; +} diff --git a/vendor/mtdowling/jmespath.php/composer.json b/vendor/mtdowling/jmespath.php/composer.json new file mode 100644 index 0000000..819db12 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/composer.json @@ -0,0 +1,38 @@ +{ + "name": "mtdowling/jmespath.php", + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": ["json", "jsonpath"], + "license": "MIT", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.33" + }, + "autoload": { + "psr-4": { + "JmesPath\\": "src/" + }, + "files": ["src/JmesPath.php"] + }, + "bin": ["bin/jp.php"], + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + } +} diff --git a/vendor/mtdowling/jmespath.php/src/AstRuntime.php b/vendor/mtdowling/jmespath.php/src/AstRuntime.php new file mode 100644 index 0000000..f5620be --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/AstRuntime.php @@ -0,0 +1,47 @@ +interpreter = new TreeInterpreter($fnDispatcher); + $this->parser = $parser ?: new Parser(); + } + + /** + * Returns data from the provided input that matches a given JMESPath + * expression. + * + * @param string $expression JMESPath expression to evaluate + * @param mixed $data Data to search. This data should be data that + * is similar to data returned from json_decode + * using associative arrays rather than objects. + * + * @return mixed Returns the matching data or null + */ + public function __invoke($expression, $data) + { + if (!isset($this->cache[$expression])) { + // Clear the AST cache when it hits 1024 entries + if (++$this->cachedCount > 1024) { + $this->cache = []; + $this->cachedCount = 0; + } + $this->cache[$expression] = $this->parser->parse($expression); + } + + return $this->interpreter->visit($this->cache[$expression], $data); + } +} diff --git a/vendor/mtdowling/jmespath.php/src/CompilerRuntime.php b/vendor/mtdowling/jmespath.php/src/CompilerRuntime.php new file mode 100644 index 0000000..b85f68e --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/CompilerRuntime.php @@ -0,0 +1,83 @@ +parser = $parser ?: new Parser(); + $this->compiler = new TreeCompiler(); + $dir = $dir ?: sys_get_temp_dir(); + + if (!is_dir($dir) && !mkdir($dir, 0755, true)) { + throw new \RuntimeException("Unable to create cache directory: $dir"); + } + + $this->cacheDir = realpath($dir); + $this->interpreter = new TreeInterpreter(); + } + + /** + * Returns data from the provided input that matches a given JMESPath + * expression. + * + * @param string $expression JMESPath expression to evaluate + * @param mixed $data Data to search. This data should be data that + * is similar to data returned from json_decode + * using associative arrays rather than objects. + * + * @return mixed Returns the matching data or null + * @throws \RuntimeException + */ + public function __invoke($expression, $data) + { + $functionName = 'jmespath_' . md5($expression); + + if (!function_exists($functionName)) { + $filename = "{$this->cacheDir}/{$functionName}.php"; + if (!file_exists($filename)) { + $this->compile($filename, $expression, $functionName); + } + require $filename; + } + + return $functionName($this->interpreter, $data); + } + + private function compile($filename, $expression, $functionName) + { + $code = $this->compiler->visit( + $this->parser->parse($expression), + $functionName, + $expression + ); + + if (!file_put_contents($filename, $code)) { + throw new \RuntimeException(sprintf( + 'Unable to write the compiled PHP code to: %s (%s)', + $filename, + var_export(error_get_last(), true) + )); + } + } +} diff --git a/vendor/mtdowling/jmespath.php/src/DebugRuntime.php b/vendor/mtdowling/jmespath.php/src/DebugRuntime.php new file mode 100644 index 0000000..4052561 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/DebugRuntime.php @@ -0,0 +1,109 @@ +runtime = $runtime; + $this->out = $output ?: STDOUT; + $this->lexer = new Lexer(); + $this->parser = new Parser($this->lexer); + } + + public function __invoke($expression, $data) + { + if ($this->runtime instanceof CompilerRuntime) { + return $this->debugCompiled($expression, $data); + } + + return $this->debugInterpreted($expression, $data); + } + + private function debugInterpreted($expression, $data) + { + return $this->debugCallback( + function () use ($expression, $data) { + $runtime = $this->runtime; + return $runtime($expression, $data); + }, + $expression, + $data + ); + } + + private function debugCompiled($expression, $data) + { + $result = $this->debugCallback( + function () use ($expression, $data) { + $runtime = $this->runtime; + return $runtime($expression, $data); + }, + $expression, + $data + ); + $this->dumpCompiledCode($expression); + + return $result; + } + + private function dumpTokens($expression) + { + $lexer = new Lexer(); + fwrite($this->out, "Tokens\n======\n\n"); + $tokens = $lexer->tokenize($expression); + + foreach ($tokens as $t) { + fprintf( + $this->out, + "%3d %-13s %s\n", $t['pos'], $t['type'], + json_encode($t['value']) + ); + } + + fwrite($this->out, "\n"); + } + + private function dumpAst($expression) + { + $parser = new Parser(); + $ast = $parser->parse($expression); + fwrite($this->out, "AST\n========\n\n"); + fwrite($this->out, json_encode($ast, JSON_PRETTY_PRINT) . "\n"); + } + + private function dumpCompiledCode($expression) + { + fwrite($this->out, "Code\n========\n\n"); + $dir = sys_get_temp_dir(); + $hash = md5($expression); + $functionName = "jmespath_{$hash}"; + $filename = "{$dir}/{$functionName}.php"; + fwrite($this->out, "File: {$filename}\n\n"); + fprintf($this->out, file_get_contents($filename)); + } + + private function debugCallback(callable $debugFn, $expression, $data) + { + fprintf($this->out, "Expression\n==========\n\n%s\n\n", $expression); + $this->dumpTokens($expression); + $this->dumpAst($expression); + fprintf($this->out, "\nData\n====\n\n%s\n\n", json_encode($data, JSON_PRETTY_PRINT)); + $startTime = microtime(true); + $result = $debugFn(); + $total = microtime(true) - $startTime; + fprintf($this->out, "\nResult\n======\n\n%s\n\n", json_encode($result, JSON_PRETTY_PRINT)); + fwrite($this->out, "Time\n====\n\n"); + fprintf($this->out, "Total time: %f ms\n\n", $total); + + return $result; + } +} diff --git a/vendor/mtdowling/jmespath.php/src/Env.php b/vendor/mtdowling/jmespath.php/src/Env.php new file mode 100644 index 0000000..b22cf25 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/Env.php @@ -0,0 +1,91 @@ +{'fn_' . $fn}($args); + } + + private function fn_abs(array $args) + { + $this->validate('abs', $args, [['number']]); + return abs($args[0]); + } + + private function fn_avg(array $args) + { + $this->validate('avg', $args, [['array']]); + $sum = $this->reduce('avg:0', $args[0], ['number'], function ($a, $b) { + return Utils::add($a, $b); + }); + return $args[0] ? ($sum / count($args[0])) : null; + } + + private function fn_ceil(array $args) + { + $this->validate('ceil', $args, [['number']]); + return ceil($args[0]); + } + + private function fn_contains(array $args) + { + $this->validate('contains', $args, [['string', 'array'], ['any']]); + if (is_array($args[0])) { + return in_array($args[1], $args[0]); + } elseif (is_string($args[1])) { + return mb_strpos($args[0], $args[1], 0, 'UTF-8') !== false; + } else { + return null; + } + } + + private function fn_ends_with(array $args) + { + $this->validate('ends_with', $args, [['string'], ['string']]); + list($search, $suffix) = $args; + return $suffix === '' || mb_substr($search, -mb_strlen($suffix, 'UTF-8'), null, 'UTF-8') === $suffix; + } + + private function fn_floor(array $args) + { + $this->validate('floor', $args, [['number']]); + return floor($args[0]); + } + + private function fn_not_null(array $args) + { + if (!$args) { + throw new \RuntimeException( + "not_null() expects 1 or more arguments, 0 were provided" + ); + } + + return array_reduce($args, function ($carry, $item) { + return $carry !== null ? $carry : $item; + }); + } + + private function fn_join(array $args) + { + $this->validate('join', $args, [['string'], ['array']]); + $fn = function ($a, $b, $i) use ($args) { + return $i ? ($a . $args[0] . $b) : $b; + }; + return $this->reduce('join:0', $args[1], ['string'], $fn); + } + + private function fn_keys(array $args) + { + $this->validate('keys', $args, [['object']]); + return array_keys((array) $args[0]); + } + + private function fn_length(array $args) + { + $this->validate('length', $args, [['string', 'array', 'object']]); + return is_string($args[0]) ? mb_strlen($args[0], 'UTF-8') : count((array) $args[0]); + } + + private function fn_max(array $args) + { + $this->validate('max', $args, [['array']]); + $fn = function ($a, $b) { + return $a >= $b ? $a : $b; + }; + return $this->reduce('max:0', $args[0], ['number', 'string'], $fn); + } + + private function fn_max_by(array $args) + { + $this->validate('max_by', $args, [['array'], ['expression']]); + $expr = $this->wrapExpression('max_by:1', $args[1], ['number', 'string']); + $fn = function ($carry, $item, $index) use ($expr) { + return $index + ? ($expr($carry) >= $expr($item) ? $carry : $item) + : $item; + }; + return $this->reduce('max_by:1', $args[0], ['any'], $fn); + } + + private function fn_min(array $args) + { + $this->validate('min', $args, [['array']]); + $fn = function ($a, $b, $i) { + return $i && $a <= $b ? $a : $b; + }; + return $this->reduce('min:0', $args[0], ['number', 'string'], $fn); + } + + private function fn_min_by(array $args) + { + $this->validate('min_by', $args, [['array'], ['expression']]); + $expr = $this->wrapExpression('min_by:1', $args[1], ['number', 'string']); + $i = -1; + $fn = function ($a, $b) use ($expr, &$i) { + return ++$i ? ($expr($a) <= $expr($b) ? $a : $b) : $b; + }; + return $this->reduce('min_by:1', $args[0], ['any'], $fn); + } + + private function fn_reverse(array $args) + { + $this->validate('reverse', $args, [['array', 'string']]); + if (is_array($args[0])) { + return array_reverse($args[0]); + } elseif (is_string($args[0])) { + return strrev($args[0]); + } else { + throw new \RuntimeException('Cannot reverse provided argument'); + } + } + + private function fn_sum(array $args) + { + $this->validate('sum', $args, [['array']]); + $fn = function ($a, $b) { + return Utils::add($a, $b); + }; + return $this->reduce('sum:0', $args[0], ['number'], $fn); + } + + private function fn_sort(array $args) + { + $this->validate('sort', $args, [['array']]); + $valid = ['string', 'number']; + return Utils::stableSort($args[0], function ($a, $b) use ($valid) { + $this->validateSeq('sort:0', $valid, $a, $b); + return strnatcmp($a, $b); + }); + } + + private function fn_sort_by(array $args) + { + $this->validate('sort_by', $args, [['array'], ['expression']]); + $expr = $args[1]; + $valid = ['string', 'number']; + return Utils::stableSort( + $args[0], + function ($a, $b) use ($expr, $valid) { + $va = $expr($a); + $vb = $expr($b); + $this->validateSeq('sort_by:0', $valid, $va, $vb); + return strnatcmp($va, $vb); + } + ); + } + + private function fn_starts_with(array $args) + { + $this->validate('starts_with', $args, [['string'], ['string']]); + list($search, $prefix) = $args; + return $prefix === '' || mb_strpos($search, $prefix, 0, 'UTF-8') === 0; + } + + private function fn_type(array $args) + { + $this->validateArity('type', count($args), 1); + return Utils::type($args[0]); + } + + private function fn_to_string(array $args) + { + $this->validateArity('to_string', count($args), 1); + $v = $args[0]; + if (is_string($v)) { + return $v; + } elseif (is_object($v) + && !($v instanceof \JsonSerializable) + && method_exists($v, '__toString') + ) { + return (string) $v; + } + + return json_encode($v); + } + + private function fn_to_number(array $args) + { + $this->validateArity('to_number', count($args), 1); + $value = $args[0]; + $type = Utils::type($value); + if ($type == 'number') { + return $value; + } elseif ($type == 'string' && is_numeric($value)) { + return mb_strpos($value, '.', 0, 'UTF-8') ? (float) $value : (int) $value; + } else { + return null; + } + } + + private function fn_values(array $args) + { + $this->validate('values', $args, [['array', 'object']]); + return array_values((array) $args[0]); + } + + private function fn_merge(array $args) + { + if (!$args) { + throw new \RuntimeException( + "merge() expects 1 or more arguments, 0 were provided" + ); + } + + return call_user_func_array('array_replace', $args); + } + + private function fn_to_array(array $args) + { + $this->validate('to_array', $args, [['any']]); + + return Utils::isArray($args[0]) ? $args[0] : [$args[0]]; + } + + private function fn_map(array $args) + { + $this->validate('map', $args, [['expression'], ['any']]); + $result = []; + foreach ($args[1] as $a) { + $result[] = $args[0]($a); + } + return $result; + } + + private function typeError($from, $msg) + { + if (mb_strpos($from, ':', 0, 'UTF-8')) { + list($fn, $pos) = explode(':', $from); + throw new \RuntimeException( + sprintf('Argument %d of %s %s', $pos, $fn, $msg) + ); + } else { + throw new \RuntimeException( + sprintf('Type error: %s %s', $from, $msg) + ); + } + } + + private function validateArity($from, $given, $expected) + { + if ($given != $expected) { + $err = "%s() expects {$expected} arguments, {$given} were provided"; + throw new \RuntimeException(sprintf($err, $from)); + } + } + + private function validate($from, $args, $types = []) + { + $this->validateArity($from, count($args), count($types)); + foreach ($args as $index => $value) { + if (!isset($types[$index]) || !$types[$index]) { + continue; + } + $this->validateType("{$from}:{$index}", $value, $types[$index]); + } + } + + private function validateType($from, $value, array $types) + { + if ($types[0] == 'any' + || in_array(Utils::type($value), $types) + || ($value === [] && in_array('object', $types)) + ) { + return; + } + $msg = 'must be one of the following types: ' . implode(', ', $types) + . '. ' . Utils::type($value) . ' found'; + $this->typeError($from, $msg); + } + + /** + * Validates value A and B, ensures they both are correctly typed, and of + * the same type. + * + * @param string $from String of function:argument_position + * @param array $types Array of valid value types. + * @param mixed $a Value A + * @param mixed $b Value B + */ + private function validateSeq($from, array $types, $a, $b) + { + $ta = Utils::type($a); + $tb = Utils::type($b); + + if ($ta !== $tb) { + $msg = "encountered a type mismatch in sequence: {$ta}, {$tb}"; + $this->typeError($from, $msg); + } + + $typeMatch = ($types && $types[0] == 'any') || in_array($ta, $types); + if (!$typeMatch) { + $msg = 'encountered a type error in sequence. The argument must be ' + . 'an array of ' . implode('|', $types) . ' types. ' + . "Found {$ta}, {$tb}."; + $this->typeError($from, $msg); + } + } + + /** + * Reduces and validates an array of values to a single value using a fn. + * + * @param string $from String of function:argument_position + * @param array $values Values to reduce. + * @param array $types Array of valid value types. + * @param callable $reduce Reduce function that accepts ($carry, $item). + * + * @return mixed + */ + private function reduce($from, array $values, array $types, callable $reduce) + { + $i = -1; + return array_reduce( + $values, + function ($carry, $item) use ($from, $types, $reduce, &$i) { + if (++$i > 0) { + $this->validateSeq($from, $types, $carry, $item); + } + return $reduce($carry, $item, $i); + } + ); + } + + /** + * Validates the return values of expressions as they are applied. + * + * @param string $from Function name : position + * @param callable $expr Expression function to validate. + * @param array $types Array of acceptable return type values. + * + * @return callable Returns a wrapped function + */ + private function wrapExpression($from, callable $expr, array $types) + { + list($fn, $pos) = explode(':', $from); + $from = "The expression return value of argument {$pos} of {$fn}"; + return function ($value) use ($from, $expr, $types) { + $value = $expr($value); + $this->validateType($from, $value, $types); + return $value; + }; + } + + /** @internal Pass function name validation off to runtime */ + public function __call($name, $args) + { + $name = str_replace('fn_', '', $name); + throw new \RuntimeException("Call to undefined function {$name}"); + } +} diff --git a/vendor/mtdowling/jmespath.php/src/JmesPath.php b/vendor/mtdowling/jmespath.php/src/JmesPath.php new file mode 100644 index 0000000..d24e516 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/JmesPath.php @@ -0,0 +1,17 @@ + self::STATE_LT, + '>' => self::STATE_GT, + '=' => self::STATE_EQ, + '!' => self::STATE_NOT, + '[' => self::STATE_LBRACKET, + '|' => self::STATE_PIPE, + '&' => self::STATE_AND, + '`' => self::STATE_JSON_LITERAL, + '"' => self::STATE_QUOTED_STRING, + "'" => self::STATE_STRING_LITERAL, + '-' => self::STATE_NUMBER, + '0' => self::STATE_NUMBER, + '1' => self::STATE_NUMBER, + '2' => self::STATE_NUMBER, + '3' => self::STATE_NUMBER, + '4' => self::STATE_NUMBER, + '5' => self::STATE_NUMBER, + '6' => self::STATE_NUMBER, + '7' => self::STATE_NUMBER, + '8' => self::STATE_NUMBER, + '9' => self::STATE_NUMBER, + ' ' => self::STATE_WHITESPACE, + "\t" => self::STATE_WHITESPACE, + "\n" => self::STATE_WHITESPACE, + "\r" => self::STATE_WHITESPACE, + '.' => self::STATE_SINGLE_CHAR, + '*' => self::STATE_SINGLE_CHAR, + ']' => self::STATE_SINGLE_CHAR, + ',' => self::STATE_SINGLE_CHAR, + ':' => self::STATE_SINGLE_CHAR, + '@' => self::STATE_SINGLE_CHAR, + '(' => self::STATE_SINGLE_CHAR, + ')' => self::STATE_SINGLE_CHAR, + '{' => self::STATE_SINGLE_CHAR, + '}' => self::STATE_SINGLE_CHAR, + '_' => self::STATE_IDENTIFIER, + 'A' => self::STATE_IDENTIFIER, + 'B' => self::STATE_IDENTIFIER, + 'C' => self::STATE_IDENTIFIER, + 'D' => self::STATE_IDENTIFIER, + 'E' => self::STATE_IDENTIFIER, + 'F' => self::STATE_IDENTIFIER, + 'G' => self::STATE_IDENTIFIER, + 'H' => self::STATE_IDENTIFIER, + 'I' => self::STATE_IDENTIFIER, + 'J' => self::STATE_IDENTIFIER, + 'K' => self::STATE_IDENTIFIER, + 'L' => self::STATE_IDENTIFIER, + 'M' => self::STATE_IDENTIFIER, + 'N' => self::STATE_IDENTIFIER, + 'O' => self::STATE_IDENTIFIER, + 'P' => self::STATE_IDENTIFIER, + 'Q' => self::STATE_IDENTIFIER, + 'R' => self::STATE_IDENTIFIER, + 'S' => self::STATE_IDENTIFIER, + 'T' => self::STATE_IDENTIFIER, + 'U' => self::STATE_IDENTIFIER, + 'V' => self::STATE_IDENTIFIER, + 'W' => self::STATE_IDENTIFIER, + 'X' => self::STATE_IDENTIFIER, + 'Y' => self::STATE_IDENTIFIER, + 'Z' => self::STATE_IDENTIFIER, + 'a' => self::STATE_IDENTIFIER, + 'b' => self::STATE_IDENTIFIER, + 'c' => self::STATE_IDENTIFIER, + 'd' => self::STATE_IDENTIFIER, + 'e' => self::STATE_IDENTIFIER, + 'f' => self::STATE_IDENTIFIER, + 'g' => self::STATE_IDENTIFIER, + 'h' => self::STATE_IDENTIFIER, + 'i' => self::STATE_IDENTIFIER, + 'j' => self::STATE_IDENTIFIER, + 'k' => self::STATE_IDENTIFIER, + 'l' => self::STATE_IDENTIFIER, + 'm' => self::STATE_IDENTIFIER, + 'n' => self::STATE_IDENTIFIER, + 'o' => self::STATE_IDENTIFIER, + 'p' => self::STATE_IDENTIFIER, + 'q' => self::STATE_IDENTIFIER, + 'r' => self::STATE_IDENTIFIER, + 's' => self::STATE_IDENTIFIER, + 't' => self::STATE_IDENTIFIER, + 'u' => self::STATE_IDENTIFIER, + 'v' => self::STATE_IDENTIFIER, + 'w' => self::STATE_IDENTIFIER, + 'x' => self::STATE_IDENTIFIER, + 'y' => self::STATE_IDENTIFIER, + 'z' => self::STATE_IDENTIFIER, + ]; + + /** @var array Valid identifier characters after first character */ + private $validIdentifier = [ + 'A' => true, 'B' => true, 'C' => true, 'D' => true, 'E' => true, + 'F' => true, 'G' => true, 'H' => true, 'I' => true, 'J' => true, + 'K' => true, 'L' => true, 'M' => true, 'N' => true, 'O' => true, + 'P' => true, 'Q' => true, 'R' => true, 'S' => true, 'T' => true, + 'U' => true, 'V' => true, 'W' => true, 'X' => true, 'Y' => true, + 'Z' => true, 'a' => true, 'b' => true, 'c' => true, 'd' => true, + 'e' => true, 'f' => true, 'g' => true, 'h' => true, 'i' => true, + 'j' => true, 'k' => true, 'l' => true, 'm' => true, 'n' => true, + 'o' => true, 'p' => true, 'q' => true, 'r' => true, 's' => true, + 't' => true, 'u' => true, 'v' => true, 'w' => true, 'x' => true, + 'y' => true, 'z' => true, '_' => true, '0' => true, '1' => true, + '2' => true, '3' => true, '4' => true, '5' => true, '6' => true, + '7' => true, '8' => true, '9' => true, + ]; + + /** @var array Valid number characters after the first character */ + private $numbers = [ + '0' => true, '1' => true, '2' => true, '3' => true, '4' => true, + '5' => true, '6' => true, '7' => true, '8' => true, '9' => true + ]; + + /** @var array Map of simple single character tokens */ + private $simpleTokens = [ + '.' => self::T_DOT, + '*' => self::T_STAR, + ']' => self::T_RBRACKET, + ',' => self::T_COMMA, + ':' => self::T_COLON, + '@' => self::T_CURRENT, + '(' => self::T_LPAREN, + ')' => self::T_RPAREN, + '{' => self::T_LBRACE, + '}' => self::T_RBRACE, + ]; + + /** + * Tokenize the JMESPath expression into an array of tokens hashes that + * contain a 'type', 'value', and 'key'. + * + * @param string $input JMESPath input + * + * @return array + * @throws SyntaxErrorException + */ + public function tokenize($input) + { + $tokens = []; + + if ($input === '') { + goto eof; + } + + $chars = str_split($input); + + while (false !== ($current = current($chars))) { + + // Every character must be in the transition character table. + if (!isset(self::$transitionTable[$current])) { + $tokens[] = [ + 'type' => self::T_UNKNOWN, + 'pos' => key($chars), + 'value' => $current + ]; + next($chars); + continue; + } + + $state = self::$transitionTable[$current]; + + if ($state === self::STATE_SINGLE_CHAR) { + + // Consume simple tokens like ".", ",", "@", etc. + $tokens[] = [ + 'type' => $this->simpleTokens[$current], + 'pos' => key($chars), + 'value' => $current + ]; + next($chars); + + } elseif ($state === self::STATE_IDENTIFIER) { + + // Consume identifiers + $start = key($chars); + $buffer = ''; + do { + $buffer .= $current; + $current = next($chars); + } while ($current !== false && isset($this->validIdentifier[$current])); + $tokens[] = [ + 'type' => self::T_IDENTIFIER, + 'value' => $buffer, + 'pos' => $start + ]; + + } elseif ($state === self::STATE_WHITESPACE) { + + // Skip whitespace + next($chars); + + } elseif ($state === self::STATE_LBRACKET) { + + // Consume "[", "[?", and "[]" + $position = key($chars); + $actual = next($chars); + if ($actual === ']') { + next($chars); + $tokens[] = [ + 'type' => self::T_FLATTEN, + 'pos' => $position, + 'value' => '[]' + ]; + } elseif ($actual === '?') { + next($chars); + $tokens[] = [ + 'type' => self::T_FILTER, + 'pos' => $position, + 'value' => '[?' + ]; + } else { + $tokens[] = [ + 'type' => self::T_LBRACKET, + 'pos' => $position, + 'value' => '[' + ]; + } + + } elseif ($state === self::STATE_STRING_LITERAL) { + + // Consume raw string literals + $t = $this->inside($chars, "'", self::T_LITERAL); + $t['value'] = str_replace("\\'", "'", $t['value']); + $tokens[] = $t; + + } elseif ($state === self::STATE_PIPE) { + + // Consume pipe and OR + $tokens[] = $this->matchOr($chars, '|', '|', self::T_OR, self::T_PIPE); + + } elseif ($state == self::STATE_JSON_LITERAL) { + + // Consume JSON literals + $token = $this->inside($chars, '`', self::T_LITERAL); + if ($token['type'] === self::T_LITERAL) { + $token['value'] = str_replace('\\`', '`', $token['value']); + $token = $this->parseJson($token); + } + $tokens[] = $token; + + } elseif ($state == self::STATE_NUMBER) { + + // Consume numbers + $start = key($chars); + $buffer = ''; + do { + $buffer .= $current; + $current = next($chars); + } while ($current !== false && isset($this->numbers[$current])); + $tokens[] = [ + 'type' => self::T_NUMBER, + 'value' => (int)$buffer, + 'pos' => $start + ]; + + } elseif ($state === self::STATE_QUOTED_STRING) { + + // Consume quoted identifiers + $token = $this->inside($chars, '"', self::T_QUOTED_IDENTIFIER); + if ($token['type'] === self::T_QUOTED_IDENTIFIER) { + $token['value'] = '"' . $token['value'] . '"'; + $token = $this->parseJson($token); + } + $tokens[] = $token; + + } elseif ($state === self::STATE_EQ) { + + // Consume equals + $tokens[] = $this->matchOr($chars, '=', '=', self::T_COMPARATOR, self::T_UNKNOWN); + + } elseif ($state == self::STATE_AND) { + + $tokens[] = $this->matchOr($chars, '&', '&', self::T_AND, self::T_EXPREF); + + } elseif ($state === self::STATE_NOT) { + + // Consume not equal + $tokens[] = $this->matchOr($chars, '!', '=', self::T_COMPARATOR, self::T_NOT); + + } else { + + // either '<' or '>' + // Consume less than and greater than + $tokens[] = $this->matchOr($chars, $current, '=', self::T_COMPARATOR, self::T_COMPARATOR); + + } + } + + eof: + $tokens[] = [ + 'type' => self::T_EOF, + 'pos' => mb_strlen($input, 'UTF-8'), + 'value' => null + ]; + + return $tokens; + } + + /** + * Returns a token based on whether or not the next token matches the + * expected value. If it does, a token of "$type" is returned. Otherwise, + * a token of "$orElse" type is returned. + * + * @param array $chars Array of characters by reference. + * @param string $current The current character. + * @param string $expected Expected character. + * @param string $type Expected result type. + * @param string $orElse Otherwise return a token of this type. + * + * @return array Returns a conditional token. + */ + private function matchOr(array &$chars, $current, $expected, $type, $orElse) + { + if (next($chars) === $expected) { + next($chars); + return [ + 'type' => $type, + 'pos' => key($chars) - 1, + 'value' => $current . $expected + ]; + } + + return [ + 'type' => $orElse, + 'pos' => key($chars) - 1, + 'value' => $current + ]; + } + + /** + * Returns a token the is the result of consuming inside of delimiter + * characters. Escaped delimiters will be adjusted before returning a + * value. If the token is not closed, "unknown" is returned. + * + * @param array $chars Array of characters by reference. + * @param string $delim The delimiter character. + * @param string $type Token type. + * + * @return array Returns the consumed token. + */ + private function inside(array &$chars, $delim, $type) + { + $position = key($chars); + $current = next($chars); + $buffer = ''; + + while ($current !== $delim) { + if ($current === '\\') { + $buffer .= '\\'; + $current = next($chars); + } + if ($current === false) { + // Unclosed delimiter + return [ + 'type' => self::T_UNKNOWN, + 'value' => $buffer, + 'pos' => $position + ]; + } + $buffer .= $current; + $current = next($chars); + } + + next($chars); + + return ['type' => $type, 'value' => $buffer, 'pos' => $position]; + } + + /** + * Parses a JSON token or sets the token type to "unknown" on error. + * + * @param array $token Token that needs parsing. + * + * @return array Returns a token with a parsed value. + */ + private function parseJson(array $token) + { + $value = json_decode($token['value'], true); + + if ($error = json_last_error()) { + // Legacy support for elided quotes. Try to parse again by adding + // quotes around the bad input value. + $value = json_decode('"' . $token['value'] . '"', true); + if ($error = json_last_error()) { + $token['type'] = self::T_UNKNOWN; + return $token; + } + } + + $token['value'] = $value; + return $token; + } +} diff --git a/vendor/mtdowling/jmespath.php/src/Parser.php b/vendor/mtdowling/jmespath.php/src/Parser.php new file mode 100644 index 0000000..d126de5 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/Parser.php @@ -0,0 +1,519 @@ + T::T_EOF]; + private static $currentNode = ['type' => T::T_CURRENT]; + + private static $bp = [ + T::T_EOF => 0, + T::T_QUOTED_IDENTIFIER => 0, + T::T_IDENTIFIER => 0, + T::T_RBRACKET => 0, + T::T_RPAREN => 0, + T::T_COMMA => 0, + T::T_RBRACE => 0, + T::T_NUMBER => 0, + T::T_CURRENT => 0, + T::T_EXPREF => 0, + T::T_COLON => 0, + T::T_PIPE => 1, + T::T_OR => 2, + T::T_AND => 3, + T::T_COMPARATOR => 5, + T::T_FLATTEN => 9, + T::T_STAR => 20, + T::T_FILTER => 21, + T::T_DOT => 40, + T::T_NOT => 45, + T::T_LBRACE => 50, + T::T_LBRACKET => 55, + T::T_LPAREN => 60, + ]; + + /** @var array Acceptable tokens after a dot token */ + private static $afterDot = [ + T::T_IDENTIFIER => true, // foo.bar + T::T_QUOTED_IDENTIFIER => true, // foo."bar" + T::T_STAR => true, // foo.* + T::T_LBRACE => true, // foo[1] + T::T_LBRACKET => true, // foo{a: 0} + T::T_FILTER => true, // foo.[?bar==10] + ]; + + /** + * @param Lexer|null $lexer Lexer used to tokenize expressions + */ + public function __construct(?Lexer $lexer = null) + { + $this->lexer = $lexer ?: new Lexer(); + } + + /** + * Parses a JMESPath expression into an AST + * + * @param string $expression JMESPath expression to compile + * + * @return array Returns an array based AST + * @throws SyntaxErrorException + */ + public function parse($expression) + { + $this->expression = $expression; + $this->tokens = $this->lexer->tokenize($expression); + $this->tpos = -1; + $this->next(); + $result = $this->expr(); + + if ($this->token['type'] === T::T_EOF) { + return $result; + } + + throw $this->syntax('Did not reach the end of the token stream'); + } + + /** + * Parses an expression while rbp < lbp. + * + * @param int $rbp Right bound precedence + * + * @return array + */ + private function expr($rbp = 0) + { + $left = $this->{"nud_{$this->token['type']}"}(); + while ($rbp < self::$bp[$this->token['type']]) { + $left = $this->{"led_{$this->token['type']}"}($left); + } + + return $left; + } + + private function nud_identifier() + { + $token = $this->token; + $this->next(); + return ['type' => 'field', 'value' => $token['value']]; + } + + private function nud_quoted_identifier() + { + $token = $this->token; + $this->next(); + $this->assertNotToken(T::T_LPAREN); + return ['type' => 'field', 'value' => $token['value']]; + } + + private function nud_current() + { + $this->next(); + return self::$currentNode; + } + + private function nud_literal() + { + $token = $this->token; + $this->next(); + return ['type' => 'literal', 'value' => $token['value']]; + } + + private function nud_expref() + { + $this->next(); + return ['type' => T::T_EXPREF, 'children' => [$this->expr(self::$bp[T::T_EXPREF])]]; + } + + private function nud_not() + { + $this->next(); + return ['type' => T::T_NOT, 'children' => [$this->expr(self::$bp[T::T_NOT])]]; + } + + private function nud_lparen() + { + $this->next(); + $result = $this->expr(0); + if ($this->token['type'] !== T::T_RPAREN) { + throw $this->syntax('Unclosed `(`'); + } + $this->next(); + return $result; + } + + private function nud_lbrace() + { + static $validKeys = [T::T_QUOTED_IDENTIFIER => true, T::T_IDENTIFIER => true]; + $this->next($validKeys); + $pairs = []; + + do { + $pairs[] = $this->parseKeyValuePair(); + if ($this->token['type'] == T::T_COMMA) { + $this->next($validKeys); + } + } while ($this->token['type'] !== T::T_RBRACE); + + $this->next(); + + return['type' => 'multi_select_hash', 'children' => $pairs]; + } + + private function nud_flatten() + { + return $this->led_flatten(self::$currentNode); + } + + private function nud_filter() + { + return $this->led_filter(self::$currentNode); + } + + private function nud_star() + { + return $this->parseWildcardObject(self::$currentNode); + } + + private function nud_lbracket() + { + $this->next(); + $type = $this->token['type']; + if ($type == T::T_NUMBER || $type == T::T_COLON) { + return $this->parseArrayIndexExpression(); + } elseif ($type == T::T_STAR && $this->lookahead() == T::T_RBRACKET) { + return $this->parseWildcardArray(); + } else { + return $this->parseMultiSelectList(); + } + } + + private function led_lbracket(array $left) + { + static $nextTypes = [T::T_NUMBER => true, T::T_COLON => true, T::T_STAR => true]; + $this->next($nextTypes); + switch ($this->token['type']) { + case T::T_NUMBER: + case T::T_COLON: + return [ + 'type' => 'subexpression', + 'children' => [$left, $this->parseArrayIndexExpression()] + ]; + default: + return $this->parseWildcardArray($left); + } + } + + private function led_flatten(array $left) + { + $this->next(); + + return [ + 'type' => 'projection', + 'from' => 'array', + 'children' => [ + ['type' => T::T_FLATTEN, 'children' => [$left]], + $this->parseProjection(self::$bp[T::T_FLATTEN]) + ] + ]; + } + + private function led_dot(array $left) + { + $this->next(self::$afterDot); + + if ($this->token['type'] == T::T_STAR) { + return $this->parseWildcardObject($left); + } + + return [ + 'type' => 'subexpression', + 'children' => [$left, $this->parseDot(self::$bp[T::T_DOT])] + ]; + } + + private function led_or(array $left) + { + $this->next(); + return [ + 'type' => T::T_OR, + 'children' => [$left, $this->expr(self::$bp[T::T_OR])] + ]; + } + + private function led_and(array $left) + { + $this->next(); + return [ + 'type' => T::T_AND, + 'children' => [$left, $this->expr(self::$bp[T::T_AND])] + ]; + } + + private function led_pipe(array $left) + { + $this->next(); + return [ + 'type' => T::T_PIPE, + 'children' => [$left, $this->expr(self::$bp[T::T_PIPE])] + ]; + } + + private function led_lparen(array $left) + { + $args = []; + $this->next(); + + while ($this->token['type'] != T::T_RPAREN) { + $args[] = $this->expr(0); + if ($this->token['type'] == T::T_COMMA) { + $this->next(); + } + } + + $this->next(); + + return [ + 'type' => 'function', + 'value' => $left['value'], + 'children' => $args + ]; + } + + private function led_filter(array $left) + { + $this->next(); + $expression = $this->expr(); + if ($this->token['type'] != T::T_RBRACKET) { + throw $this->syntax('Expected a closing rbracket for the filter'); + } + + $this->next(); + $rhs = $this->parseProjection(self::$bp[T::T_FILTER]); + + return [ + 'type' => 'projection', + 'from' => 'array', + 'children' => [ + $left ?: self::$currentNode, + [ + 'type' => 'condition', + 'children' => [$expression, $rhs] + ] + ] + ]; + } + + private function led_comparator(array $left) + { + $token = $this->token; + $this->next(); + + return [ + 'type' => T::T_COMPARATOR, + 'value' => $token['value'], + 'children' => [$left, $this->expr(self::$bp[T::T_COMPARATOR])] + ]; + } + + private function parseProjection($bp) + { + $type = $this->token['type']; + if (self::$bp[$type] < 10) { + return self::$currentNode; + } elseif ($type == T::T_DOT) { + $this->next(self::$afterDot); + return $this->parseDot($bp); + } elseif ($type == T::T_LBRACKET || $type == T::T_FILTER) { + return $this->expr($bp); + } + + throw $this->syntax('Syntax error after projection'); + } + + private function parseDot($bp) + { + if ($this->token['type'] == T::T_LBRACKET) { + $this->next(); + return $this->parseMultiSelectList(); + } + + return $this->expr($bp); + } + + private function parseKeyValuePair() + { + static $validColon = [T::T_COLON => true]; + $key = $this->token['value']; + $this->next($validColon); + $this->next(); + + return [ + 'type' => 'key_val_pair', + 'value' => $key, + 'children' => [$this->expr()] + ]; + } + + private function parseWildcardObject(?array $left = null) + { + $this->next(); + + return [ + 'type' => 'projection', + 'from' => 'object', + 'children' => [ + $left ?: self::$currentNode, + $this->parseProjection(self::$bp[T::T_STAR]) + ] + ]; + } + + private function parseWildcardArray(?array $left = null) + { + static $getRbracket = [T::T_RBRACKET => true]; + $this->next($getRbracket); + $this->next(); + + return [ + 'type' => 'projection', + 'from' => 'array', + 'children' => [ + $left ?: self::$currentNode, + $this->parseProjection(self::$bp[T::T_STAR]) + ] + ]; + } + + /** + * Parses an array index expression (e.g., [0], [1:2:3] + */ + private function parseArrayIndexExpression() + { + static $matchNext = [ + T::T_NUMBER => true, + T::T_COLON => true, + T::T_RBRACKET => true + ]; + + $pos = 0; + $parts = [null, null, null]; + $expected = $matchNext; + + do { + if ($this->token['type'] == T::T_COLON) { + $pos++; + $expected = $matchNext; + } elseif ($this->token['type'] == T::T_NUMBER) { + $parts[$pos] = $this->token['value']; + $expected = [T::T_COLON => true, T::T_RBRACKET => true]; + } + $this->next($expected); + } while ($this->token['type'] != T::T_RBRACKET); + + // Consume the closing bracket + $this->next(); + + if ($pos === 0) { + // No colons were found so this is a simple index extraction + return ['type' => 'index', 'value' => $parts[0]]; + } + + if ($pos > 2) { + throw $this->syntax('Invalid array slice syntax: too many colons'); + } + + // Sliced array from start (e.g., [2:]) + return [ + 'type' => 'projection', + 'from' => 'array', + 'children' => [ + ['type' => 'slice', 'value' => $parts], + $this->parseProjection(self::$bp[T::T_STAR]) + ] + ]; + } + + private function parseMultiSelectList() + { + $nodes = []; + + do { + $nodes[] = $this->expr(); + if ($this->token['type'] == T::T_COMMA) { + $this->next(); + $this->assertNotToken(T::T_RBRACKET); + } + } while ($this->token['type'] !== T::T_RBRACKET); + $this->next(); + + return ['type' => 'multi_select_list', 'children' => $nodes]; + } + + private function syntax($msg) + { + return new SyntaxErrorException($msg, $this->token, $this->expression); + } + + private function lookahead() + { + return (!isset($this->tokens[$this->tpos + 1])) + ? T::T_EOF + : $this->tokens[$this->tpos + 1]['type']; + } + + private function next(?array $match = null) + { + if (!isset($this->tokens[$this->tpos + 1])) { + $this->token = self::$nullToken; + } else { + $this->token = $this->tokens[++$this->tpos]; + } + + if ($match && !isset($match[$this->token['type']])) { + throw $this->syntax($match); + } + } + + private function assertNotToken($type) + { + if ($this->token['type'] == $type) { + throw $this->syntax("Token {$this->tpos} not allowed to be $type"); + } + } + + /** + * @internal Handles undefined tokens without paying the cost of validation + */ + public function __call($method, $args) + { + $prefix = substr($method, 0, 4); + if ($prefix == 'nud_' || $prefix == 'led_') { + $token = substr($method, 4); + $message = "Unexpected \"$token\" token ($method). Expected one of" + . " the following tokens: " + . implode(', ', array_map(function ($i) { + return '"' . substr($i, 4) . '"'; + }, array_filter( + get_class_methods($this), + function ($i) use ($prefix) { + return strpos($i, $prefix) === 0; + } + ))); + throw $this->syntax($message); + } + + throw new \BadMethodCallException("Call to undefined method $method"); + } +} diff --git a/vendor/mtdowling/jmespath.php/src/SyntaxErrorException.php b/vendor/mtdowling/jmespath.php/src/SyntaxErrorException.php new file mode 100644 index 0000000..b9e376e --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/SyntaxErrorException.php @@ -0,0 +1,36 @@ +createTokenMessage($token, $expectedTypesOrMessage); + parent::__construct($message); + } + + private function createTokenMessage(array $token, array $valid) + { + return sprintf( + 'Expected one of the following: %s; found %s "%s"', + implode(', ', array_keys($valid)), + $token['type'], + $token['value'] + ); + } +} diff --git a/vendor/mtdowling/jmespath.php/src/TreeCompiler.php b/vendor/mtdowling/jmespath.php/src/TreeCompiler.php new file mode 100644 index 0000000..b5f0658 --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/TreeCompiler.php @@ -0,0 +1,419 @@ +vars = []; + $this->source = $this->indentation = ''; + $this->write("write('use JmesPath\\TreeInterpreter as Ti;') + ->write('use JmesPath\\FnDispatcher as Fd;') + ->write('use JmesPath\\Utils;') + ->write('') + ->write('function %s(Ti $interpreter, $value) {', $fnName) + ->indent() + ->dispatch($ast) + ->write('') + ->write('return $value;') + ->outdent() + ->write('}'); + + return $this->source; + } + + /** + * @param array $node + * @return mixed + */ + private function dispatch(array $node) + { + return $this->{"visit_{$node['type']}"}($node); + } + + /** + * Creates a monotonically incrementing unique variable name by prefix. + * + * @param string $prefix Variable name prefix + * + * @return string + */ + private function makeVar($prefix) + { + if (!isset($this->vars[$prefix])) { + $this->vars[$prefix] = 0; + return '$' . $prefix; + } + + return '$' . $prefix . ++$this->vars[$prefix]; + } + + /** + * Writes the given line of source code. Pass positional arguments to write + * that match the format of sprintf. + * + * @param string $str String to write + * @return $this + */ + private function write($str) + { + $this->source .= $this->indentation; + if (func_num_args() == 1) { + $this->source .= $str . "\n"; + return $this; + } + $this->source .= vsprintf($str, array_slice(func_get_args(), 1)) . "\n"; + return $this; + } + + /** + * Decreases the indentation level of code being written + * @return $this + */ + private function outdent() + { + $this->indentation = substr($this->indentation, 0, -4); + return $this; + } + + /** + * Increases the indentation level of code being written + * @return $this + */ + private function indent() + { + $this->indentation .= ' '; + return $this; + } + + private function visit_or(array $node) + { + $a = $this->makeVar('beforeOr'); + return $this + ->write('%s = $value;', $a) + ->dispatch($node['children'][0]) + ->write('if (!$value && $value !== "0" && $value !== 0) {') + ->indent() + ->write('$value = %s;', $a) + ->dispatch($node['children'][1]) + ->outdent() + ->write('}'); + } + + private function visit_and(array $node) + { + $a = $this->makeVar('beforeAnd'); + return $this + ->write('%s = $value;', $a) + ->dispatch($node['children'][0]) + ->write('if ($value || $value === "0" || $value === 0) {') + ->indent() + ->write('$value = %s;', $a) + ->dispatch($node['children'][1]) + ->outdent() + ->write('}'); + } + + private function visit_not(array $node) + { + return $this + ->write('// Visiting not node') + ->dispatch($node['children'][0]) + ->write('// Applying boolean not to result of not node') + ->write('$value = !Utils::isTruthy($value);'); + } + + private function visit_subexpression(array $node) + { + return $this + ->dispatch($node['children'][0]) + ->write('if ($value !== null) {') + ->indent() + ->dispatch($node['children'][1]) + ->outdent() + ->write('}'); + } + + private function visit_field(array $node) + { + $arr = '$value[' . var_export($node['value'], true) . ']'; + $obj = '$value->{' . var_export($node['value'], true) . '}'; + $this->write('if (is_array($value) || $value instanceof \\ArrayAccess) {') + ->indent() + ->write('$value = isset(%s) ? %s : null;', $arr, $arr) + ->outdent() + ->write('} elseif ($value instanceof \\stdClass) {') + ->indent() + ->write('$value = isset(%s) ? %s : null;', $obj, $obj) + ->outdent() + ->write("} else {") + ->indent() + ->write('$value = null;') + ->outdent() + ->write("}"); + + return $this; + } + + private function visit_index(array $node) + { + if ($node['value'] >= 0) { + $check = '$value[' . $node['value'] . ']'; + return $this->write( + '$value = (is_array($value) || $value instanceof \\ArrayAccess)' + . ' && isset(%s) ? %s : null;', + $check, $check + ); + } + + $a = $this->makeVar('count'); + return $this + ->write('if (is_array($value) || ($value instanceof \\ArrayAccess && $value instanceof \\Countable)) {') + ->indent() + ->write('%s = count($value) + %s;', $a, $node['value']) + ->write('$value = isset($value[%s]) ? $value[%s] : null;', $a, $a) + ->outdent() + ->write('} else {') + ->indent() + ->write('$value = null;') + ->outdent() + ->write('}'); + } + + private function visit_literal(array $node) + { + return $this->write('$value = %s;', var_export($node['value'], true)); + } + + private function visit_pipe(array $node) + { + return $this + ->dispatch($node['children'][0]) + ->dispatch($node['children'][1]); + } + + private function visit_multi_select_list(array $node) + { + return $this->visit_multi_select_hash($node); + } + + private function visit_multi_select_hash(array $node) + { + $listVal = $this->makeVar('list'); + $value = $this->makeVar('prev'); + $this->write('if ($value !== null) {') + ->indent() + ->write('%s = [];', $listVal) + ->write('%s = $value;', $value); + + $first = true; + foreach ($node['children'] as $child) { + if (!$first) { + $this->write('$value = %s;', $value); + } + $first = false; + if ($node['type'] == 'multi_select_hash') { + $this->dispatch($child['children'][0]); + $key = var_export($child['value'], true); + $this->write('%s[%s] = $value;', $listVal, $key); + } else { + $this->dispatch($child); + $this->write('%s[] = $value;', $listVal); + } + } + + return $this + ->write('$value = %s;', $listVal) + ->outdent() + ->write('}'); + } + + private function visit_function(array $node) + { + $value = $this->makeVar('val'); + $args = $this->makeVar('args'); + $this->write('%s = $value;', $value) + ->write('%s = [];', $args); + + foreach ($node['children'] as $arg) { + $this->dispatch($arg); + $this->write('%s[] = $value;', $args) + ->write('$value = %s;', $value); + } + + return $this->write( + '$value = Fd::getInstance()->__invoke("%s", %s);', + $node['value'], $args + ); + } + + private function visit_slice(array $node) + { + return $this + ->write('$value = !is_string($value) && !Utils::isArray($value)') + ->write(' ? null : Utils::slice($value, %s, %s, %s);', + var_export($node['value'][0], true), + var_export($node['value'][1], true), + var_export($node['value'][2], true) + ); + } + + private function visit_current(array $node) + { + return $this->write('// Visiting current node (no-op)'); + } + + private function visit_expref(array $node) + { + $child = var_export($node['children'][0], true); + return $this->write('$value = function ($value) use ($interpreter) {') + ->indent() + ->write('return $interpreter->visit(%s, $value);', $child) + ->outdent() + ->write('};'); + } + + private function visit_flatten(array $node) + { + $this->dispatch($node['children'][0]); + $merged = $this->makeVar('merged'); + $val = $this->makeVar('val'); + + $this + ->write('// Visiting merge node') + ->write('if (!Utils::isArray($value)) {') + ->indent() + ->write('$value = null;') + ->outdent() + ->write('} else {') + ->indent() + ->write('%s = [];', $merged) + ->write('foreach ($value as %s) {', $val) + ->indent() + ->write('if (is_array(%s) && array_key_exists(0, %s)) {', $val, $val) + ->indent() + ->write('%s = array_merge(%s, %s);', $merged, $merged, $val) + ->outdent() + ->write('} elseif (%s !== []) {', $val) + ->indent() + ->write('%s[] = %s;', $merged, $val) + ->outdent() + ->write('}') + ->outdent() + ->write('}') + ->write('$value = %s;', $merged) + ->outdent() + ->write('}'); + + return $this; + } + + private function visit_projection(array $node) + { + $val = $this->makeVar('val'); + $collected = $this->makeVar('collected'); + $this->write('// Visiting projection node') + ->dispatch($node['children'][0]) + ->write(''); + + if (!isset($node['from'])) { + $this->write('if (!is_array($value) || !($value instanceof \stdClass)) { $value = null; }'); + } elseif ($node['from'] == 'object') { + $this->write('if (!Utils::isObject($value)) { $value = null; }'); + } elseif ($node['from'] == 'array') { + $this->write('if (!Utils::isArray($value)) { $value = null; }'); + } + + $this->write('if ($value !== null) {') + ->indent() + ->write('%s = [];', $collected) + ->write('foreach ((array) $value as %s) {', $val) + ->indent() + ->write('$value = %s;', $val) + ->dispatch($node['children'][1]) + ->write('if ($value !== null) {') + ->indent() + ->write('%s[] = $value;', $collected) + ->outdent() + ->write('}') + ->outdent() + ->write('}') + ->write('$value = %s;', $collected) + ->outdent() + ->write('}'); + + return $this; + } + + private function visit_condition(array $node) + { + $value = $this->makeVar('beforeCondition'); + return $this + ->write('%s = $value;', $value) + ->write('// Visiting condition node') + ->dispatch($node['children'][0]) + ->write('// Checking result of condition node') + ->write('if (Utils::isTruthy($value)) {') + ->indent() + ->write('$value = %s;', $value) + ->dispatch($node['children'][1]) + ->outdent() + ->write('} else {') + ->indent() + ->write('$value = null;') + ->outdent() + ->write('}'); + } + + private function visit_comparator(array $node) + { + $value = $this->makeVar('val'); + $a = $this->makeVar('left'); + $b = $this->makeVar('right'); + + $this + ->write('// Visiting comparator node') + ->write('%s = $value;', $value) + ->dispatch($node['children'][0]) + ->write('%s = $value;', $a) + ->write('$value = %s;', $value) + ->dispatch($node['children'][1]) + ->write('%s = $value;', $b); + + if ($node['value'] == '==') { + $this->write('$value = Utils::isEqual(%s, %s);', $a, $b); + } elseif ($node['value'] == '!=') { + $this->write('$value = !Utils::isEqual(%s, %s);', $a, $b); + } else { + $this->write( + '$value = (is_int(%s) || is_float(%s)) && (is_int(%s) || is_float(%s)) && %s %s %s;', + $a, $a, $b, $b, $a, $node['value'], $b + ); + } + + return $this; + } + + /** @internal */ + public function __call($method, $args) + { + throw new \RuntimeException( + sprintf('Invalid node encountered: %s', json_encode($args[0])) + ); + } +} diff --git a/vendor/mtdowling/jmespath.php/src/TreeInterpreter.php b/vendor/mtdowling/jmespath.php/src/TreeInterpreter.php new file mode 100644 index 0000000..f4a8aec --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/TreeInterpreter.php @@ -0,0 +1,235 @@ +fnDispatcher = $fnDispatcher ?: FnDispatcher::getInstance(); + } + + /** + * Visits each node in a JMESPath AST and returns the evaluated result. + * + * @param array $node JMESPath AST node + * @param mixed $data Data to evaluate + * + * @return mixed + */ + public function visit(array $node, $data) + { + return $this->dispatch($node, $data); + } + + /** + * Recursively traverses an AST using depth-first, pre-order traversal. + * The evaluation logic for each node type is embedded into a large switch + * statement to avoid the cost of "double dispatch". + * @return mixed + */ + private function dispatch(array $node, $value) + { + $dispatcher = $this->fnDispatcher; + + switch ($node['type']) { + + case 'field': + if (is_array($value) || $value instanceof \ArrayAccess) { + return isset($value[$node['value']]) ? $value[$node['value']] : null; + } elseif ($value instanceof \stdClass) { + return isset($value->{$node['value']}) ? $value->{$node['value']} : null; + } + return null; + + case 'subexpression': + return $this->dispatch( + $node['children'][1], + $this->dispatch($node['children'][0], $value) + ); + + case 'index': + if (!Utils::isArray($value)) { + return null; + } + $idx = $node['value'] >= 0 + ? $node['value'] + : $node['value'] + count($value); + return isset($value[$idx]) ? $value[$idx] : null; + + case 'projection': + $left = $this->dispatch($node['children'][0], $value); + switch ($node['from']) { + case 'object': + if (!Utils::isObject($left)) { + return null; + } + break; + case 'array': + if (!Utils::isArray($left)) { + return null; + } + break; + default: + if (!is_array($left) || !($left instanceof \stdClass)) { + return null; + } + } + + $collected = []; + foreach ((array) $left as $val) { + $result = $this->dispatch($node['children'][1], $val); + if ($result !== null) { + $collected[] = $result; + } + } + + return $collected; + + case 'flatten': + static $skipElement = []; + $value = $this->dispatch($node['children'][0], $value); + + if (!Utils::isArray($value)) { + return null; + } + + $merged = []; + foreach ($value as $values) { + // Only merge up arrays lists and not hashes + if (is_array($values) && array_key_exists(0, $values)) { + $merged = array_merge($merged, $values); + } elseif ($values !== $skipElement) { + $merged[] = $values; + } + } + + return $merged; + + case 'literal': + return $node['value']; + + case 'current': + return $value; + + case 'or': + $result = $this->dispatch($node['children'][0], $value); + return Utils::isTruthy($result) + ? $result + : $this->dispatch($node['children'][1], $value); + + case 'and': + $result = $this->dispatch($node['children'][0], $value); + return Utils::isTruthy($result) + ? $this->dispatch($node['children'][1], $value) + : $result; + + case 'not': + return !Utils::isTruthy( + $this->dispatch($node['children'][0], $value) + ); + + case 'pipe': + return $this->dispatch( + $node['children'][1], + $this->dispatch($node['children'][0], $value) + ); + + case 'multi_select_list': + if ($value === null) { + return null; + } + + $collected = []; + foreach ($node['children'] as $node) { + $collected[] = $this->dispatch($node, $value); + } + + return $collected; + + case 'multi_select_hash': + if ($value === null) { + return null; + } + + $collected = []; + foreach ($node['children'] as $node) { + $collected[$node['value']] = $this->dispatch( + $node['children'][0], + $value + ); + } + + return $collected; + + case 'comparator': + $left = $this->dispatch($node['children'][0], $value); + $right = $this->dispatch($node['children'][1], $value); + if ($node['value'] == '==') { + return Utils::isEqual($left, $right); + } elseif ($node['value'] == '!=') { + return !Utils::isEqual($left, $right); + } else { + return self::relativeCmp($left, $right, $node['value']); + } + + case 'condition': + return Utils::isTruthy($this->dispatch($node['children'][0], $value)) + ? $this->dispatch($node['children'][1], $value) + : null; + + case 'function': + $args = []; + foreach ($node['children'] as $arg) { + $args[] = $this->dispatch($arg, $value); + } + return $dispatcher($node['value'], $args); + + case 'slice': + return is_string($value) || Utils::isArray($value) + ? Utils::slice( + $value, + $node['value'][0], + $node['value'][1], + $node['value'][2] + ) : null; + + case 'expref': + $apply = $node['children'][0]; + return function ($value) use ($apply) { + return $this->visit($apply, $value); + }; + + default: + throw new \RuntimeException("Unknown node type: {$node['type']}"); + } + } + + /** + * @return bool + */ + private static function relativeCmp($left, $right, $cmp) + { + if (!(is_int($left) || is_float($left)) || !(is_int($right) || is_float($right))) { + return false; + } + + switch ($cmp) { + case '>': return $left > $right; + case '>=': return $left >= $right; + case '<': return $left < $right; + case '<=': return $left <= $right; + default: throw new \RuntimeException("Invalid comparison: $cmp"); + } + } +} diff --git a/vendor/mtdowling/jmespath.php/src/Utils.php b/vendor/mtdowling/jmespath.php/src/Utils.php new file mode 100644 index 0000000..9e69fef --- /dev/null +++ b/vendor/mtdowling/jmespath.php/src/Utils.php @@ -0,0 +1,258 @@ + 'boolean', + 'string' => 'string', + 'NULL' => 'null', + 'double' => 'number', + 'float' => 'number', + 'integer' => 'number' + ]; + + /** + * Returns true if the value is truthy + * + * @param mixed $value Value to check + * + * @return bool + */ + public static function isTruthy($value) + { + if (!$value) { + return $value === 0 || $value === '0'; + } elseif ($value instanceof \stdClass) { + return (bool) get_object_vars($value); + } else { + return true; + } + } + + /** + * Gets the JMESPath type equivalent of a PHP variable. + * + * @param mixed $arg PHP variable + * @return string Returns the JSON data type + * @throws \InvalidArgumentException when an unknown type is given. + */ + public static function type($arg) + { + $type = gettype($arg); + if (isset(self::$typeMap[$type])) { + return self::$typeMap[$type]; + } elseif ($type === 'array') { + if (empty($arg)) { + return 'array'; + } + reset($arg); + return key($arg) === 0 ? 'array' : 'object'; + } elseif ($arg instanceof \stdClass) { + return 'object'; + } elseif ($arg instanceof \Closure) { + return 'expression'; + } elseif ($arg instanceof \ArrayAccess + && $arg instanceof \Countable + ) { + return count($arg) == 0 || $arg->offsetExists(0) + ? 'array' + : 'object'; + } elseif (method_exists($arg, '__toString')) { + return 'string'; + } + + throw new \InvalidArgumentException( + 'Unable to determine JMESPath type from ' . get_class($arg) + ); + } + + /** + * Determine if the provided value is a JMESPath compatible object. + * + * @param mixed $value + * + * @return bool + */ + public static function isObject($value) + { + if (is_array($value)) { + return !$value || array_keys($value)[0] !== 0; + } + + // Handle array-like values. Must be empty or offset 0 does not exist + return $value instanceof \Countable && $value instanceof \ArrayAccess + ? count($value) == 0 || !$value->offsetExists(0) + : $value instanceof \stdClass; + } + + /** + * Determine if the provided value is a JMESPath compatible array. + * + * @param mixed $value + * + * @return bool + */ + public static function isArray($value) + { + if (is_array($value)) { + return !$value || array_keys($value)[0] === 0; + } + + // Handle array-like values. Must be empty or offset 0 exists. + return $value instanceof \Countable && $value instanceof \ArrayAccess + ? count($value) == 0 || $value->offsetExists(0) + : false; + } + + /** + * JSON aware value comparison function. + * + * @param mixed $a First value to compare + * @param mixed $b Second value to compare + * + * @return bool + */ + public static function isEqual($a, $b) + { + if ($a === $b) { + return true; + } elseif ($a instanceof \stdClass) { + return self::isEqual((array) $a, $b); + } elseif ($b instanceof \stdClass) { + return self::isEqual($a, (array) $b); + } else { + return false; + } + } + + /** + * Safely add together two values. + * + * @param mixed $a First value to add + * @param mixed $b Second value to add + * + * @return int|float + */ + public static function add($a, $b) + { + if (is_numeric($a)) { + if (is_numeric($b)) { + return $a + $b; + } else { + return $a; + } + } else { + if (is_numeric($b)) { + return $b; + } else { + return 0; + } + } + } + + /** + * JMESPath requires a stable sorting algorithm, so here we'll implement + * a simple Schwartzian transform that uses array index positions as tie + * breakers. + * + * @param array $data List or map of data to sort + * @param callable $sortFn Callable used to sort values + * + * @return array Returns the sorted array + * @link http://en.wikipedia.org/wiki/Schwartzian_transform + */ + public static function stableSort(array $data, callable $sortFn) + { + // Decorate each item by creating an array of [value, index] + array_walk($data, function (&$v, $k) { + $v = [$v, $k]; + }); + // Sort by the sort function and use the index as a tie-breaker + uasort($data, function ($a, $b) use ($sortFn) { + return $sortFn($a[0], $b[0]) ?: ($a[1] < $b[1] ? -1 : 1); + }); + + // Undecorate each item and return the resulting sorted array + return array_map(function ($v) { + return $v[0]; + }, array_values($data)); + } + + /** + * Creates a Python-style slice of a string or array. + * + * @param array|string $value Value to slice + * @param int|null $start Starting position + * @param int|null $stop Stop position + * @param int $step Step (1, 2, -1, -2, etc.) + * + * @return array|string + * @throws \InvalidArgumentException + */ + public static function slice($value, $start = null, $stop = null, $step = 1) + { + if (!is_array($value) && !is_string($value)) { + throw new \InvalidArgumentException('Expects string or array'); + } + + return self::sliceIndices($value, $start, $stop, $step); + } + + private static function adjustEndpoint($length, $endpoint, $step) + { + if ($endpoint < 0) { + $endpoint += $length; + if ($endpoint < 0) { + $endpoint = $step < 0 ? -1 : 0; + } + } elseif ($endpoint >= $length) { + $endpoint = $step < 0 ? $length - 1 : $length; + } + + return $endpoint; + } + + private static function adjustSlice($length, $start, $stop, $step) + { + if ($step === null) { + $step = 1; + } elseif ($step === 0) { + throw new \RuntimeException('step cannot be 0'); + } + + if ($start === null) { + $start = $step < 0 ? $length - 1 : 0; + } else { + $start = self::adjustEndpoint($length, $start, $step); + } + + if ($stop === null) { + $stop = $step < 0 ? -1 : $length; + } else { + $stop = self::adjustEndpoint($length, $stop, $step); + } + + return [$start, $stop, $step]; + } + + private static function sliceIndices($subject, $start, $stop, $step) + { + $type = gettype($subject); + $len = $type == 'string' ? mb_strlen($subject, 'UTF-8') : count($subject); + list($start, $stop, $step) = self::adjustSlice($len, $start, $stop, $step); + + $result = []; + if ($step > 0) { + for ($i = $start; $i < $stop; $i += $step) { + $result[] = $subject[$i]; + } + } else { + for ($i = $start; $i > $stop; $i += $step) { + $result[] = $subject[$i]; + } + } + + return $type == 'string' ? implode('', $result) : $result; + } +} diff --git a/vendor/symfony/polyfill-ctype/Ctype.php b/vendor/symfony/polyfill-ctype/Ctype.php new file mode 100644 index 0000000..ba75a2c --- /dev/null +++ b/vendor/symfony/polyfill-ctype/Ctype.php @@ -0,0 +1,232 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Ctype; + +/** + * Ctype implementation through regex. + * + * @internal + * + * @author Gert de Pagter + */ +final class Ctype +{ + /** + * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. + * + * @see https://php.net/ctype-alnum + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_alnum($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is a letter, FALSE otherwise. + * + * @see https://php.net/ctype-alpha + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_alpha($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); + } + + /** + * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. + * + * @see https://php.net/ctype-cntrl + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_cntrl($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); + } + + /** + * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. + * + * @see https://php.net/ctype-digit + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_digit($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. + * + * @see https://php.net/ctype-graph + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_graph($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); + } + + /** + * Returns TRUE if every character in text is a lowercase letter. + * + * @see https://php.net/ctype-lower + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_lower($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); + } + + /** + * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. + * + * @see https://php.net/ctype-print + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_print($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); + } + + /** + * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. + * + * @see https://php.net/ctype-punct + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_punct($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); + } + + /** + * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. + * + * @see https://php.net/ctype-space + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_space($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); + } + + /** + * Returns TRUE if every character in text is an uppercase letter. + * + * @see https://php.net/ctype-upper + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_upper($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); + } + + /** + * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. + * + * @see https://php.net/ctype-xdigit + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_xdigit($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); + } + + /** + * Converts integers to their char versions according to normal ctype behaviour, if needed. + * + * If an integer between -128 and 255 inclusive is provided, + * it is interpreted as the ASCII value of a single character + * (negative values have 256 added in order to allow characters in the Extended ASCII range). + * Any other integer is interpreted as a string containing the decimal digits of the integer. + * + * @param mixed $int + * @param string $function + * + * @return mixed + */ + private static function convert_int_to_char_for_ctype($int, $function) + { + if (!\is_int($int)) { + return $int; + } + + if ($int < -128 || $int > 255) { + return (string) $int; + } + + if (\PHP_VERSION_ID >= 80100) { + @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED); + } + + if ($int < 0) { + $int += 256; + } + + return \chr($int); + } +} diff --git a/vendor/symfony/polyfill-ctype/LICENSE b/vendor/symfony/polyfill-ctype/LICENSE new file mode 100644 index 0000000..7536cae --- /dev/null +++ b/vendor/symfony/polyfill-ctype/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-ctype/README.md b/vendor/symfony/polyfill-ctype/README.md new file mode 100644 index 0000000..b144d03 --- /dev/null +++ b/vendor/symfony/polyfill-ctype/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / Ctype +======================== + +This component provides `ctype_*` functions to users who run php versions without the ctype extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-ctype/bootstrap.php b/vendor/symfony/polyfill-ctype/bootstrap.php new file mode 100644 index 0000000..d54524b --- /dev/null +++ b/vendor/symfony/polyfill-ctype/bootstrap.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit($text) { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph($text) { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower($text) { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print($text) { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct($text) { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space($text) { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper($text) { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } +} diff --git a/vendor/symfony/polyfill-ctype/bootstrap80.php b/vendor/symfony/polyfill-ctype/bootstrap80.php new file mode 100644 index 0000000..ab2f861 --- /dev/null +++ b/vendor/symfony/polyfill-ctype/bootstrap80.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (!function_exists('ctype_alnum')) { + function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); } +} diff --git a/vendor/symfony/polyfill-ctype/composer.json b/vendor/symfony/polyfill-ctype/composer.json new file mode 100644 index 0000000..131ca7a --- /dev/null +++ b/vendor/symfony/polyfill-ctype/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/polyfill-ctype", + "type": "library", + "description": "Symfony polyfill for ctype functions", + "keywords": ["polyfill", "compatibility", "portable", "ctype"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/vendor/symfony/yaml/.gitignore b/vendor/symfony/yaml/.gitignore new file mode 100644 index 0000000..c49a5d8 --- /dev/null +++ b/vendor/symfony/yaml/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/vendor/symfony/yaml/CHANGELOG.md b/vendor/symfony/yaml/CHANGELOG.md new file mode 100644 index 0000000..f55b570 --- /dev/null +++ b/vendor/symfony/yaml/CHANGELOG.md @@ -0,0 +1,28 @@ +CHANGELOG +========= + +2.8.0 +----- + + * Deprecated usage of a colon in an unquoted mapping value + * Deprecated usage of @, \`, | and > at the beginning of an unquoted string + * When surrounding strings with double-quotes, you must now escape `\` characters. Not + escaping those characters (when surrounded by double-quotes) is deprecated. + + Before: + + ```yml + class: "Foo\Var" + ``` + + After: + + ```yml + class: "Foo\\Var" + ``` + +2.1.0 +----- + + * Yaml::parse() does not evaluate loaded files as PHP files by default + anymore (call Yaml::enablePhpParsing() to get back the old behavior) diff --git a/vendor/symfony/yaml/Dumper.php b/vendor/symfony/yaml/Dumper.php new file mode 100644 index 0000000..8b523d1 --- /dev/null +++ b/vendor/symfony/yaml/Dumper.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +/** + * Dumper dumps PHP variables to YAML strings. + * + * @author Fabien Potencier + */ +class Dumper +{ + /** + * The amount of spaces to use for indentation of nested nodes. + * + * @var int + */ + protected $indentation = 4; + + /** + * Sets the indentation. + * + * @param int $num The amount of spaces to use for indentation of nested nodes + */ + public function setIndentation($num) + { + if ($num < 1) { + throw new \InvalidArgumentException('The indentation must be greater than zero.'); + } + + $this->indentation = (int) $num; + } + + /** + * Dumps a PHP value to YAML. + * + * @param mixed $input The PHP value + * @param int $inline The level where you switch to inline YAML + * @param int $indent The level of indentation (used internally) + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * + * @return string The YAML representation of the PHP value + */ + public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false) + { + $output = ''; + $prefix = $indent ? str_repeat(' ', $indent) : ''; + + if ($inline <= 0 || !\is_array($input) || empty($input)) { + $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport); + } else { + $isAHash = Inline::isHash($input); + + foreach ($input as $key => $value) { + $willBeInlined = $inline - 1 <= 0 || !\is_array($value) || empty($value); + + $output .= sprintf('%s%s%s%s', + $prefix, + $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-', + $willBeInlined ? ' ' : "\n", + $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport) + ).($willBeInlined ? "\n" : ''); + } + } + + return $output; + } +} diff --git a/vendor/symfony/yaml/Escaper.php b/vendor/symfony/yaml/Escaper.php new file mode 100644 index 0000000..2b1321f --- /dev/null +++ b/vendor/symfony/yaml/Escaper.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +/** + * Escaper encapsulates escaping rules for single and double-quoted + * YAML strings. + * + * @author Matthew Lewinski + * + * @internal + */ +class Escaper +{ + // Characters that would cause a dumped string to require double quoting. + const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9"; + + // Mapping arrays for escaping a double quoted string. The backslash is + // first to ensure proper escaping because str_replace operates iteratively + // on the input arrays. This ordering of the characters avoids the use of strtr, + // which performs more slowly. + private static $escapees = array('\\', '\\\\', '\\"', '"', + "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", + "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", + "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", + "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", + "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9", + ); + private static $escaped = array('\\\\', '\\"', '\\\\', '\\"', + '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', + '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', + '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', + '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', + '\\N', '\\_', '\\L', '\\P', + ); + + /** + * Determines if a PHP value would require double quoting in YAML. + * + * @param string $value A PHP value + * + * @return bool True if the value would require double quotes + */ + public static function requiresDoubleQuoting($value) + { + return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); + } + + /** + * Escapes and surrounds a PHP value with double quotes. + * + * @param string $value A PHP value + * + * @return string The quoted, escaped string + */ + public static function escapeWithDoubleQuotes($value) + { + return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value)); + } + + /** + * Determines if a PHP value would require single quoting in YAML. + * + * @param string $value A PHP value + * + * @return bool True if the value would require single quotes + */ + public static function requiresSingleQuoting($value) + { + // Determines if a PHP value is entirely composed of a value that would + // require single quoting in YAML. + if (\in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) { + return true; + } + + // Determines if the PHP value contains any single characters that would + // cause it to require single quoting in YAML. + return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); + } + + /** + * Escapes and surrounds a PHP value with single quotes. + * + * @param string $value A PHP value + * + * @return string The quoted, escaped string + */ + public static function escapeWithSingleQuotes($value) + { + return sprintf("'%s'", str_replace('\'', '\'\'', $value)); + } +} diff --git a/vendor/symfony/yaml/Exception/DumpException.php b/vendor/symfony/yaml/Exception/DumpException.php new file mode 100644 index 0000000..cce972f --- /dev/null +++ b/vendor/symfony/yaml/Exception/DumpException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception class thrown when an error occurs during dumping. + * + * @author Fabien Potencier + */ +class DumpException extends RuntimeException +{ +} diff --git a/vendor/symfony/yaml/Exception/ExceptionInterface.php b/vendor/symfony/yaml/Exception/ExceptionInterface.php new file mode 100644 index 0000000..ad850ee --- /dev/null +++ b/vendor/symfony/yaml/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Fabien Potencier + */ +interface ExceptionInterface +{ +} diff --git a/vendor/symfony/yaml/Exception/ParseException.php b/vendor/symfony/yaml/Exception/ParseException.php new file mode 100644 index 0000000..60802b6 --- /dev/null +++ b/vendor/symfony/yaml/Exception/ParseException.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception class thrown when an error occurs during parsing. + * + * @author Fabien Potencier + */ +class ParseException extends RuntimeException +{ + private $parsedFile; + private $parsedLine; + private $snippet; + private $rawMessage; + + /** + * @param string $message The error message + * @param int $parsedLine The line where the error occurred + * @param string|null $snippet The snippet of code near the problem + * @param string|null $parsedFile The file name where the error occurred + * @param \Exception|null $previous The previous exception + */ + public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null) + { + $this->parsedFile = $parsedFile; + $this->parsedLine = $parsedLine; + $this->snippet = $snippet; + $this->rawMessage = $message; + + $this->updateRepr(); + + parent::__construct($this->message, 0, $previous); + } + + /** + * Gets the snippet of code near the error. + * + * @return string The snippet of code + */ + public function getSnippet() + { + return $this->snippet; + } + + /** + * Sets the snippet of code near the error. + * + * @param string $snippet The code snippet + */ + public function setSnippet($snippet) + { + $this->snippet = $snippet; + + $this->updateRepr(); + } + + /** + * Gets the filename where the error occurred. + * + * This method returns null if a string is parsed. + * + * @return string The filename + */ + public function getParsedFile() + { + return $this->parsedFile; + } + + /** + * Sets the filename where the error occurred. + * + * @param string $parsedFile The filename + */ + public function setParsedFile($parsedFile) + { + $this->parsedFile = $parsedFile; + + $this->updateRepr(); + } + + /** + * Gets the line where the error occurred. + * + * @return int The file line + */ + public function getParsedLine() + { + return $this->parsedLine; + } + + /** + * Sets the line where the error occurred. + * + * @param int $parsedLine The file line + */ + public function setParsedLine($parsedLine) + { + $this->parsedLine = $parsedLine; + + $this->updateRepr(); + } + + private function updateRepr() + { + $this->message = $this->rawMessage; + + $dot = false; + if ('.' === substr($this->message, -1)) { + $this->message = substr($this->message, 0, -1); + $dot = true; + } + + if (null !== $this->parsedFile) { + if (\PHP_VERSION_ID >= 50400) { + $jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; + } else { + $jsonOptions = 0; + } + $this->message .= sprintf(' in %s', json_encode($this->parsedFile, $jsonOptions)); + } + + if ($this->parsedLine >= 0) { + $this->message .= sprintf(' at line %d', $this->parsedLine); + } + + if ($this->snippet) { + $this->message .= sprintf(' (near "%s")', $this->snippet); + } + + if ($dot) { + $this->message .= '.'; + } + } +} diff --git a/vendor/symfony/yaml/Exception/RuntimeException.php b/vendor/symfony/yaml/Exception/RuntimeException.php new file mode 100644 index 0000000..3f36b73 --- /dev/null +++ b/vendor/symfony/yaml/Exception/RuntimeException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception class thrown when an error occurs during parsing. + * + * @author Romain Neutron + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/yaml/Inline.php b/vendor/symfony/yaml/Inline.php new file mode 100644 index 0000000..639ff4a --- /dev/null +++ b/vendor/symfony/yaml/Inline.php @@ -0,0 +1,609 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Exception\DumpException; +use Symfony\Component\Yaml\Exception\ParseException; + +/** + * Inline implements a YAML parser/dumper for the YAML inline syntax. + * + * @author Fabien Potencier + */ +class Inline +{ + const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')'; + + private static $exceptionOnInvalidType = false; + private static $objectSupport = false; + private static $objectForMap = false; + + /** + * Converts a YAML string to a PHP value. + * + * @param string $value A YAML string + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * @param bool $objectForMap True if maps should return a stdClass instead of array() + * @param array $references Mapping of variable names to values + * + * @return mixed A PHP value + * + * @throws ParseException + */ + public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array()) + { + self::$exceptionOnInvalidType = $exceptionOnInvalidType; + self::$objectSupport = $objectSupport; + self::$objectForMap = $objectForMap; + + $value = trim($value); + + if ('' === $value) { + return ''; + } + + if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('ASCII'); + } + + $i = 0; + switch ($value[0]) { + case '[': + $result = self::parseSequence($value, $i, $references); + ++$i; + break; + case '{': + $result = self::parseMapping($value, $i, $references); + ++$i; + break; + default: + $result = self::parseScalar($value, null, array('"', "'"), $i, true, $references); + } + + // some comments are allowed at the end + if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) { + throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i))); + } + + if (isset($mbEncoding)) { + mb_internal_encoding($mbEncoding); + } + + return $result; + } + + /** + * Dumps a given PHP variable to a YAML string. + * + * @param mixed $value The PHP variable to convert + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * + * @return string The YAML string representing the PHP value + * + * @throws DumpException When trying to dump PHP resource + */ + public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false) + { + switch (true) { + case \is_resource($value): + if ($exceptionOnInvalidType) { + throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); + } + + return 'null'; + case \is_object($value): + if ($objectSupport) { + return '!php/object:'.serialize($value); + } + + if ($exceptionOnInvalidType) { + throw new DumpException('Object support when dumping a YAML file has been disabled.'); + } + + return 'null'; + case \is_array($value): + return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport); + case null === $value: + return 'null'; + case true === $value: + return 'true'; + case false === $value: + return 'false'; + case ctype_digit($value): + return \is_string($value) ? "'$value'" : (int) $value; + case is_numeric($value): + $locale = setlocale(LC_NUMERIC, 0); + if (false !== $locale) { + setlocale(LC_NUMERIC, 'C'); + } + if (\is_float($value)) { + $repr = (string) $value; + if (is_infinite($value)) { + $repr = str_ireplace('INF', '.Inf', $repr); + } elseif (floor($value) == $value && $repr == $value) { + // Preserve float data type since storing a whole number will result in integer value. + $repr = '!!float '.$repr; + } + } else { + $repr = \is_string($value) ? "'$value'" : (string) $value; + } + if (false !== $locale) { + setlocale(LC_NUMERIC, $locale); + } + + return $repr; + case '' == $value: + return "''"; + case Escaper::requiresDoubleQuoting($value): + return Escaper::escapeWithDoubleQuotes($value); + case Escaper::requiresSingleQuoting($value): + case Parser::preg_match(self::getHexRegex(), $value): + case Parser::preg_match(self::getTimestampRegex(), $value): + return Escaper::escapeWithSingleQuotes($value); + default: + return $value; + } + } + + /** + * Check if given array is hash or just normal indexed array. + * + * @internal + * + * @param array $value The PHP array to check + * + * @return bool true if value is hash array, false otherwise + */ + public static function isHash(array $value) + { + $expectedKey = 0; + + foreach ($value as $key => $val) { + if ($key !== $expectedKey++) { + return true; + } + } + + return false; + } + + /** + * Dumps a PHP array to a YAML string. + * + * @param array $value The PHP array to dump + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * + * @return string The YAML string representing the PHP array + */ + private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport) + { + // array + if ($value && !self::isHash($value)) { + $output = array(); + foreach ($value as $val) { + $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport); + } + + return sprintf('[%s]', implode(', ', $output)); + } + + // hash + $output = array(); + foreach ($value as $key => $val) { + $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport)); + } + + return sprintf('{ %s }', implode(', ', $output)); + } + + /** + * Parses a YAML scalar. + * + * @param string $scalar + * @param string[] $delimiters + * @param string[] $stringDelimiters + * @param int &$i + * @param bool $evaluate + * @param array $references + * + * @return string + * + * @throws ParseException When malformed inline YAML string is parsed + * + * @internal + */ + public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array()) + { + if (\in_array($scalar[$i], $stringDelimiters)) { + // quoted scalar + $output = self::parseQuotedScalar($scalar, $i); + + if (null !== $delimiters) { + $tmp = ltrim(substr($scalar, $i), ' '); + if ('' === $tmp) { + throw new ParseException(sprintf('Unexpected end of line, expected one of "%s".', implode('', $delimiters))); + } + if (!\in_array($tmp[0], $delimiters)) { + throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i))); + } + } + } else { + // "normal" string + if (!$delimiters) { + $output = substr($scalar, $i); + $i += \strlen($output); + + // remove comments + if (Parser::preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) { + $output = substr($output, 0, $match[0][1]); + } + } elseif (Parser::preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { + $output = $match[1]; + $i += \strlen($output); + } else { + throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar)); + } + + // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >) + if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) { + @trigger_error(sprintf('Not quoting the scalar "%s" starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output, $output[0]), E_USER_DEPRECATED); + + // to be thrown in 3.0 + // throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0])); + } + + if ($evaluate) { + $output = self::evaluateScalar($output, $references); + } + } + + return $output; + } + + /** + * Parses a YAML quoted scalar. + * + * @param string $scalar + * @param int &$i + * + * @return string + * + * @throws ParseException When malformed inline YAML string is parsed + */ + private static function parseQuotedScalar($scalar, &$i) + { + if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { + throw new ParseException(sprintf('Malformed inline YAML string: %s.', substr($scalar, $i))); + } + + $output = substr($match[0], 1, \strlen($match[0]) - 2); + + $unescaper = new Unescaper(); + if ('"' == $scalar[$i]) { + $output = $unescaper->unescapeDoubleQuotedString($output); + } else { + $output = $unescaper->unescapeSingleQuotedString($output); + } + + $i += \strlen($match[0]); + + return $output; + } + + /** + * Parses a YAML sequence. + * + * @param string $sequence + * @param int &$i + * @param array $references + * + * @return array + * + * @throws ParseException When malformed inline YAML string is parsed + */ + private static function parseSequence($sequence, &$i = 0, $references = array()) + { + $output = array(); + $len = \strlen($sequence); + ++$i; + + // [foo, bar, ...] + while ($i < $len) { + switch ($sequence[$i]) { + case '[': + // nested sequence + $output[] = self::parseSequence($sequence, $i, $references); + break; + case '{': + // nested mapping + $output[] = self::parseMapping($sequence, $i, $references); + break; + case ']': + return $output; + case ',': + case ' ': + break; + default: + $isQuoted = \in_array($sequence[$i], array('"', "'")); + $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references); + + // the value can be an array if a reference has been resolved to an array var + if (!\is_array($value) && !$isQuoted && false !== strpos($value, ': ')) { + // embedded mapping? + try { + $pos = 0; + $value = self::parseMapping('{'.$value.'}', $pos, $references); + } catch (\InvalidArgumentException $e) { + // no, it's not + } + } + + $output[] = $value; + + --$i; + } + + ++$i; + } + + throw new ParseException(sprintf('Malformed inline YAML string: %s.', $sequence)); + } + + /** + * Parses a YAML mapping. + * + * @param string $mapping + * @param int &$i + * @param array $references + * + * @return array|\stdClass + * + * @throws ParseException When malformed inline YAML string is parsed + */ + private static function parseMapping($mapping, &$i = 0, $references = array()) + { + $output = array(); + $len = \strlen($mapping); + ++$i; + $allowOverwrite = false; + + // {foo: bar, bar:foo, ...} + while ($i < $len) { + switch ($mapping[$i]) { + case ' ': + case ',': + ++$i; + continue 2; + case '}': + if (self::$objectForMap) { + return (object) $output; + } + + return $output; + } + + // key + $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false); + + if ('<<' === $key) { + $allowOverwrite = true; + } + + // value + $done = false; + + while ($i < $len) { + switch ($mapping[$i]) { + case '[': + // nested sequence + $value = self::parseSequence($mapping, $i, $references); + // Spec: Keys MUST be unique; first one wins. + // Parser cannot abort this mapping earlier, since lines + // are processed sequentially. + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + foreach ($value as $parsedValue) { + $output += $parsedValue; + } + } elseif ($allowOverwrite || !isset($output[$key])) { + $output[$key] = $value; + } + $done = true; + break; + case '{': + // nested mapping + $value = self::parseMapping($mapping, $i, $references); + // Spec: Keys MUST be unique; first one wins. + // Parser cannot abort this mapping earlier, since lines + // are processed sequentially. + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + $output += $value; + } elseif ($allowOverwrite || !isset($output[$key])) { + $output[$key] = $value; + } + $done = true; + break; + case ':': + case ' ': + break; + default: + $value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references); + // Spec: Keys MUST be unique; first one wins. + // Parser cannot abort this mapping earlier, since lines + // are processed sequentially. + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + $output += $value; + } elseif ($allowOverwrite || !isset($output[$key])) { + $output[$key] = $value; + } + $done = true; + --$i; + } + + ++$i; + + if ($done) { + continue 2; + } + } + } + + throw new ParseException(sprintf('Malformed inline YAML string: %s.', $mapping)); + } + + /** + * Evaluates scalars and replaces magic values. + * + * @param string $scalar + * @param array $references + * + * @return mixed The evaluated YAML string + * + * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved + */ + private static function evaluateScalar($scalar, $references = array()) + { + $scalar = trim($scalar); + $scalarLower = strtolower($scalar); + + if (0 === strpos($scalar, '*')) { + if (false !== $pos = strpos($scalar, '#')) { + $value = substr($scalar, 1, $pos - 2); + } else { + $value = substr($scalar, 1); + } + + // an unquoted * + if (false === $value || '' === $value) { + throw new ParseException('A reference must contain at least one character.'); + } + + if (!array_key_exists($value, $references)) { + throw new ParseException(sprintf('Reference "%s" does not exist.', $value)); + } + + return $references[$value]; + } + + switch (true) { + case 'null' === $scalarLower: + case '' === $scalar: + case '~' === $scalar: + return; + case 'true' === $scalarLower: + return true; + case 'false' === $scalarLower: + return false; + // Optimise for returning strings. + case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || '!' === $scalar[0] || is_numeric($scalar[0]): + switch (true) { + case 0 === strpos($scalar, '!str'): + return (string) substr($scalar, 5); + case 0 === strpos($scalar, '! '): + return (int) self::parseScalar(substr($scalar, 2)); + case 0 === strpos($scalar, '!php/object:'): + if (self::$objectSupport) { + return unserialize(substr($scalar, 12)); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.'); + } + + return; + case 0 === strpos($scalar, '!!php/object:'): + if (self::$objectSupport) { + return unserialize(substr($scalar, 13)); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.'); + } + + return; + case 0 === strpos($scalar, '!!float '): + return (float) substr($scalar, 8); + case ctype_digit($scalar): + $raw = $scalar; + $cast = (int) $scalar; + + return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); + case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)): + $raw = $scalar; + $cast = (int) $scalar; + + return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw); + case is_numeric($scalar): + case Parser::preg_match(self::getHexRegex(), $scalar): + return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar; + case '.inf' === $scalarLower: + case '.nan' === $scalarLower: + return -log(0); + case '-.inf' === $scalarLower: + return log(0); + case Parser::preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): + return (float) str_replace(',', '', $scalar); + case Parser::preg_match(self::getTimestampRegex(), $scalar): + $timeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $time = strtotime($scalar); + date_default_timezone_set($timeZone); + + return $time; + } + // no break + default: + return (string) $scalar; + } + } + + /** + * Gets a regex that matches a YAML date. + * + * @return string The regular expression + * + * @see http://www.yaml.org/spec/1.2/spec.html#id2761573 + */ + private static function getTimestampRegex() + { + return <<[0-9][0-9][0-9][0-9]) + -(?P[0-9][0-9]?) + -(?P[0-9][0-9]?) + (?:(?:[Tt]|[ \t]+) + (?P[0-9][0-9]?) + :(?P[0-9][0-9]) + :(?P[0-9][0-9]) + (?:\.(?P[0-9]*))? + (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) + (?::(?P[0-9][0-9]))?))?)? + $~x +EOF; + } + + /** + * Gets a regex that matches a YAML number in hexadecimal notation. + * + * @return string + */ + private static function getHexRegex() + { + return '~^0x[0-9a-f]++$~i'; + } +} diff --git a/vendor/symfony/yaml/LICENSE b/vendor/symfony/yaml/LICENSE new file mode 100644 index 0000000..21d7fb9 --- /dev/null +++ b/vendor/symfony/yaml/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2018 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/yaml/Parser.php b/vendor/symfony/yaml/Parser.php new file mode 100644 index 0000000..cb0d8f1 --- /dev/null +++ b/vendor/symfony/yaml/Parser.php @@ -0,0 +1,852 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Exception\ParseException; + +/** + * Parser parses YAML strings to convert them to PHP arrays. + * + * @author Fabien Potencier + */ +class Parser +{ + const BLOCK_SCALAR_HEADER_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; + // BC - wrongly named + const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN; + + private $offset = 0; + private $totalNumberOfLines; + private $lines = array(); + private $currentLineNb = -1; + private $currentLine = ''; + private $refs = array(); + private $skippedLineNumbers = array(); + private $locallySkippedLineNumbers = array(); + + /** + * @param int $offset The offset of YAML document (used for line numbers in error messages) + * @param int|null $totalNumberOfLines The overall number of lines being parsed + * @param int[] $skippedLineNumbers Number of comment lines that have been skipped by the parser + */ + public function __construct($offset = 0, $totalNumberOfLines = null, array $skippedLineNumbers = array()) + { + $this->offset = $offset; + $this->totalNumberOfLines = $totalNumberOfLines; + $this->skippedLineNumbers = $skippedLineNumbers; + } + + /** + * Parses a YAML string to a PHP value. + * + * @param string $value A YAML string + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * @param bool $objectForMap True if maps should return a stdClass instead of array() + * + * @return mixed A PHP value + * + * @throws ParseException If the YAML is not valid + */ + public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false) + { + if (false === preg_match('//u', $value)) { + throw new ParseException('The YAML value does not appear to be valid UTF-8.'); + } + + $this->refs = array(); + + $mbEncoding = null; + $e = null; + $data = null; + + if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('UTF-8'); + } + + try { + $data = $this->doParse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if (null !== $mbEncoding) { + mb_internal_encoding($mbEncoding); + } + + $this->lines = array(); + $this->currentLine = ''; + $this->refs = array(); + $this->skippedLineNumbers = array(); + $this->locallySkippedLineNumbers = array(); + + if (null !== $e) { + throw $e; + } + + return $data; + } + + private function doParse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false) + { + $this->currentLineNb = -1; + $this->currentLine = ''; + $value = $this->cleanup($value); + $this->lines = explode("\n", $value); + $this->locallySkippedLineNumbers = array(); + + if (null === $this->totalNumberOfLines) { + $this->totalNumberOfLines = \count($this->lines); + } + + $data = array(); + $context = null; + $allowOverwrite = false; + + while ($this->moveToNextLine()) { + if ($this->isCurrentLineEmpty()) { + continue; + } + + // tab? + if ("\t" === $this->currentLine[0]) { + throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + + $isRef = $mergeNode = false; + if (self::preg_match('#^\-((?P\s+)(?P.+))?$#u', rtrim($this->currentLine), $values)) { + if ($context && 'mapping' == $context) { + throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + $context = 'sequence'; + + if (isset($values['value']) && self::preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { + $isRef = $matches['ref']; + $values['value'] = $matches['value']; + } + + // array + if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { + $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap); + } else { + if (isset($values['leadspaces']) + && self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+))?$#u', rtrim($values['value']), $matches) + ) { + // this is a compact notation element, add to next block and parse + $block = $values['value']; + if ($this->isNextLineIndented()) { + $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1); + } + + $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $exceptionOnInvalidType, $objectSupport, $objectForMap); + } else { + $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context); + } + } + if ($isRef) { + $this->refs[$isRef] = end($data); + } + } elseif ( + self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+))?$#u', rtrim($this->currentLine), $values) + && (false === strpos($values['key'], ' #') || \in_array($values['key'][0], array('"', "'"))) + ) { + if ($context && 'sequence' == $context) { + throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine); + } + $context = 'mapping'; + + // force correct settings + Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs); + try { + $key = Inline::parseScalar($values['key']); + } catch (ParseException $e) { + $e->setParsedLine($this->getRealCurrentLineNb() + 1); + $e->setSnippet($this->currentLine); + + throw $e; + } + + // Convert float keys to strings, to avoid being converted to integers by PHP + if (\is_float($key)) { + $key = (string) $key; + } + + if ('<<' === $key && (!isset($values['value']) || !self::preg_match('#^&(?P[^ ]+)#u', $values['value'], $refMatches))) { + $mergeNode = true; + $allowOverwrite = true; + if (isset($values['value']) && 0 === strpos($values['value'], '*')) { + $refName = substr($values['value'], 1); + if (!array_key_exists($refName, $this->refs)) { + throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + + $refValue = $this->refs[$refName]; + + if (!\is_array($refValue)) { + throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + + $data += $refValue; // array union + } else { + if (isset($values['value']) && '' !== $values['value']) { + $value = $values['value']; + } else { + $value = $this->getNextEmbedBlock(); + } + $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $exceptionOnInvalidType, $objectSupport, $objectForMap); + + if (!\is_array($parsed)) { + throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + + if (isset($parsed[0])) { + // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes + // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier + // in the sequence override keys specified in later mapping nodes. + foreach ($parsed as $parsedItem) { + if (!\is_array($parsedItem)) { + throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem); + } + + $data += $parsedItem; // array union + } + } else { + // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the + // current mapping, unless the key already exists in it. + $data += $parsed; // array union + } + } + } elseif ('<<' !== $key && isset($values['value']) && self::preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { + $isRef = $matches['ref']; + $values['value'] = $matches['value']; + } + + if ($mergeNode) { + // Merge keys + } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#') || '<<' === $key) { + // hash + // if next line is less indented or equal, then it means that the current value is null + if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) { + // Spec: Keys MUST be unique; first one wins. + // But overwriting is allowed when a merge node is used in current block. + if ($allowOverwrite || !isset($data[$key])) { + $data[$key] = null; + } + } else { + $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap); + + if ('<<' === $key) { + $this->refs[$refMatches['ref']] = $value; + $data += $value; + } elseif ($allowOverwrite || !isset($data[$key])) { + // Spec: Keys MUST be unique; first one wins. + // But overwriting is allowed when a merge node is used in current block. + $data[$key] = $value; + } + } + } else { + $value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context); + // Spec: Keys MUST be unique; first one wins. + // But overwriting is allowed when a merge node is used in current block. + if ($allowOverwrite || !isset($data[$key])) { + $data[$key] = $value; + } + } + if ($isRef) { + $this->refs[$isRef] = $data[$key]; + } + } else { + // multiple documents are not supported + if ('---' === $this->currentLine) { + throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine); + } + + // 1-liner optionally followed by newline(s) + if (\is_string($value) && $this->lines[0] === trim($value)) { + try { + $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs); + } catch (ParseException $e) { + $e->setParsedLine($this->getRealCurrentLineNb() + 1); + $e->setSnippet($this->currentLine); + + throw $e; + } + + return $value; + } + + throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + } + + if ($objectForMap && !\is_object($data) && 'mapping' === $context) { + $object = new \stdClass(); + + foreach ($data as $key => $value) { + $object->$key = $value; + } + + $data = $object; + } + + return empty($data) ? null : $data; + } + + private function parseBlock($offset, $yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap) + { + $skippedLineNumbers = $this->skippedLineNumbers; + + foreach ($this->locallySkippedLineNumbers as $lineNumber) { + if ($lineNumber < $offset) { + continue; + } + + $skippedLineNumbers[] = $lineNumber; + } + + $parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers); + $parser->refs = &$this->refs; + + return $parser->doParse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap); + } + + /** + * Returns the current line number (takes the offset into account). + * + * @return int The current line number + */ + private function getRealCurrentLineNb() + { + $realCurrentLineNumber = $this->currentLineNb + $this->offset; + + foreach ($this->skippedLineNumbers as $skippedLineNumber) { + if ($skippedLineNumber > $realCurrentLineNumber) { + break; + } + + ++$realCurrentLineNumber; + } + + return $realCurrentLineNumber; + } + + /** + * Returns the current line indentation. + * + * @return int The current line indentation + */ + private function getCurrentLineIndentation() + { + return \strlen($this->currentLine) - \strlen(ltrim($this->currentLine, ' ')); + } + + /** + * Returns the next embed block of YAML. + * + * @param int $indentation The indent level at which the block is to be read, or null for default + * @param bool $inSequence True if the enclosing data structure is a sequence + * + * @return string A YAML string + * + * @throws ParseException When indentation problem are detected + */ + private function getNextEmbedBlock($indentation = null, $inSequence = false) + { + $oldLineIndentation = $this->getCurrentLineIndentation(); + $blockScalarIndentations = array(); + + if ($this->isBlockScalarHeader()) { + $blockScalarIndentations[] = $this->getCurrentLineIndentation(); + } + + if (!$this->moveToNextLine()) { + return; + } + + if (null === $indentation) { + $newIndent = $this->getCurrentLineIndentation(); + + $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem(); + + if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) { + throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + } else { + $newIndent = $indentation; + } + + $data = array(); + if ($this->getCurrentLineIndentation() >= $newIndent) { + $data[] = substr($this->currentLine, $newIndent); + } else { + $this->moveToPreviousLine(); + + return; + } + + if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) { + // the previous line contained a dash but no item content, this line is a sequence item with the same indentation + // and therefore no nested list or mapping + $this->moveToPreviousLine(); + + return; + } + + $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); + + if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) { + $blockScalarIndentations[] = $this->getCurrentLineIndentation(); + } + + $previousLineIndentation = $this->getCurrentLineIndentation(); + + while ($this->moveToNextLine()) { + $indent = $this->getCurrentLineIndentation(); + + // terminate all block scalars that are more indented than the current line + if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && '' !== trim($this->currentLine)) { + foreach ($blockScalarIndentations as $key => $blockScalarIndentation) { + if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) { + unset($blockScalarIndentations[$key]); + } + } + } + + if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) { + $blockScalarIndentations[] = $this->getCurrentLineIndentation(); + } + + $previousLineIndentation = $indent; + + if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) { + $this->moveToPreviousLine(); + break; + } + + if ($this->isCurrentLineBlank()) { + $data[] = substr($this->currentLine, $newIndent); + continue; + } + + // we ignore "comment" lines only when we are not inside a scalar block + if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) { + // remember ignored comment lines (they are used later in nested + // parser calls to determine real line numbers) + // + // CAUTION: beware to not populate the global property here as it + // will otherwise influence the getRealCurrentLineNb() call here + // for consecutive comment lines and subsequent embedded blocks + $this->locallySkippedLineNumbers[] = $this->getRealCurrentLineNb(); + + continue; + } + + if ($indent >= $newIndent) { + $data[] = substr($this->currentLine, $newIndent); + } elseif (0 == $indent) { + $this->moveToPreviousLine(); + + break; + } else { + throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); + } + } + + return implode("\n", $data); + } + + /** + * Moves the parser to the next line. + * + * @return bool + */ + private function moveToNextLine() + { + if ($this->currentLineNb >= \count($this->lines) - 1) { + return false; + } + + $this->currentLine = $this->lines[++$this->currentLineNb]; + + return true; + } + + /** + * Moves the parser to the previous line. + * + * @return bool + */ + private function moveToPreviousLine() + { + if ($this->currentLineNb < 1) { + return false; + } + + $this->currentLine = $this->lines[--$this->currentLineNb]; + + return true; + } + + /** + * Parses a YAML value. + * + * @param string $value A YAML value + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * @param bool $objectForMap True if maps should return a stdClass instead of array() + * @param string $context The parser context (either sequence or mapping) + * + * @return mixed A PHP value + * + * @throws ParseException When reference does not exist + */ + private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $context) + { + if (0 === strpos($value, '*')) { + if (false !== $pos = strpos($value, '#')) { + $value = substr($value, 1, $pos - 2); + } else { + $value = substr($value, 1); + } + + if (!array_key_exists($value, $this->refs)) { + throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine); + } + + return $this->refs[$value]; + } + + if (self::preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) { + $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; + + return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers)); + } + + try { + $parsedValue = Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs); + + if ('mapping' === $context && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { + @trigger_error(sprintf('Using a colon in the unquoted mapping value "%s" in line %d is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $value, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); + + // to be thrown in 3.0 + // throw new ParseException('A colon cannot be used in an unquoted mapping value.'); + } + + return $parsedValue; + } catch (ParseException $e) { + $e->setParsedLine($this->getRealCurrentLineNb() + 1); + $e->setSnippet($this->currentLine); + + throw $e; + } + } + + /** + * Parses a block scalar. + * + * @param string $style The style indicator that was used to begin this block scalar (| or >) + * @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -) + * @param int $indentation The indentation indicator that was used to begin this block scalar + * + * @return string The text value + */ + private function parseBlockScalar($style, $chomping = '', $indentation = 0) + { + $notEOF = $this->moveToNextLine(); + if (!$notEOF) { + return ''; + } + + $isCurrentLineBlank = $this->isCurrentLineBlank(); + $blockLines = array(); + + // leading blank lines are consumed before determining indentation + while ($notEOF && $isCurrentLineBlank) { + // newline only if not EOF + if ($notEOF = $this->moveToNextLine()) { + $blockLines[] = ''; + $isCurrentLineBlank = $this->isCurrentLineBlank(); + } + } + + // determine indentation if not specified + if (0 === $indentation) { + if (self::preg_match('/^ +/', $this->currentLine, $matches)) { + $indentation = \strlen($matches[0]); + } + } + + if ($indentation > 0) { + $pattern = sprintf('/^ {%d}(.*)$/', $indentation); + + while ( + $notEOF && ( + $isCurrentLineBlank || + self::preg_match($pattern, $this->currentLine, $matches) + ) + ) { + if ($isCurrentLineBlank && \strlen($this->currentLine) > $indentation) { + $blockLines[] = substr($this->currentLine, $indentation); + } elseif ($isCurrentLineBlank) { + $blockLines[] = ''; + } else { + $blockLines[] = $matches[1]; + } + + // newline only if not EOF + if ($notEOF = $this->moveToNextLine()) { + $isCurrentLineBlank = $this->isCurrentLineBlank(); + } + } + } elseif ($notEOF) { + $blockLines[] = ''; + } + + if ($notEOF) { + $blockLines[] = ''; + $this->moveToPreviousLine(); + } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) { + $blockLines[] = ''; + } + + // folded style + if ('>' === $style) { + $text = ''; + $previousLineIndented = false; + $previousLineBlank = false; + + for ($i = 0, $blockLinesCount = \count($blockLines); $i < $blockLinesCount; ++$i) { + if ('' === $blockLines[$i]) { + $text .= "\n"; + $previousLineIndented = false; + $previousLineBlank = true; + } elseif (' ' === $blockLines[$i][0]) { + $text .= "\n".$blockLines[$i]; + $previousLineIndented = true; + $previousLineBlank = false; + } elseif ($previousLineIndented) { + $text .= "\n".$blockLines[$i]; + $previousLineIndented = false; + $previousLineBlank = false; + } elseif ($previousLineBlank || 0 === $i) { + $text .= $blockLines[$i]; + $previousLineIndented = false; + $previousLineBlank = false; + } else { + $text .= ' '.$blockLines[$i]; + $previousLineIndented = false; + $previousLineBlank = false; + } + } + } else { + $text = implode("\n", $blockLines); + } + + // deal with trailing newlines + if ('' === $chomping) { + $text = preg_replace('/\n+$/', "\n", $text); + } elseif ('-' === $chomping) { + $text = preg_replace('/\n+$/', '', $text); + } + + return $text; + } + + /** + * Returns true if the next line is indented. + * + * @return bool Returns true if the next line is indented, false otherwise + */ + private function isNextLineIndented() + { + $currentIndentation = $this->getCurrentLineIndentation(); + $EOF = !$this->moveToNextLine(); + + while (!$EOF && $this->isCurrentLineEmpty()) { + $EOF = !$this->moveToNextLine(); + } + + if ($EOF) { + return false; + } + + $ret = $this->getCurrentLineIndentation() > $currentIndentation; + + $this->moveToPreviousLine(); + + return $ret; + } + + /** + * Returns true if the current line is blank or if it is a comment line. + * + * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise + */ + private function isCurrentLineEmpty() + { + return $this->isCurrentLineBlank() || $this->isCurrentLineComment(); + } + + /** + * Returns true if the current line is blank. + * + * @return bool Returns true if the current line is blank, false otherwise + */ + private function isCurrentLineBlank() + { + return '' == trim($this->currentLine, ' '); + } + + /** + * Returns true if the current line is a comment line. + * + * @return bool Returns true if the current line is a comment line, false otherwise + */ + private function isCurrentLineComment() + { + //checking explicitly the first char of the trim is faster than loops or strpos + $ltrimmedLine = ltrim($this->currentLine, ' '); + + return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0]; + } + + private function isCurrentLineLastLineInDocument() + { + return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1); + } + + /** + * Cleanups a YAML string to be parsed. + * + * @param string $value The input YAML string + * + * @return string A cleaned up YAML string + */ + private function cleanup($value) + { + $value = str_replace(array("\r\n", "\r"), "\n", $value); + + // strip YAML header + $count = 0; + $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count); + $this->offset += $count; + + // remove leading comments + $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count); + if (1 == $count) { + // items have been removed, update the offset + $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); + $value = $trimmedValue; + } + + // remove start of the document marker (---) + $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count); + if (1 == $count) { + // items have been removed, update the offset + $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); + $value = $trimmedValue; + + // remove end of the document marker (...) + $value = preg_replace('#\.\.\.\s*$#', '', $value); + } + + return $value; + } + + /** + * Returns true if the next line starts unindented collection. + * + * @return bool Returns true if the next line starts unindented collection, false otherwise + */ + private function isNextLineUnIndentedCollection() + { + $currentIndentation = $this->getCurrentLineIndentation(); + $notEOF = $this->moveToNextLine(); + + while ($notEOF && $this->isCurrentLineEmpty()) { + $notEOF = $this->moveToNextLine(); + } + + if (false === $notEOF) { + return false; + } + + $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem(); + + $this->moveToPreviousLine(); + + return $ret; + } + + /** + * Returns true if the string is un-indented collection item. + * + * @return bool Returns true if the string is un-indented collection item, false otherwise + */ + private function isStringUnIndentedCollectionItem() + { + return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- '); + } + + /** + * Tests whether or not the current line is the header of a block scalar. + * + * @return bool + */ + private function isBlockScalarHeader() + { + return (bool) self::preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine); + } + + /** + * A local wrapper for `preg_match` which will throw a ParseException if there + * is an internal error in the PCRE engine. + * + * This avoids us needing to check for "false" every time PCRE is used + * in the YAML engine + * + * @throws ParseException on a PCRE internal error + * + * @see preg_last_error() + * + * @internal + */ + public static function preg_match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0) + { + if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) { + switch (preg_last_error()) { + case PREG_INTERNAL_ERROR: + $error = 'Internal PCRE error.'; + break; + case PREG_BACKTRACK_LIMIT_ERROR: + $error = 'pcre.backtrack_limit reached.'; + break; + case PREG_RECURSION_LIMIT_ERROR: + $error = 'pcre.recursion_limit reached.'; + break; + case PREG_BAD_UTF8_ERROR: + $error = 'Malformed UTF-8 data.'; + break; + case PREG_BAD_UTF8_OFFSET_ERROR: + $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.'; + break; + default: + $error = 'Error.'; + } + + throw new ParseException($error); + } + + return $ret; + } +} diff --git a/vendor/symfony/yaml/README.md b/vendor/symfony/yaml/README.md new file mode 100644 index 0000000..0d32488 --- /dev/null +++ b/vendor/symfony/yaml/README.md @@ -0,0 +1,13 @@ +Yaml Component +============== + +The Yaml component loads and dumps YAML files. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/yaml/index.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/yaml/Tests/DumperTest.php b/vendor/symfony/yaml/Tests/DumperTest.php new file mode 100644 index 0000000..6bac6da --- /dev/null +++ b/vendor/symfony/yaml/Tests/DumperTest.php @@ -0,0 +1,257 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Dumper; +use Symfony\Component\Yaml\Parser; + +class DumperTest extends TestCase +{ + protected $parser; + protected $dumper; + protected $path; + + protected $array = array( + '' => 'bar', + 'foo' => '#bar', + 'foo\'bar' => array(), + 'bar' => array(1, 'foo'), + 'foobar' => array( + 'foo' => 'bar', + 'bar' => array(1, 'foo'), + 'foobar' => array( + 'foo' => 'bar', + 'bar' => array(1, 'foo'), + ), + ), + ); + + protected function setUp() + { + $this->parser = new Parser(); + $this->dumper = new Dumper(); + $this->path = __DIR__.'/Fixtures'; + } + + protected function tearDown() + { + $this->parser = null; + $this->dumper = null; + $this->path = null; + $this->array = null; + } + + public function testSetIndentation() + { + $this->dumper->setIndentation(7); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: + - 1 + - foo + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 4, 0)); + } + + public function testSpecifications() + { + $files = $this->parser->parse(file_get_contents($this->path.'/index.yml')); + foreach ($files as $file) { + $yamls = file_get_contents($this->path.'/'.$file.'.yml'); + + // split YAMLs documents + foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { + if (!$yaml) { + continue; + } + + $test = $this->parser->parse($yaml); + if (isset($test['dump_skip']) && $test['dump_skip']) { + continue; + } elseif (isset($test['todo']) && $test['todo']) { + // TODO + } else { + eval('$expected = '.trim($test['php']).';'); + $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']); + } + } + } + } + + public function testInlineLevel() + { + $expected = <<<'EOF' +{ '': bar, foo: '#bar', 'foo''bar': { }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } } +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument'); + $this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: [1, foo] +foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: [1, foo] + foobar: { foo: bar, bar: [1, foo] } + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: [1, foo] + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: + - 1 + - foo + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument'); + $this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument'); + } + + public function testObjectSupportEnabled() + { + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true); + + $this->assertEquals('{ foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1)); + + $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\DumpException + */ + public function testObjectSupportDisabledWithExceptions() + { + $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true, false); + } + + /** + * @dataProvider getEscapeSequences + */ + public function testEscapedEscapeSequencesInQuotedScalar($input, $expected) + { + $this->assertEquals($expected, $this->dumper->dump($input)); + } + + public function getEscapeSequences() + { + return array( + 'empty string' => array('', "''"), + 'null' => array("\x0", '"\\0"'), + 'bell' => array("\x7", '"\\a"'), + 'backspace' => array("\x8", '"\\b"'), + 'horizontal-tab' => array("\t", '"\\t"'), + 'line-feed' => array("\n", '"\\n"'), + 'vertical-tab' => array("\v", '"\\v"'), + 'form-feed' => array("\xC", '"\\f"'), + 'carriage-return' => array("\r", '"\\r"'), + 'escape' => array("\x1B", '"\\e"'), + 'space' => array(' ', "' '"), + 'double-quote' => array('"', "'\"'"), + 'slash' => array('/', '/'), + 'backslash' => array('\\', '\\'), + 'next-line' => array("\xC2\x85", '"\\N"'), + 'non-breaking-space' => array("\xc2\xa0", '"\\_"'), + 'line-separator' => array("\xE2\x80\xA8", '"\\L"'), + 'paragraph-separator' => array("\xE2\x80\xA9", '"\\P"'), + 'colon' => array(':', "':'"), + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testZeroIndentationThrowsException() + { + $this->dumper->setIndentation(0); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testNegativeIndentationThrowsException() + { + $this->dumper->setIndentation(-4); + } +} + +class A +{ + public $a = 'foo'; +} diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml new file mode 100644 index 0000000..5f9c942 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml @@ -0,0 +1,31 @@ +--- %YAML:1.0 +test: Simple Alias Example +brief: > + If you need to refer to the same item of data twice, + you can give that item an alias. The alias is a plain + string, starting with an ampersand. The item may then + be referred to by the alias throughout your document + by using an asterisk before the name of the alias. + This is called an anchor. +yaml: | + - &showell Steve + - Clark + - Brian + - Oren + - *showell +php: | + array('Steve', 'Clark', 'Brian', 'Oren', 'Steve') + +--- +test: Alias of a Mapping +brief: > + An alias can be used on any item of data, including + sequences, mappings, and other complex data types. +yaml: | + - &hello + Meat: pork + Starch: potato + - banana + - *hello +php: | + array(array('Meat'=>'pork', 'Starch'=>'potato'), 'banana', array('Meat'=>'pork', 'Starch'=>'potato')) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml new file mode 100644 index 0000000..dfd9302 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml @@ -0,0 +1,202 @@ +--- %YAML:1.0 +test: Simple Sequence +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - banana + - carrot +php: | + array('apple', 'banana', 'carrot') +--- +test: Sequence With Item Being Null In The Middle +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - + - carrot +php: | + array('apple', null, 'carrot') +--- +test: Sequence With Last Item Being Null +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - banana + - +php: | + array('apple', 'banana', null) +--- +test: Nested Sequences +brief: | + You can include a sequence within another + sequence by giving the sequence an empty + dash, followed by an indented list. +yaml: | + - + - foo + - bar + - baz +php: | + array(array('foo', 'bar', 'baz')) +--- +test: Mixed Sequences +brief: | + Sequences can contain any YAML data, + including strings and other sequences. +yaml: | + - apple + - + - foo + - bar + - x123 + - banana + - carrot +php: | + array('apple', array('foo', 'bar', 'x123'), 'banana', 'carrot') +--- +test: Deeply Nested Sequences +brief: | + Sequences can be nested even deeper, with each + level of indentation representing a level of + depth. +yaml: | + - + - + - uno + - dos +php: | + array(array(array('uno', 'dos'))) +--- +test: Simple Mapping +brief: | + You can add a keyed list (also known as a dictionary or + hash) to your document by placing each member of the + list on a new line, with a colon separating the key + from its value. In YAML, this type of list is called + a mapping. +yaml: | + foo: whatever + bar: stuff +php: | + array('foo' => 'whatever', 'bar' => 'stuff') +--- +test: Sequence in a Mapping +brief: | + A value in a mapping can be a sequence. +yaml: | + foo: whatever + bar: + - uno + - dos +php: | + array('foo' => 'whatever', 'bar' => array('uno', 'dos')) +--- +test: Nested Mappings +brief: | + A value in a mapping can be another mapping. +yaml: | + foo: whatever + bar: + fruit: apple + name: steve + sport: baseball +php: | + array( + 'foo' => 'whatever', + 'bar' => array( + 'fruit' => 'apple', + 'name' => 'steve', + 'sport' => 'baseball' + ) + ) +--- +test: Mixed Mapping +brief: | + A mapping can contain any assortment + of mappings and sequences as values. +yaml: | + foo: whatever + bar: + - + fruit: apple + name: steve + sport: baseball + - more + - + python: rocks + perl: papers + ruby: scissorses +php: | + array( + 'foo' => 'whatever', + 'bar' => array( + array( + 'fruit' => 'apple', + 'name' => 'steve', + 'sport' => 'baseball' + ), + 'more', + array( + 'python' => 'rocks', + 'perl' => 'papers', + 'ruby' => 'scissorses' + ) + ) + ) +--- +test: Mapping-in-Sequence Shortcut +todo: true +brief: | + If you are adding a mapping to a sequence, you + can place the mapping on the same line as the + dash as a shortcut. +yaml: | + - work on YAML.py: + - work on Store +php: | + array(array('work on YAML.py' => array('work on Store'))) +--- +test: Sequence-in-Mapping Shortcut +todo: true +brief: | + The dash in a sequence counts as indentation, so + you can add a sequence inside of a mapping without + needing spaces as indentation. +yaml: | + allow: + - 'localhost' + - '%.sourceforge.net' + - '%.freepan.org' +php: | + array('allow' => array('localhost', '%.sourceforge.net', '%.freepan.org')) +--- +todo: true +test: Merge key +brief: | + A merge key ('<<') can be used in a mapping to insert other mappings. If + the value associated with the merge key is a mapping, each of its key/value + pairs is inserted into the current mapping. +yaml: | + mapping: + name: Joe + job: Accountant + <<: + age: 38 +php: | + array( + 'mapping' => + array( + 'name' => 'Joe', + 'job' => 'Accountant', + 'age' => 38 + ) + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml new file mode 100644 index 0000000..f7ca469 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml @@ -0,0 +1,51 @@ +--- +test: One Element Mapping +brief: | + A mapping with one key/value pair +yaml: | + foo: bar +php: | + array('foo' => 'bar') +--- +test: Multi Element Mapping +brief: | + More than one key/value pair +yaml: | + red: baron + white: walls + blue: berries +php: | + array( + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ) +--- +test: Values aligned +brief: | + Often times human editors of documents will align the values even + though YAML emitters generally don't. +yaml: | + red: baron + white: walls + blue: berries +php: | + array( + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ) +--- +test: Colons aligned +brief: | + Spaces can come before the ': ' key/value separator. +yaml: | + red : baron + white : walls + blue : berries +php: | + array( + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml new file mode 100644 index 0000000..d988102 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml @@ -0,0 +1,85 @@ +--- %YAML:1.0 +test: Trailing Document Separator +todo: true +brief: > + You can separate YAML documents + with a string of three dashes. +yaml: | + - foo: 1 + bar: 2 + --- + more: stuff +python: | + [ + [ { 'foo': 1, 'bar': 2 } ], + { 'more': 'stuff' } + ] +ruby: | + [ { 'foo' => 1, 'bar' => 2 } ] + +--- +test: Leading Document Separator +todo: true +brief: > + You can explicitly give an opening + document separator to your YAML stream. +yaml: | + --- + - foo: 1 + bar: 2 + --- + more: stuff +python: | + [ + [ {'foo': 1, 'bar': 2}], + {'more': 'stuff'} + ] +ruby: | + [ { 'foo' => 1, 'bar' => 2 } ] + +--- +test: YAML Header +todo: true +brief: > + The opening separator can contain directives + to the YAML parser, such as the version + number. +yaml: | + --- %YAML:1.0 + foo: 1 + bar: 2 +php: | + array('foo' => 1, 'bar' => 2) +documents: 1 + +--- +test: Red Herring Document Separator +brief: > + Separators included in blocks or strings + are treated as blocks or strings, as the + document separator should have no indentation + preceding it. +yaml: | + foo: | + --- +php: | + array('foo' => "---\n") + +--- +test: Multiple Document Separators in Block +brief: > + This technique allows you to embed other YAML + documents within literal blocks. +yaml: | + foo: | + --- + foo: bar + --- + yo: baz + bar: | + fooness +php: | + array( + 'foo' => "---\nfoo: bar\n---\nyo: baz\n", + 'bar' => "fooness\n" + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml new file mode 100644 index 0000000..e8506fc --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml @@ -0,0 +1,25 @@ +--- +test: Missing value for hash item +todo: true +brief: | + Third item in this hash doesn't have a value +yaml: | + okay: value + also okay: ~ + causes error because no value specified + last key: value okay here too +python-error: causes error because no value specified + +--- +test: Not indenting enough +brief: | + There was a bug in PyYaml where it was off by one + in the indentation check. It was allowing the YAML + below. +# This is actually valid YAML now. Someone should tell showell. +yaml: | + foo: + firstline: 1 + secondline: 2 +php: | + array('foo' => null, 'firstline' => 1, 'secondline' => 2) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml new file mode 100644 index 0000000..03090e4 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml @@ -0,0 +1,60 @@ +--- +test: Simple Inline Array +brief: > + Sequences can be contained on a + single line, using the inline syntax. + Separate each entry with commas and + enclose in square brackets. +yaml: | + seq: [ a, b, c ] +php: | + array('seq' => array('a', 'b', 'c')) +--- +test: Simple Inline Hash +brief: > + Mapping can also be contained on + a single line, using the inline + syntax. Each key-value pair is + separated by a colon, with a comma + between each entry in the mapping. + Enclose with curly braces. +yaml: | + hash: { name: Steve, foo: bar } +php: | + array('hash' => array('name' => 'Steve', 'foo' => 'bar')) +--- +test: Multi-line Inline Collections +todo: true +brief: > + Both inline sequences and inline mappings + can span multiple lines, provided that you + indent the additional lines. +yaml: | + languages: [ Ruby, + Perl, + Python ] + websites: { YAML: yaml.org, + Ruby: ruby-lang.org, + Python: python.org, + Perl: use.perl.org } +php: | + array( + 'languages' => array('Ruby', 'Perl', 'Python'), + 'websites' => array( + 'YAML' => 'yaml.org', + 'Ruby' => 'ruby-lang.org', + 'Python' => 'python.org', + 'Perl' => 'use.perl.org' + ) + ) +--- +test: Commas in Values (not in the spec!) +todo: true +brief: > + List items in collections are delimited by commas, but + there must be a space after each comma. This allows you + to add numbers without quoting. +yaml: | + attendances: [ 45,123, 70,000, 17,222 ] +php: | + array('attendances' => array(45123, 70000, 17222)) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml new file mode 100644 index 0000000..a14735a --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml @@ -0,0 +1,176 @@ +--- %YAML:1.0 +test: Single ending newline +brief: > + A pipe character, followed by an indented + block of text is treated as a literal + block, in which newlines are preserved + throughout the block, including the final + newline. +yaml: | + --- + this: | + Foo + Bar +php: | + array('this' => "Foo\nBar\n") +--- +test: The '+' indicator +brief: > + The '+' indicator says to keep newlines at the end of text + blocks. +yaml: | + normal: | + extra new lines not kept + + preserving: |+ + extra new lines are kept + + + dummy: value +php: | + array( + 'normal' => "extra new lines not kept\n", + 'preserving' => "extra new lines are kept\n\n\n", + 'dummy' => 'value' + ) +--- +test: Three trailing newlines in literals +brief: > + To give you more control over how space + is preserved in text blocks, YAML has + the keep '+' and chomp '-' indicators. + The keep indicator will preserve all + ending newlines, while the chomp indicator + will strip all ending newlines. +yaml: | + clipped: | + This has one newline. + + + + same as "clipped" above: "This has one newline.\n" + + stripped: |- + This has no newline. + + + + same as "stripped" above: "This has no newline." + + kept: |+ + This has four newlines. + + + + same as "kept" above: "This has four newlines.\n\n\n\n" +php: | + array( + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has four newlines.\n\n\n\n", + 'same as "kept" above' => "This has four newlines.\n\n\n\n" + ) +--- +test: Extra trailing newlines with spaces +todo: true +brief: > + Normally, only a single newline is kept + from the end of a literal block, unless the + keep '+' character is used in combination + with the pipe. The following example + will preserve all ending whitespace + since the last line of both literal blocks + contains spaces which extend past the indentation + level. +yaml: | + --- + this: | + Foo + + + kept: |+ + Foo + + +php: | + array('this' => "Foo\n\n \n", + 'kept' => "Foo\n\n \n" ) + +--- +test: Folded Block in a Sequence +brief: > + A greater-then character, followed by an indented + block of text is treated as a folded block, in + which lines of text separated by a single newline + are concatenated as a single line. +yaml: | + --- + - apple + - banana + - > + can't you see + the beauty of yaml? + hmm + - dog +php: | + array( + 'apple', + 'banana', + "can't you see the beauty of yaml? hmm\n", + 'dog' + ) +--- +test: Folded Block as a Mapping Value +brief: > + Both literal and folded blocks can be + used in collections, as values in a + sequence or a mapping. +yaml: | + --- + quote: > + Mark McGwire's + year was crippled + by a knee injury. + source: espn +php: | + array( + 'quote' => "Mark McGwire's year was crippled by a knee injury.\n", + 'source' => 'espn' + ) +--- +test: Three trailing newlines in folded blocks +brief: > + The keep and chomp indicators can also + be applied to folded blocks. +yaml: | + clipped: > + This has one newline. + + + + same as "clipped" above: "This has one newline.\n" + + stripped: >- + This has no newline. + + + + same as "stripped" above: "This has no newline." + + kept: >+ + This has four newlines. + + + + same as "kept" above: "This has four newlines.\n\n\n\n" +php: | + array( + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has four newlines.\n\n\n\n", + 'same as "kept" above' => "This has four newlines.\n\n\n\n" + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml new file mode 100644 index 0000000..9a5300f --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml @@ -0,0 +1,45 @@ +--- %YAML:1.0 +test: Empty Sequence +brief: > + You can represent the empty sequence + with an empty inline sequence. +yaml: | + empty: [] +php: | + array('empty' => array()) +--- +test: Empty Mapping +brief: > + You can represent the empty mapping + with an empty inline mapping. +yaml: | + empty: {} +php: | + array('empty' => array()) +--- +test: Empty Sequence as Entire Document +yaml: | + [] +php: | + array() +--- +test: Empty Mapping as Entire Document +yaml: | + {} +php: | + array() +--- +test: Null as Document +yaml: | + ~ +php: | + null +--- +test: Empty String +brief: > + You can represent an empty string + with a pair of quotes. +yaml: | + '' +php: | + '' diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml new file mode 100644 index 0000000..ec1c4c3 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml @@ -0,0 +1,1697 @@ +--- %YAML:1.0 +test: Sequence of scalars +spec: 2.1 +yaml: | + - Mark McGwire + - Sammy Sosa + - Ken Griffey +php: | + array('Mark McGwire', 'Sammy Sosa', 'Ken Griffey') +--- +test: Mapping of scalars to scalars +spec: 2.2 +yaml: | + hr: 65 + avg: 0.278 + rbi: 147 +php: | + array('hr' => 65, 'avg' => 0.278, 'rbi' => 147) +--- +test: Mapping of scalars to sequences +spec: 2.3 +yaml: | + american: + - Boston Red Sox + - Detroit Tigers + - New York Yankees + national: + - New York Mets + - Chicago Cubs + - Atlanta Braves +php: | + array('american' => + array( 'Boston Red Sox', 'Detroit Tigers', + 'New York Yankees' ), + 'national' => + array( 'New York Mets', 'Chicago Cubs', + 'Atlanta Braves' ) + ) +--- +test: Sequence of mappings +spec: 2.4 +yaml: | + - + name: Mark McGwire + hr: 65 + avg: 0.278 + - + name: Sammy Sosa + hr: 63 + avg: 0.288 +php: | + array( + array('name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278), + array('name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288) + ) +--- +test: Legacy A5 +todo: true +spec: legacy_A5 +yaml: | + ? + - New York Yankees + - Atlanta Braves + : + - 2001-07-02 + - 2001-08-12 + - 2001-08-14 + ? + - Detroit Tigers + - Chicago Cubs + : + - 2001-07-23 +perl-busted: > + YAML.pm will be able to emulate this behavior soon. In this regard + it may be somewhat more correct than Python's native behaviour which + can only use tuples as mapping keys. PyYAML will also need to figure + out some clever way to roundtrip structured keys. +python: | + [ + { + ('New York Yankees', 'Atlanta Braves'): + [yaml.timestamp('2001-07-02'), + yaml.timestamp('2001-08-12'), + yaml.timestamp('2001-08-14')], + ('Detroit Tigers', 'Chicago Cubs'): + [yaml.timestamp('2001-07-23')] + } + ] +ruby: | + { + [ 'New York Yankees', 'Atlanta Braves' ] => + [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ], + [ 'Detroit Tigers', 'Chicago Cubs' ] => + [ Date.new( 2001, 7, 23 ) ] + } +syck: | + struct test_node seq1[] = { + { T_STR, 0, "New York Yankees" }, + { T_STR, 0, "Atlanta Braves" }, + end_node + }; + struct test_node seq2[] = { + { T_STR, 0, "2001-07-02" }, + { T_STR, 0, "2001-08-12" }, + { T_STR, 0, "2001-08-14" }, + end_node + }; + struct test_node seq3[] = { + { T_STR, 0, "Detroit Tigers" }, + { T_STR, 0, "Chicago Cubs" }, + end_node + }; + struct test_node seq4[] = { + { T_STR, 0, "2001-07-23" }, + end_node + }; + struct test_node map[] = { + { T_SEQ, 0, 0, seq1 }, + { T_SEQ, 0, 0, seq2 }, + { T_SEQ, 0, 0, seq3 }, + { T_SEQ, 0, 0, seq4 }, + end_node + }; + struct test_node stream[] = { + { T_MAP, 0, 0, map }, + end_node + }; + +--- +test: Sequence of sequences +spec: 2.5 +yaml: | + - [ name , hr , avg ] + - [ Mark McGwire , 65 , 0.278 ] + - [ Sammy Sosa , 63 , 0.288 ] +php: | + array( + array( 'name', 'hr', 'avg' ), + array( 'Mark McGwire', 65, 0.278 ), + array( 'Sammy Sosa', 63, 0.288 ) + ) +--- +test: Mapping of mappings +todo: true +spec: 2.6 +yaml: | + Mark McGwire: {hr: 65, avg: 0.278} + Sammy Sosa: { + hr: 63, + avg: 0.288 + } +php: | + array( + 'Mark McGwire' => + array( 'hr' => 65, 'avg' => 0.278 ), + 'Sammy Sosa' => + array( 'hr' => 63, 'avg' => 0.288 ) + ) +--- +test: Two documents in a stream each with a leading comment +todo: true +spec: 2.7 +yaml: | + # Ranking of 1998 home runs + --- + - Mark McGwire + - Sammy Sosa + - Ken Griffey + + # Team ranking + --- + - Chicago Cubs + - St Louis Cardinals +ruby: | + y = YAML::Stream.new + y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] ) + y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] ) +documents: 2 + +--- +test: Play by play feed from a game +todo: true +spec: 2.8 +yaml: | + --- + time: 20:03:20 + player: Sammy Sosa + action: strike (miss) + ... + --- + time: 20:03:47 + player: Sammy Sosa + action: grand slam + ... +perl: | + [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] +documents: 2 + +--- +test: Single document with two comments +spec: 2.9 +yaml: | + hr: # 1998 hr ranking + - Mark McGwire + - Sammy Sosa + rbi: + # 1998 rbi ranking + - Sammy Sosa + - Ken Griffey +php: | + array( + 'hr' => array( 'Mark McGwire', 'Sammy Sosa' ), + 'rbi' => array( 'Sammy Sosa', 'Ken Griffey' ) + ) +--- +test: Node for Sammy Sosa appears twice in this document +spec: 2.10 +yaml: | + --- + hr: + - Mark McGwire + # Following node labeled SS + - &SS Sammy Sosa + rbi: + - *SS # Subsequent occurrence + - Ken Griffey +php: | + array( + 'hr' => + array('Mark McGwire', 'Sammy Sosa'), + 'rbi' => + array('Sammy Sosa', 'Ken Griffey') + ) +--- +test: Mapping between sequences +todo: true +spec: 2.11 +yaml: | + ? # PLAY SCHEDULE + - Detroit Tigers + - Chicago Cubs + : + - 2001-07-23 + + ? [ New York Yankees, + Atlanta Braves ] + : [ 2001-07-02, 2001-08-12, + 2001-08-14 ] +ruby: | + { + [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ], + [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] + } +syck: | + struct test_node seq1[] = { + { T_STR, 0, "New York Yankees" }, + { T_STR, 0, "Atlanta Braves" }, + end_node + }; + struct test_node seq2[] = { + { T_STR, 0, "2001-07-02" }, + { T_STR, 0, "2001-08-12" }, + { T_STR, 0, "2001-08-14" }, + end_node + }; + struct test_node seq3[] = { + { T_STR, 0, "Detroit Tigers" }, + { T_STR, 0, "Chicago Cubs" }, + end_node + }; + struct test_node seq4[] = { + { T_STR, 0, "2001-07-23" }, + end_node + }; + struct test_node map[] = { + { T_SEQ, 0, 0, seq3 }, + { T_SEQ, 0, 0, seq4 }, + { T_SEQ, 0, 0, seq1 }, + { T_SEQ, 0, 0, seq2 }, + end_node + }; + struct test_node stream[] = { + { T_MAP, 0, 0, map }, + end_node + }; + +--- +test: Sequence key shortcut +spec: 2.12 +yaml: | + --- + # products purchased + - item : Super Hoop + quantity: 1 + - item : Basketball + quantity: 4 + - item : Big Shoes + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'item' => 'Basketball', + 'quantity' => 4, + ), + array ( + 'item' => 'Big Shoes', + 'quantity' => 1, + ) + ) +perl: | + [ + { item => 'Super Hoop', quantity => 1 }, + { item => 'Basketball', quantity => 4 }, + { item => 'Big Shoes', quantity => 1 } + ] + +ruby: | + [ + { 'item' => 'Super Hoop', 'quantity' => 1 }, + { 'item' => 'Basketball', 'quantity' => 4 }, + { 'item' => 'Big Shoes', 'quantity' => 1 } + ] +python: | + [ + { 'item': 'Super Hoop', 'quantity': 1 }, + { 'item': 'Basketball', 'quantity': 4 }, + { 'item': 'Big Shoes', 'quantity': 1 } + ] +syck: | + struct test_node map1[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Super Hoop" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "1" }, + end_node + }; + struct test_node map2[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Basketball" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "4" }, + end_node + }; + struct test_node map3[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Big Shoes" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "1" }, + end_node + }; + struct test_node seq[] = { + { T_MAP, 0, 0, map1 }, + { T_MAP, 0, 0, map2 }, + { T_MAP, 0, 0, map3 }, + end_node + }; + struct test_node stream[] = { + { T_SEQ, 0, 0, seq }, + end_node + }; + + +--- +test: Literal perserves newlines +todo: true +spec: 2.13 +yaml: | + # ASCII Art + --- | + \//||\/|| + // || ||_ +perl: | + "\\//||\\/||\n// || ||_\n" +ruby: | + "\\//||\\/||\n// || ||_\n" +python: | + [ + flushLeft( + """ + \//||\/|| + // || ||_ + """ + ) + ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "\\//||\\/||\n// || ||_\n" }, + end_node + }; + +--- +test: Folded treats newlines as a space +todo: true +spec: 2.14 +yaml: | + --- + Mark McGwire's + year was crippled + by a knee injury. +perl: | + "Mark McGwire's year was crippled by a knee injury." +ruby: | + "Mark McGwire's year was crippled by a knee injury." +python: | + [ "Mark McGwire's year was crippled by a knee injury." ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." }, + end_node + }; + +--- +test: Newlines preserved for indented and blank lines +todo: true +spec: 2.15 +yaml: | + --- > + Sammy Sosa completed another + fine season with great stats. + + 63 Home Runs + 0.288 Batting Average + + What a year! +perl: | + "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" +ruby: | + "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" +python: | + [ + flushLeft( + """ + Sammy Sosa completed another fine season with great stats. + + 63 Home Runs + 0.288 Batting Average + + What a year! + """ + ) + ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" }, + end_node + }; + + +--- +test: Indentation determines scope +spec: 2.16 +yaml: | + name: Mark McGwire + accomplishment: > + Mark set a major league + home run record in 1998. + stats: | + 65 Home Runs + 0.278 Batting Average +php: | + array( + 'name' => 'Mark McGwire', + 'accomplishment' => "Mark set a major league home run record in 1998.\n", + 'stats' => "65 Home Runs\n0.278 Batting Average\n" + ) +--- +test: Quoted scalars +todo: true +spec: 2.17 +yaml: | + unicode: "Sosa did fine.\u263A" + control: "\b1998\t1999\t2000\n" + hexesc: "\x0D\x0A is \r\n" + + single: '"Howdy!" he cried.' + quoted: ' # not a ''comment''.' + tie-fighter: '|\-*-/|' +ruby: | + { + "tie-fighter" => "|\\-*-/|", + "control"=>"\0101998\t1999\t2000\n", + "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'), + "quoted"=>" # not a 'comment'.", + "single"=>"\"Howdy!\" he cried.", + "hexesc"=>"\r\n is \r\n" + } +--- +test: Multiline flow scalars +todo: true +spec: 2.18 +yaml: | + plain: + This unquoted scalar + spans many lines. + + quoted: "So does this + quoted scalar.\n" +ruby: | + { + 'plain' => 'This unquoted scalar spans many lines.', + 'quoted' => "So does this quoted scalar.\n" + } +--- +test: Integers +spec: 2.19 +yaml: | + canonical: 12345 + decimal: +12,345 + octal: 014 + hexadecimal: 0xC +php: | + array( + 'canonical' => 12345, + 'decimal' => 12345.0, + 'octal' => 014, + 'hexadecimal' => 0xC + ) +--- +# FIX: spec shows parens around -inf and NaN +test: Floating point +spec: 2.20 +yaml: | + canonical: 1.23015e+3 + exponential: 12.3015e+02 + fixed: 1,230.15 + negative infinity: -.inf + not a number: .NaN + float as whole number: !!float 1 +php: | + array( + 'canonical' => 1230.15, + 'exponential' => 1230.15, + 'fixed' => 1230.15, + 'negative infinity' => log(0), + 'not a number' => -log(0), + 'float as whole number' => (float) 1 + ) +--- +test: Miscellaneous +spec: 2.21 +yaml: | + null: ~ + true: true + false: false + string: '12345' +php: | + array( + '' => null, + 1 => true, + 0 => false, + 'string' => '12345' + ) +--- +test: Timestamps +todo: true +spec: 2.22 +yaml: | + canonical: 2001-12-15T02:59:43.1Z + iso8601: 2001-12-14t21:59:43.10-05:00 + spaced: 2001-12-14 21:59:43.10 -05:00 + date: 2002-12-14 # Time is noon UTC +php: | + array( + 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), + 'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'date' => Date.new( 2002, 12, 14 ) + ) +--- +test: legacy Timestamps test +todo: true +spec: legacy D4 +yaml: | + canonical: 2001-12-15T02:59:43.00Z + iso8601: 2001-02-28t21:59:43.00-05:00 + spaced: 2001-12-14 21:59:43.00 -05:00 + date: 2002-12-14 +php: | + array( + 'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ), + 'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ), + 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ), + 'date' => Date.new( 2002, 12, 14 ) + ) +--- +test: Various explicit families +todo: true +spec: 2.23 +yaml: | + not-date: !str 2002-04-28 + picture: !binary | + R0lGODlhDAAMAIQAAP//9/X + 17unp5WZmZgAAAOfn515eXv + Pz7Y6OjuDg4J+fn5OTk6enp + 56enmleECcgggoBADs= + + application specific tag: !!something | + The semantics of the tag + above may be different for + different documents. + +ruby-setup: | + YAML.add_private_type( "something" ) do |type, val| + "SOMETHING: #{val}" + end +ruby: | + { + 'not-date' => '2002-04-28', + 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", + 'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n" + } +--- +test: Application specific family +todo: true +spec: 2.24 +yaml: | + # Establish a tag prefix + --- !clarkevans.com,2002/graph/^shape + # Use the prefix: shorthand for + # !clarkevans.com,2002/graph/circle + - !^circle + center: &ORIGIN {x: 73, 'y': 129} + radius: 7 + - !^line # !clarkevans.com,2002/graph/line + start: *ORIGIN + finish: { x: 89, 'y': 102 } + - !^label + start: *ORIGIN + color: 0xFFEEBB + value: Pretty vector drawing. +ruby-setup: | + YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val| + if Array === val + val << "Shape Container" + val + else + raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect + end + } + one_shape_proc = Proc.new { |type, val| + scheme, domain, type = type.split( /:/, 3 ) + if val.is_a? ::Hash + val['TYPE'] = "Shape: #{type}" + val + else + raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect + end + } + YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc ) + YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc ) + YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc ) +ruby: | + [ + { + "radius" => 7, + "center"=> + { + "x" => 73, + "y" => 129 + }, + "TYPE" => "Shape: graph/circle" + }, { + "finish" => + { + "x" => 89, + "y" => 102 + }, + "TYPE" => "Shape: graph/line", + "start" => + { + "x" => 73, + "y" => 129 + } + }, { + "TYPE" => "Shape: graph/label", + "value" => "Pretty vector drawing.", + "start" => + { + "x" => 73, + "y" => 129 + }, + "color" => 16772795 + }, + "Shape Container" + ] +# --- +# test: Unordered set +# spec: 2.25 +# yaml: | +# # sets are represented as a +# # mapping where each key is +# # associated with the empty string +# --- !set +# ? Mark McGwire +# ? Sammy Sosa +# ? Ken Griff +--- +test: Ordered mappings +todo: true +spec: 2.26 +yaml: | + # ordered maps are represented as + # a sequence of mappings, with + # each mapping having one key + --- !omap + - Mark McGwire: 65 + - Sammy Sosa: 63 + - Ken Griffy: 58 +ruby: | + YAML::Omap[ + 'Mark McGwire', 65, + 'Sammy Sosa', 63, + 'Ken Griffy', 58 + ] +--- +test: Invoice +dump_skip: true +spec: 2.27 +yaml: | + --- !clarkevans.com,2002/^invoice + invoice: 34843 + date : 2001-01-23 + bill-to: &id001 + given : Chris + family : Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 + city : Royal Oak + state : MI + postal : 48046 + ship-to: *id001 + product: + - + sku : BL394D + quantity : 4 + description : Basketball + price : 450.00 + - + sku : BL4438H + quantity : 1 + description : Super Hoop + price : 2392.00 + tax : 251.42 + total: 4443.52 + comments: > + Late afternoon is best. + Backup contact is Nancy + Billsmer @ 338-4338. +php: | + array( + 'invoice' => 34843, 'date' => gmmktime(0, 0, 0, 1, 23, 2001), + 'bill-to' => + array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) ) + , 'ship-to' => + array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) ) + , 'product' => + array( + array( 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ), + array( 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 ) + ), + 'tax' => 251.42, 'total' => 4443.52, + 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" + ) +--- +test: Log file +todo: true +spec: 2.28 +yaml: | + --- + Time: 2001-11-23 15:01:42 -05:00 + User: ed + Warning: > + This is an error message + for the log file + --- + Time: 2001-11-23 15:02:31 -05:00 + User: ed + Warning: > + A slightly different error + message. + --- + Date: 2001-11-23 15:03:17 -05:00 + User: ed + Fatal: > + Unknown variable "bar" + Stack: + - file: TopClass.py + line: 23 + code: | + x = MoreObject("345\n") + - file: MoreClass.py + line: 58 + code: |- + foo = bar +ruby: | + y = YAML::Stream.new + y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } ) + y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } ) + y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ), + 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n", + 'Stack' => [ + { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" }, + { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } ) +documents: 3 + +--- +test: Throwaway comments +yaml: | + ### These are four throwaway comment ### + + ### lines (the second line is empty). ### + this: | # Comments may trail lines. + contains three lines of text. + The third one starts with a + # character. This isn't a comment. + + # These are three throwaway comment + # lines (the first line is empty). +php: | + array( + 'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n" + ) +--- +test: Document with a single value +todo: true +yaml: | + --- > + This YAML stream contains a single text value. + The next stream is a log file - a sequence of + log entries. Adding an entry to the log is a + simple matter of appending it at the end. +ruby: | + "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" +--- +test: Document stream +todo: true +yaml: | + --- + at: 2001-08-12 09:25:00.00 Z + type: GET + HTTP: '1.0' + url: '/index.html' + --- + at: 2001-08-12 09:25:10.00 Z + type: GET + HTTP: '1.0' + url: '/toc.html' +ruby: | + y = YAML::Stream.new + y.add( { + 'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ), + 'type' => 'GET', + 'HTTP' => '1.0', + 'url' => '/index.html' + } ) + y.add( { + 'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ), + 'type' => 'GET', + 'HTTP' => '1.0', + 'url' => '/toc.html' + } ) +documents: 2 + +--- +test: Top level mapping +yaml: | + # This stream is an example of a top-level mapping. + invoice : 34843 + date : 2001-01-23 + total : 4443.52 +php: | + array( + 'invoice' => 34843, + 'date' => gmmktime(0, 0, 0, 1, 23, 2001), + 'total' => 4443.52 + ) +--- +test: Single-line documents +todo: true +yaml: | + # The following is a sequence of three documents. + # The first contains an empty mapping, the second + # an empty sequence, and the last an empty string. + --- {} + --- [ ] + --- '' +ruby: | + y = YAML::Stream.new + y.add( {} ) + y.add( [] ) + y.add( '' ) +documents: 3 + +--- +test: Document with pause +todo: true +yaml: | + # A communication channel based on a YAML stream. + --- + sent at: 2002-06-06 11:46:25.10 Z + payload: Whatever + # Receiver can process this as soon as the following is sent: + ... + # Even if the next message is sent long after: + --- + sent at: 2002-06-06 12:05:53.47 Z + payload: Whatever + ... +ruby: | + y = YAML::Stream.new + y.add( + { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ), + 'payload' => 'Whatever' } + ) + y.add( + { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) } + ) +documents: 2 + +--- +test: Explicit typing +yaml: | + integer: 12 + also int: ! "12" + string: !str 12 +php: | + array( 'integer' => 12, 'also int' => 12, 'string' => '12' ) +--- +test: Private types +todo: true +yaml: | + # Both examples below make use of the 'x-private:ball' + # type family URI, but with different semantics. + --- + pool: !!ball + number: 8 + color: black + --- + bearing: !!ball + material: steel +ruby: | + y = YAML::Stream.new + y.add( { 'pool' => + YAML::PrivateType.new( 'ball', + { 'number' => 8, 'color' => 'black' } ) } + ) + y.add( { 'bearing' => + YAML::PrivateType.new( 'ball', + { 'material' => 'steel' } ) } + ) +documents: 2 + +--- +test: Type family under yaml.org +yaml: | + # The URI is 'tag:yaml.org,2002:str' + - !str a Unicode string +php: | + array( 'a Unicode string' ) +--- +test: Type family under perl.yaml.org +todo: true +yaml: | + # The URI is 'tag:perl.yaml.org,2002:Text::Tabs' + - !perl/Text::Tabs {} +ruby: | + [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ] +--- +test: Type family under clarkevans.com +todo: true +yaml: | + # The URI is 'tag:clarkevans.com,2003-02:timesheet' + - !clarkevans.com,2003-02/timesheet {} +ruby: | + [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ] +--- +test: URI Escaping +todo: true +yaml: | + same: + - !domain.tld,2002/type\x30 value + - !domain.tld,2002/type0 value + different: # As far as the YAML parser is concerned + - !domain.tld,2002/type%30 value + - !domain.tld,2002/type0 value +ruby-setup: | + YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val| + "ONE: #{val}" + } + YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val| + "TWO: #{val}" + } +ruby: | + { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] } +--- +test: URI Prefixing +todo: true +yaml: | + # 'tag:domain.tld,2002:invoice' is some type family. + invoice: !domain.tld,2002/^invoice + # 'seq' is shorthand for 'tag:yaml.org,2002:seq'. + # This does not effect '^customer' below + # because it is does not specify a prefix. + customers: !seq + # '^customer' is shorthand for the full + # notation 'tag:domain.tld,2002:customer'. + - !^customer + given : Chris + family : Dumars +ruby-setup: | + YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val| + if val.is_a? ::Hash + scheme, domain, type = type.split( /:/, 3 ) + val['type'] = "domain #{type}" + val + else + raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect + end + } +ruby: | + { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } } + +--- +test: Overriding anchors +yaml: | + anchor : &A001 This scalar has an anchor. + override : &A001 > + The alias node below is a + repeated use of this value. + alias : *A001 +php: | + array( 'anchor' => 'This scalar has an anchor.', + 'override' => "The alias node below is a repeated use of this value.\n", + 'alias' => "The alias node below is a repeated use of this value.\n" ) +--- +test: Flow and block formatting +todo: true +yaml: | + empty: [] + flow: [ one, two, three # May span lines, + , four, # indentation is + five ] # mostly ignored. + block: + - First item in top sequence + - + - Subordinate sequence entry + - > + A folded sequence entry + - Sixth item in top sequence +ruby: | + { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ], + 'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ], + "A folded sequence entry\n", 'Sixth item in top sequence' ] } +--- +test: Complete mapping test +todo: true +yaml: | + empty: {} + flow: { one: 1, two: 2 } + spanning: { one: 1, + two: 2 } + block: + first : First entry + second: + key: Subordinate mapping + third: + - Subordinate sequence + - { } + - Previous mapping is empty. + - A key: value pair in a sequence. + A second: key:value pair. + - The previous entry is equal to the following one. + - + A key: value pair in a sequence. + A second: key:value pair. + !float 12 : This key is a float. + ? > + ? + : This key had to be protected. + "\a" : This key had to be escaped. + ? > + This is a + multi-line + folded key + : Whose value is + also multi-line. + ? this also works as a key + : with a value at the next line. + ? + - This key + - is a sequence + : + - With a sequence value. + ? + This: key + is a: mapping + : + with a: mapping value. +ruby: | + { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 }, + 'spanning' => { 'one' => 1, 'two' => 2 }, + 'block' => { 'first' => 'First entry', 'second' => + { 'key' => 'Subordinate mapping' }, 'third' => + [ 'Subordinate sequence', {}, 'Previous mapping is empty.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' }, + 'The previous entry is equal to the following one.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ], + 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.', + "\a" => 'This key had to be escaped.', + "This is a multi-line folded key\n" => "Whose value is also multi-line.", + 'this also works as a key' => 'with a value at the next line.', + [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } } + # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact + obj_y['block'].keys.each { |k| + if Hash === k + v = obj_y['block'][k] + if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.' + obj_r['block'][k] = v + end + end + } +--- +test: Literal explicit indentation +yaml: | + # Explicit indentation must + # be given in all the three + # following cases. + leading spaces: |2 + This value starts with four spaces. + + leading line break: |2 + + This value starts with a line break. + + leading comment indicator: |2 + # first line starts with a + # character. + + # Explicit indentation may + # also be given when it is + # not required. + redundant: |2 + This value is indented 2 spaces. +php: | + array( + 'leading spaces' => " This value starts with four spaces.\n", + 'leading line break' => "\nThis value starts with a line break.\n", + 'leading comment indicator' => "# first line starts with a\n# character.\n", + 'redundant' => "This value is indented 2 spaces.\n" + ) +--- +test: Chomping and keep modifiers +yaml: | + clipped: | + This has one newline. + + same as "clipped" above: "This has one newline.\n" + + stripped: |- + This has no newline. + + same as "stripped" above: "This has no newline." + + kept: |+ + This has two newlines. + + same as "kept" above: "This has two newlines.\n\n" +php: | + array( + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has two newlines.\n\n", + 'same as "kept" above' => "This has two newlines.\n\n" + ) +--- +test: Literal combinations +todo: true +yaml: | + empty: | + + literal: | + The \ ' " characters may be + freely used. Leading white + space is significant. + + Line breaks are significant. + Thus this value contains one + empty line and ends with a + single line break, but does + not start with one. + + is equal to: "The \\ ' \" characters may \ + be\nfreely used. Leading white\n space \ + is significant.\n\nLine breaks are \ + significant.\nThus this value contains \ + one\nempty line and ends with a\nsingle \ + line break, but does\nnot start with one.\n" + + # Comments may follow a block + # scalar value. They must be + # less indented. + + # Modifiers may be combined in any order. + indented and chomped: |2- + This has no newline. + + also written as: |-2 + This has no newline. + + both are equal to: " This has no newline." +php: | + array( + 'empty' => '', + 'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", + 'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", + 'indented and chomped' => ' This has no newline.', + 'also written as' => ' This has no newline.', + 'both are equal to' => ' This has no newline.' + ) +--- +test: Folded combinations +todo: true +yaml: | + empty: > + + one paragraph: > + Line feeds are converted + to spaces, so this value + contains no line breaks + except for the final one. + + multiple paragraphs: >2 + + An empty line, either + at the start or in + the value: + + Is interpreted as a + line break. Thus this + value contains three + line breaks. + + indented text: > + This is a folded + paragraph followed + by a list: + * first entry + * second entry + Followed by another + folded paragraph, + another list: + + * first entry + + * second entry + + And a final folded + paragraph. + + above is equal to: | + This is a folded paragraph followed by a list: + * first entry + * second entry + Followed by another folded paragraph, another list: + + * first entry + + * second entry + + And a final folded paragraph. + + # Explicit comments may follow + # but must be less indented. +php: | + array( + 'empty' => '', + 'one paragraph' => 'Line feeds are converted to spaces, so this value'. + " contains no line breaks except for the final one.\n", + 'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n". + "Is interpreted as a line break. Thus this value contains three line breaks.\n", + 'indented text' => "This is a folded paragraph followed by a list:\n". + " * first entry\n * second entry\nFollowed by another folded paragraph, ". + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n", + 'above is equal to' => "This is a folded paragraph followed by a list:\n". + " * first entry\n * second entry\nFollowed by another folded paragraph, ". + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n" + ) +--- +test: Single quotes +todo: true +yaml: | + empty: '' + second: '! : \ etc. can be used freely.' + third: 'a single quote '' must be escaped.' + span: 'this contains + six spaces + + and one + line break' + is same as: "this contains six spaces\nand one line break" +php: | + array( + 'empty' => '', + 'second' => '! : \\ etc. can be used freely.', + 'third' => "a single quote ' must be escaped.", + 'span' => "this contains six spaces\nand one line break", + 'is same as' => "this contains six spaces\nand one line break" + ) +--- +test: Double quotes +todo: true +yaml: | + empty: "" + second: "! : etc. can be used freely." + third: "a \" or a \\ must be escaped." + fourth: "this value ends with an LF.\n" + span: "this contains + four \ + spaces" + is equal to: "this contains four spaces" +php: | + array( + 'empty' => '', + 'second' => '! : etc. can be used freely.', + 'third' => 'a " or a \\ must be escaped.', + 'fourth' => "this value ends with an LF.\n", + 'span' => "this contains four spaces", + 'is equal to' => "this contains four spaces" + ) +--- +test: Unquoted strings +todo: true +yaml: | + first: There is no unquoted empty string. + + second: 12 ## This is an integer. + + third: !str 12 ## This is a string. + + span: this contains + six spaces + + and one + line break + + indicators: this has no comments. + #:foo and bar# are + both text. + + flow: [ can span + lines, # comment + like + this ] + + note: { one-line keys: but multi-line values } + +php: | + array( + 'first' => 'There is no unquoted empty string.', + 'second' => 12, + 'third' => '12', + 'span' => "this contains six spaces\nand one line break", + 'indicators' => "this has no comments. #:foo and bar# are both text.", + 'flow' => [ 'can span lines', 'like this' ], + 'note' => { 'one-line keys' => 'but multi-line values' } + ) +--- +test: Spanning sequences +todo: true +yaml: | + # The following are equal seqs + # with different identities. + flow: [ one, two ] + spanning: [ one, + two ] + block: + - one + - two +php: | + array( + 'flow' => [ 'one', 'two' ], + 'spanning' => [ 'one', 'two' ], + 'block' => [ 'one', 'two' ] + ) +--- +test: Flow mappings +yaml: | + # The following are equal maps + # with different identities. + flow: { one: 1, two: 2 } + block: + one: 1 + two: 2 +php: | + array( + 'flow' => array( 'one' => 1, 'two' => 2 ), + 'block' => array( 'one' => 1, 'two' => 2 ) + ) +--- +test: Representations of 12 +todo: true +yaml: | + - 12 # An integer + # The following scalars + # are loaded to the + # string value '1' '2'. + - !str 12 + - '12' + - "12" + - "\ + 1\ + 2\ + " + # Strings containing paths and regexps can be unquoted: + - /foo/bar + - d:/foo/bar + - foo/bar + - /a.*b/ +php: | + array( 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' ) +--- +test: "Null" +todo: true +yaml: | + canonical: ~ + + english: null + + # This sequence has five + # entries, two with values. + sparse: + - ~ + - 2nd entry + - Null + - 4th entry + - + + four: This mapping has five keys, + only two with values. + +php: | + array ( + 'canonical' => null, + 'english' => null, + 'sparse' => array( null, '2nd entry', null, '4th entry', null ]), + 'four' => 'This mapping has five keys, only two with values.' + ) +--- +test: Omap +todo: true +yaml: | + # Explicitly typed dictionary. + Bestiary: !omap + - aardvark: African pig-like ant eater. Ugly. + - anteater: South-American ant eater. Two species. + - anaconda: South-American constrictor snake. Scary. + # Etc. +ruby: | + { + 'Bestiary' => YAML::Omap[ + 'aardvark', 'African pig-like ant eater. Ugly.', + 'anteater', 'South-American ant eater. Two species.', + 'anaconda', 'South-American constrictor snake. Scary.' + ] + } + +--- +test: Pairs +todo: true +yaml: | + # Explicitly typed pairs. + tasks: !pairs + - meeting: with team. + - meeting: with boss. + - break: lunch. + - meeting: with client. +ruby: | + { + 'tasks' => YAML::Pairs[ + 'meeting', 'with team.', + 'meeting', 'with boss.', + 'break', 'lunch.', + 'meeting', 'with client.' + ] + } + +--- +test: Set +todo: true +yaml: | + # Explicitly typed set. + baseball players: !set + Mark McGwire: + Sammy Sosa: + Ken Griffey: +ruby: | + { + 'baseball players' => YAML::Set[ + 'Mark McGwire', nil, + 'Sammy Sosa', nil, + 'Ken Griffey', nil + ] + } + +--- +test: Boolean +yaml: | + false: used as key + logical: true + answer: false +php: | + array( + false => 'used as key', + 'logical' => true, + 'answer' => false + ) +--- +test: Integer +yaml: | + canonical: 12345 + decimal: +12,345 + octal: 014 + hexadecimal: 0xC +php: | + array( + 'canonical' => 12345, + 'decimal' => 12345.0, + 'octal' => 12, + 'hexadecimal' => 12 + ) +--- +test: Float +yaml: | + canonical: 1.23015e+3 + exponential: 12.3015e+02 + fixed: 1,230.15 + negative infinity: -.inf + not a number: .NaN +php: | + array( + 'canonical' => 1230.15, + 'exponential' => 1230.15, + 'fixed' => 1230.15, + 'negative infinity' => log(0), + 'not a number' => -log(0) + ) +--- +test: Timestamp +todo: true +yaml: | + canonical: 2001-12-15T02:59:43.1Z + valid iso8601: 2001-12-14t21:59:43.10-05:00 + space separated: 2001-12-14 21:59:43.10 -05:00 + date (noon UTC): 2002-12-14 +ruby: | + array( + 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), + 'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'date (noon UTC)' => Date.new( 2002, 12, 14 ) + ) +--- +test: Binary +todo: true +yaml: | + canonical: !binary "\ + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" + base64: !binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + description: > + The binary value above is a tiny arrow + encoded as a gif image. +ruby-setup: | + arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;" +ruby: | + { + 'canonical' => arrow_gif, + 'base64' => arrow_gif, + 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" + } + +--- +test: Merge key +todo: true +yaml: | + --- + - &CENTER { x: 1, y: 2 } + - &LEFT { x: 0, y: 2 } + - &BIG { r: 10 } + - &SMALL { r: 1 } + + # All the following maps are equal: + + - # Explicit keys + x: 1 + y: 2 + r: 10 + label: center/big + + - # Merge one map + << : *CENTER + r: 10 + label: center/big + + - # Merge multiple maps + << : [ *CENTER, *BIG ] + label: center/big + + - # Override + << : [ *BIG, *LEFT, *SMALL ] + x: 1 + label: center/big + +ruby-setup: | + center = { 'x' => 1, 'y' => 2 } + left = { 'x' => 0, 'y' => 2 } + big = { 'r' => 10 } + small = { 'r' => 1 } + node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' } + node2 = center.dup + node2.update( { 'r' => 10, 'label' => 'center/big' } ) + node3 = big.dup + node3.update( center ) + node3.update( { 'label' => 'center/big' } ) + node4 = small.dup + node4.update( left ) + node4.update( big ) + node4.update( { 'x' => 1, 'label' => 'center/big' } ) + +ruby: | + [ + center, left, big, small, node1, node2, node3, node4 + ] + +--- +test: Default key +todo: true +yaml: | + --- # Old schema + link with: + - library1.dll + - library2.dll + --- # New schema + link with: + - = : library1.dll + version: 1.2 + - = : library2.dll + version: 2.3 +ruby: | + y = YAML::Stream.new + y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } ) + obj_h = Hash[ 'version' => 1.2 ] + obj_h.default = 'library1.dll' + obj_h2 = Hash[ 'version' => 2.3 ] + obj_h2.default = 'library2.dll' + y.add( { 'link with' => [ obj_h, obj_h2 ] } ) +documents: 2 + +--- +test: Special keys +todo: true +yaml: | + "!": These three keys + "&": had to be quoted + "=": and are normal strings. + # NOTE: the following node should NOT be serialized this way. + encoded node : + !special '!' : '!type' + !special|canonical '&' : 12 + = : value + # The proper way to serialize the above node is as follows: + node : !!type &12 value +ruby: | + { '!' => 'These three keys', '&' => 'had to be quoted', + '=' => 'and are normal strings.', + 'encoded node' => YAML::PrivateType.new( 'type', 'value' ), + 'node' => YAML::PrivateType.new( 'type', 'value' ) } diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml new file mode 100644 index 0000000..46c8d4a --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml @@ -0,0 +1,244 @@ +--- %YAML:1.0 +test: Strings +brief: > + Any group of characters beginning with an + alphabetic or numeric character is a string, + unless it belongs to one of the groups below + (such as an Integer or Time). +yaml: | + String +php: | + 'String' +--- +test: String characters +brief: > + A string can contain any alphabetic or + numeric character, along with many + punctuation characters, including the + period, dash, space, quotes, exclamation, and + question mark. +yaml: | + - What's Yaml? + - It's for writing data structures in plain text. + - And? + - And what? That's not good enough for you? + - No, I mean, "And what about Yaml?" + - Oh, oh yeah. Uh.. Yaml for Ruby. +php: | + array( + "What's Yaml?", + "It's for writing data structures in plain text.", + "And?", + "And what? That's not good enough for you?", + "No, I mean, \"And what about Yaml?\"", + "Oh, oh yeah. Uh.. Yaml for Ruby." + ) +--- +test: Indicators in Strings +brief: > + Be careful using indicators in strings. In particular, + the comma, colon, and pound sign must be used carefully. +yaml: | + the colon followed by space is an indicator: but is a string:right here + same for the pound sign: here we have it#in a string + the comma can, honestly, be used in most cases: [ but not in, inline collections ] +php: | + array( + 'the colon followed by space is an indicator' => 'but is a string:right here', + 'same for the pound sign' => 'here we have it#in a string', + 'the comma can, honestly, be used in most cases' => array('but not in', 'inline collections') + ) +--- +test: Forcing Strings +brief: > + Any YAML type can be forced into a string using the + explicit !str method. +yaml: | + date string: !str 2001-08-01 + number string: !str 192 +php: | + array( + 'date string' => '2001-08-01', + 'number string' => '192' + ) +--- +test: Single-quoted Strings +brief: > + You can also enclose your strings within single quotes, + which allows use of slashes, colons, and other indicators + freely. Inside single quotes, you can represent a single + quote in your string by using two single quotes next to + each other. +yaml: | + all my favorite symbols: '#:!/%.)' + a few i hate: '&(*' + why do i hate them?: 'it''s very hard to explain' + entities: '£ me' +php: | + array( + 'all my favorite symbols' => '#:!/%.)', + 'a few i hate' => '&(*', + 'why do i hate them?' => 'it\'s very hard to explain', + 'entities' => '£ me' + ) +--- +test: Double-quoted Strings +brief: > + Enclosing strings in double quotes allows you + to use escapings to represent ASCII and + Unicode characters. +yaml: | + i know where i want my line breaks: "one here\nand another here\n" +php: | + array( + 'i know where i want my line breaks' => "one here\nand another here\n" + ) +--- +test: Multi-line Quoted Strings +todo: true +brief: > + Both single- and double-quoted strings may be + carried on to new lines in your YAML document. + They must be indented a step and indentation + is interpreted as a single space. +yaml: | + i want a long string: "so i'm going to + let it go on and on to other lines + until i end it with a quote." +php: | + array('i want a long string' => "so i'm going to ". + "let it go on and on to other lines ". + "until i end it with a quote." + ) + +--- +test: Plain scalars +todo: true +brief: > + Unquoted strings may also span multiple lines, if they + are free of YAML space indicators and indented. +yaml: | + - My little toe is broken in two places; + - I'm crazy to have skied this way; + - I'm not the craziest he's seen, since there was always the German guy + who skied for 3 hours on a broken shin bone (just below the kneecap); + - Nevertheless, second place is respectable, and he doesn't + recommend going for the record; + - He's going to put my foot in plaster for a month; + - This would impair my skiing ability somewhat for the + duration, as can be imagined. +php: | + array( + "My little toe is broken in two places;", + "I'm crazy to have skied this way;", + "I'm not the craziest he's seen, since there was always ". + "the German guy who skied for 3 hours on a broken shin ". + "bone (just below the kneecap);", + "Nevertheless, second place is respectable, and he doesn't ". + "recommend going for the record;", + "He's going to put my foot in plaster for a month;", + "This would impair my skiing ability somewhat for the duration, ". + "as can be imagined." + ) +--- +test: 'Null' +brief: > + You can use the tilde '~' character for a null value. +yaml: | + name: Mr. Show + hosted by: Bob and David + date of next season: ~ +php: | + array( + 'name' => 'Mr. Show', + 'hosted by' => 'Bob and David', + 'date of next season' => null + ) +--- +test: Boolean +brief: > + You can use 'true' and 'false' for Boolean values. +yaml: | + Is Gus a Liar?: true + Do I rely on Gus for Sustenance?: false +php: | + array( + 'Is Gus a Liar?' => true, + 'Do I rely on Gus for Sustenance?' => false + ) +--- +test: Integers +dump_skip: true +brief: > + An integer is a series of numbers, optionally + starting with a positive or negative sign. Integers + may also contain commas for readability. +yaml: | + zero: 0 + simple: 12 + one-thousand: 1,000 + negative one-thousand: -1,000 +php: | + array( + 'zero' => 0, + 'simple' => 12, + 'one-thousand' => 1000.0, + 'negative one-thousand' => -1000.0 + ) +--- +test: Integers as Map Keys +brief: > + An integer can be used a dictionary key. +yaml: | + 1: one + 2: two + 3: three +php: | + array( + 1 => 'one', + 2 => 'two', + 3 => 'three' + ) +--- +test: Floats +dump_skip: true +brief: > + Floats are represented by numbers with decimals, + allowing for scientific notation, as well as + positive and negative infinity and "not a number." +yaml: | + a simple float: 2.00 + larger float: 1,000.09 + scientific notation: 1.00009e+3 +php: | + array( + 'a simple float' => 2.0, + 'larger float' => 1000.09, + 'scientific notation' => 1000.09 + ) +--- +test: Time +todo: true +brief: > + You can represent timestamps by using + ISO8601 format, or a variation which + allows spaces between the date, time and + time zone. +yaml: | + iso8601: 2001-12-14t21:59:43.10-05:00 + space separated: 2001-12-14 21:59:43.10 -05:00 +php: | + array( + 'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ) + ) +--- +test: Date +todo: true +brief: > + A date can be represented by its year, + month and day in ISO8601 order. +yaml: | + 1976-07-31 +php: | + date( 1976, 7, 31 ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml new file mode 100644 index 0000000..ec456ed --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml @@ -0,0 +1 @@ +value: diff --git a/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml new file mode 100644 index 0000000..6ca044c --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml @@ -0,0 +1,155 @@ +test: outside double quotes +yaml: | + \0 \ \a \b \n +php: | + "\\0 \\ \\a \\b \\n" +--- +test: null +yaml: | + "\0" +php: | + "\x00" +--- +test: bell +yaml: | + "\a" +php: | + "\x07" +--- +test: backspace +yaml: | + "\b" +php: | + "\x08" +--- +test: horizontal tab (1) +yaml: | + "\t" +php: | + "\x09" +--- +test: horizontal tab (2) +yaml: | + "\ " +php: | + "\x09" +--- +test: line feed +yaml: | + "\n" +php: | + "\x0a" +--- +test: vertical tab +yaml: | + "\v" +php: | + "\x0b" +--- +test: form feed +yaml: | + "\f" +php: | + "\x0c" +--- +test: carriage return +yaml: | + "\r" +php: | + "\x0d" +--- +test: escape +yaml: | + "\e" +php: | + "\x1b" +--- +test: space +yaml: | + "\ " +php: | + "\x20" +--- +test: slash +yaml: | + "\/" +php: | + "\x2f" +--- +test: backslash +yaml: | + "\\" +php: | + "\\" +--- +test: Unicode next line +yaml: | + "\N" +php: | + "\xc2\x85" +--- +test: Unicode non-breaking space +yaml: | + "\_" +php: | + "\xc2\xa0" +--- +test: Unicode line separator +yaml: | + "\L" +php: | + "\xe2\x80\xa8" +--- +test: Unicode paragraph separator +yaml: | + "\P" +php: | + "\xe2\x80\xa9" +--- +test: Escaped 8-bit Unicode +yaml: | + "\x42" +php: | + "B" +--- +test: Escaped 16-bit Unicode +yaml: | + "\u20ac" +php: | + "\xe2\x82\xac" +--- +test: Escaped 32-bit Unicode +yaml: | + "\U00000043" +php: | + "C" +--- +test: Example 5.13 Escaped Characters +note: | + Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support + continuation of string across multiple lines? Keeping test here but disabled. +todo: true +yaml: | + "Fun with \\ + \" \a \b \e \f \ + \n \r \t \v \0 \ + \ \_ \N \L \P \ + \x41 \u0041 \U00000041" +php: | + "Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A" +--- +test: Double quotes with a line feed +yaml: | + { double: "some value\n \"some quoted string\" and 'some single quotes one'" } +php: | + array( + 'double' => "some value\n \"some quoted string\" and 'some single quotes one'" + ) +--- +test: Backslashes +yaml: | + { single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" } +php: | + array( + 'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var' + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/index.yml b/vendor/symfony/yaml/Tests/Fixtures/index.yml new file mode 100644 index 0000000..3216a89 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/index.yml @@ -0,0 +1,18 @@ +- escapedCharacters +- sfComments +- sfCompact +- sfTests +- sfObjects +- sfMergeKey +- sfQuotes +- YtsAnchorAlias +- YtsBasicTests +- YtsBlockMapping +- YtsDocumentSeparator +- YtsErrorTests +- YtsFlowCollections +- YtsFoldedScalars +- YtsNullsAndEmpties +- YtsSpecificationExamples +- YtsTypeTransfers +- unindentedCollections diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml new file mode 100644 index 0000000..b72a9b6 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml @@ -0,0 +1,76 @@ +--- %YAML:1.0 +test: Comments at the end of a line +brief: > + Comments at the end of a line +yaml: | + ex1: "foo # bar" + ex2: "foo # bar" # comment + ex3: 'foo # bar' # comment + ex4: foo # comment + ex5: foo # comment with tab before + ex6: foo#foo # comment here + ex7: foo # ignore me # and me +php: | + array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo', 'ex5' => 'foo', 'ex6' => 'foo#foo', 'ex7' => 'foo') +--- +test: Comments in the middle +brief: > + Comments in the middle +yaml: | + foo: + # some comment + # some comment + bar: foo + # some comment + # some comment +php: | + array('foo' => array('bar' => 'foo')) +--- +test: Comments on a hash line +brief: > + Comments on a hash line +yaml: | + foo: # a comment + foo: bar # a comment +php: | + array('foo' => array('foo' => 'bar')) +--- +test: 'Value starting with a #' +brief: > + 'Value starting with a #' +yaml: | + foo: '#bar' +php: | + array('foo' => '#bar') +--- +test: Document starting with a comment and a separator +brief: > + Commenting before document start is allowed +yaml: | + # document comment + --- + foo: bar # a comment +php: | + array('foo' => 'bar') +--- +test: Comment containing a colon on a hash line +brief: > + Comment containing a colon on a scalar line +yaml: 'foo # comment: this is also part of the comment' +php: | + 'foo' +--- +test: 'Hash key containing a #' +brief: > + 'Hash key containing a #' +yaml: 'foo#bar: baz' +php: | + array('foo#bar' => 'baz') +--- +test: 'Hash key ending with a space and a #' +brief: > + 'Hash key ending with a space and a #' +yaml: | + 'foo #': baz +php: | + array('foo #' => 'baz') diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml new file mode 100644 index 0000000..1339d23 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml @@ -0,0 +1,159 @@ +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + ), + array ( + 'item' => 'Basketball', + 'quantity' => 1, + ), + array ( + 'item' => array( + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ), + 'quantity' => 1 + ) + ) +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + array ( + 'items' => array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'Basketball', + 'Big Shoes' + ) + ) + ) +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + ), + array ( + 'item' => 'Basketball', + 'quantity' => 1, + ), + array ( + 'item' => array( + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ), + 'quantity' => 1 + ) + ) +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + array ( + 'items' => array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'Basketball', + 'Big Shoes' + ) + ) + ) +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + ), + array ( + 'item' => 'Basketball', + 'quantity' => 1, + ), + array ( + 'item' => array( + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ), + 'quantity' => 1 + ) + ) +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + array ( + 'items' => array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'Basketball', + 'Big Shoes' + ) + ) + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml new file mode 100644 index 0000000..499446c --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml @@ -0,0 +1,66 @@ +--- %YAML:1.0 +test: Simple In Place Substitution +brief: > + If you want to reuse an entire alias, only overwriting what is different + you can use a << in place substitution. This is not part of the official + YAML spec, but a widely implemented extension. See the following URL for + details: http://yaml.org/type/merge.html +yaml: | + foo: &foo + a: Steve + b: Clark + c: Brian + e: notnull + bar: + a: before + d: other + e: ~ + <<: *foo + b: new + x: Oren + c: + foo: bar + foo: ignore + bar: foo + bar_inline: {a: before, d: other, <<: *foo, b: new, x: Oren, c: { foo: bar, foo: ignore, bar: foo}} + duplicate: + foo: bar + foo: ignore + foo2: &foo2 + a: Ballmer + ding: &dong [ fi, fei, fo, fam] + check: + <<: + - *foo + - *dong + isit: tested + head: + <<: [ *foo , *dong , *foo2 ] + taz: &taz + a: Steve + w: + p: 1234 + nested: + <<: *taz + d: Doug + w: &nestedref + p: 12345 + z: + <<: *nestedref + head_inline: &head_inline { <<: [ *foo , *dong , *foo2 ] } + recursive_inline: { <<: *head_inline, c: { <<: *foo2 } } +php: | + array( + 'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull'), + 'bar' => array('a' => 'before', 'd' => 'other', 'e' => null, 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'), + 'bar_inline' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'e' => 'notnull', 'x' => 'Oren'), + 'duplicate' => array('foo' => 'bar'), + 'foo2' => array('a' => 'Ballmer'), + 'ding' => array('fi', 'fei', 'fo', 'fam'), + 'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'), + 'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'), + 'taz' => array('a' => 'Steve', 'w' => array('p' => 1234)), + 'nested' => array('a' => 'Steve', 'w' => array('p' => 12345), 'd' => 'Doug', 'z' => array('p' => 12345)), + 'head_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'), + 'recursive_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => array('a' => 'Ballmer'), 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'), + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml new file mode 100644 index 0000000..ee124b2 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml @@ -0,0 +1,11 @@ +--- %YAML:1.0 +test: Objects +brief: > + Comments at the end of a line +yaml: | + ex1: "foo # bar" + ex2: "foo # bar" # comment + ex3: 'foo # bar' # comment + ex4: foo # comment +php: | + array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo') diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml new file mode 100644 index 0000000..7c60bae --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml @@ -0,0 +1,33 @@ +--- %YAML:1.0 +test: Some characters at the beginning of a string must be escaped +brief: > + Some characters at the beginning of a string must be escaped +yaml: | + foo: '| bar' +php: | + array('foo' => '| bar') +--- +test: A key can be a quoted string +brief: > + A key can be a quoted string +yaml: | + "foo1": bar + 'foo2': bar + "foo \" bar": bar + 'foo '' bar': bar + 'foo3: ': bar + "foo4: ": bar + foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar } +php: | + array( + 'foo1' => 'bar', + 'foo2' => 'bar', + 'foo " bar' => 'bar', + 'foo \' bar' => 'bar', + 'foo3: ' => 'bar', + 'foo4: ' => 'bar', + 'foo5' => array( + 'foo " bar: ' => 'bar', + 'foo \' bar: ' => 'bar', + ), + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml new file mode 100644 index 0000000..a427be1 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml @@ -0,0 +1,149 @@ +--- %YAML:1.0 +test: Multiple quoted string on one line +brief: > + Multiple quoted string on one line +yaml: | + stripped_title: { name: "foo bar", help: "bar foo" } +php: | + array('stripped_title' => array('name' => 'foo bar', 'help' => 'bar foo')) +--- +test: Empty sequence +yaml: | + foo: [ ] +php: | + array('foo' => array()) +--- +test: Empty value +yaml: | + foo: +php: | + array('foo' => null) +--- +test: Inline string parsing +brief: > + Inline string parsing +yaml: | + test: ['complex: string', 'another [string]'] +php: | + array('test' => array('complex: string', 'another [string]')) +--- +test: Boolean +brief: > + Boolean +yaml: | + - false + - true + - null + - ~ + - 'false' + - 'true' + - 'null' + - '~' +php: | + array( + false, + true, + null, + null, + 'false', + 'true', + 'null', + '~', + ) +--- +test: Empty lines in literal blocks +brief: > + Empty lines in literal blocks +yaml: | + foo: + bar: | + foo + + + + bar +php: | + array('foo' => array('bar' => "foo\n\n\n \nbar\n")) +--- +test: Empty lines in folded blocks +brief: > + Empty lines in folded blocks +yaml: | + foo: + bar: > + + foo + + + bar +php: | + array('foo' => array('bar' => "\nfoo\n\nbar\n")) +--- +test: IP addresses +brief: > + IP addresses +yaml: | + foo: 10.0.0.2 +php: | + array('foo' => '10.0.0.2') +--- +test: A sequence with an embedded mapping +brief: > + A sequence with an embedded mapping +yaml: | + - foo + - bar: { bar: foo } +php: | + array('foo', array('bar' => array('bar' => 'foo'))) +--- +test: A sequence with an unordered array +brief: > + A sequence with an unordered array +yaml: | + 1: foo + 0: bar +php: | + array(1 => 'foo', 0 => 'bar') +--- +test: Octal +brief: as in spec example 2.19, octal value is converted +yaml: | + foo: 0123 +php: | + array('foo' => 83) +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: "0123" +php: | + array('foo' => '0123') +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: '0123' +php: | + array('foo' => '0123') +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: | + 0123 +php: | + array('foo' => "0123\n") +--- +test: Document as a simple hash +brief: Document as a simple hash +yaml: | + { foo: bar } +php: | + array('foo' => 'bar') +--- +test: Document as a simple array +brief: Document as a simple array +yaml: | + [ foo, bar ] +php: | + array('foo', 'bar') diff --git a/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml new file mode 100644 index 0000000..0c96108 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml @@ -0,0 +1,82 @@ +--- %YAML:1.0 +test: Unindented collection +brief: > + Unindented collection +yaml: | + collection: + - item1 + - item2 + - item3 +php: | + array('collection' => array('item1', 'item2', 'item3')) +--- +test: Nested unindented collection (two levels) +brief: > + Nested unindented collection +yaml: | + collection: + key: + - a + - b + - c +php: | + array('collection' => array('key' => array('a', 'b', 'c'))) +--- +test: Nested unindented collection (three levels) +brief: > + Nested unindented collection +yaml: | + collection: + key: + subkey: + - one + - two + - three +php: | + array('collection' => array('key' => array('subkey' => array('one', 'two', 'three')))) +--- +test: Key/value after unindented collection (1) +brief: > + Key/value after unindented collection (1) +yaml: | + collection: + key: + - a + - b + - c + foo: bar +php: | + array('collection' => array('key' => array('a', 'b', 'c')), 'foo' => 'bar') +--- +test: Key/value after unindented collection (at the same level) +brief: > + Key/value after unindented collection +yaml: | + collection: + key: + - a + - b + - c + foo: bar +php: | + array('collection' => array('key' => array('a', 'b', 'c'), 'foo' => 'bar')) +--- +test: Shortcut Key after unindented collection +brief: > + Key/value after unindented collection +yaml: | + collection: + - key: foo + foo: bar +php: | + array('collection' => array(array('key' => 'foo', 'foo' => 'bar'))) +--- +test: Shortcut Key after unindented collection with custom spaces +brief: > + Key/value after unindented collection +yaml: | + collection: + - key: foo + foo: bar +php: | + array('collection' => array(array('key' => 'foo', 'foo' => 'bar'))) diff --git a/vendor/symfony/yaml/Tests/InlineTest.php b/vendor/symfony/yaml/Tests/InlineTest.php new file mode 100644 index 0000000..66ef701 --- /dev/null +++ b/vendor/symfony/yaml/Tests/InlineTest.php @@ -0,0 +1,506 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Inline; + +class InlineTest extends TestCase +{ + /** + * @dataProvider getTestsForParse + */ + public function testParse($yaml, $value) + { + $this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml)); + } + + /** + * @dataProvider getTestsForParseWithMapObjects + */ + public function testParseWithMapObjects($yaml, $value) + { + $actual = Inline::parse($yaml, false, false, true); + + $this->assertSame(serialize($value), serialize($actual)); + } + + /** + * @dataProvider getTestsForDump + */ + public function testDump($yaml, $value) + { + $this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml)); + + $this->assertSame($value, Inline::parse(Inline::dump($value)), 'check consistency'); + } + + public function testDumpNumericValueWithLocale() + { + $locale = setlocale(LC_NUMERIC, 0); + if (false === $locale) { + $this->markTestSkipped('Your platform does not support locales.'); + } + + try { + $requiredLocales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252'); + if (false === setlocale(LC_NUMERIC, $requiredLocales)) { + $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales)); + } + + $this->assertEquals('1.2', Inline::dump(1.2)); + $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0))); + setlocale(LC_NUMERIC, $locale); + } catch (\Exception $e) { + setlocale(LC_NUMERIC, $locale); + throw $e; + } + } + + public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF() + { + $value = '686e444'; + + $this->assertSame($value, Inline::parse(Inline::dump($value))); + } + + /** + * @group legacy + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseScalarWithNonEscapedBlackslashShouldThrowException() + { + $this->assertSame('Foo\Var', Inline::parse('"Foo\Var"')); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException() + { + Inline::parse('"Foo\\"'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException() + { + $value = "'don't do somthin' like that'"; + Inline::parse($value); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException() + { + $value = '"don"t do somthin" like that"'; + Inline::parse($value); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidMappingKeyShouldThrowException() + { + $value = '{ "foo " bar": "bar" }'; + Inline::parse($value); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidMappingShouldThrowException() + { + Inline::parse('[foo] bar'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidSequenceShouldThrowException() + { + Inline::parse('{ foo: bar } bar'); + } + + public function testParseScalarWithCorrectlyQuotedStringShouldReturnString() + { + $value = "'don''t do somthin'' like that'"; + $expect = "don't do somthin' like that"; + + $this->assertSame($expect, Inline::parseScalar($value)); + } + + /** + * @dataProvider getDataForParseReferences + */ + public function testParseReferences($yaml, $expected) + { + $this->assertSame($expected, Inline::parse($yaml, false, false, false, array('var' => 'var-value'))); + } + + public function getDataForParseReferences() + { + return array( + 'scalar' => array('*var', 'var-value'), + 'list' => array('[ *var ]', array('var-value')), + 'list-in-list' => array('[[ *var ]]', array(array('var-value'))), + 'map-in-list' => array('[ { key: *var } ]', array(array('key' => 'var-value'))), + 'embedded-mapping-in-list' => array('[ key: *var ]', array(array('key' => 'var-value'))), + 'map' => array('{ key: *var }', array('key' => 'var-value')), + 'list-in-map' => array('{ key: [*var] }', array('key' => array('var-value'))), + 'map-in-map' => array('{ foo: { bar: *var } }', array('foo' => array('bar' => 'var-value'))), + ); + } + + public function testParseMapReferenceInSequence() + { + $foo = array( + 'a' => 'Steve', + 'b' => 'Clark', + 'c' => 'Brian', + ); + $this->assertSame(array($foo), Inline::parse('[*foo]', false, false, false, array('foo' => $foo))); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage A reference must contain at least one character. + */ + public function testParseUnquotedAsterisk() + { + Inline::parse('{ foo: * }'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage A reference must contain at least one character. + */ + public function testParseUnquotedAsteriskFollowedByAComment() + { + Inline::parse('{ foo: * #foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar "@foo " starting with "@" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithReservedAtIndicator() + { + Inline::parse('{ foo: @foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar "`foo " starting with "`" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithReservedBacktickIndicator() + { + Inline::parse('{ foo: `foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar "|foo " starting with "|" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithLiteralStyleIndicator() + { + Inline::parse('{ foo: |foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar ">foo " starting with ">" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithFoldedStyleIndicator() + { + Inline::parse('{ foo: >foo }'); + } + + public function getScalarIndicators() + { + return array(array('|'), array('>')); + } + + /** + * @dataProvider getDataForIsHash + */ + public function testIsHash($array, $expected) + { + $this->assertSame($expected, Inline::isHash($array)); + } + + public function getDataForIsHash() + { + return array( + array(array(), false), + array(array(1, 2, 3), false), + array(array(2 => 1, 1 => 2, 0 => 3), true), + array(array('foo' => 1, 'bar' => 2), true), + ); + } + + public function getTestsForParse() + { + return array( + array('', ''), + array('null', null), + array('false', false), + array('true', true), + array('12', 12), + array('-12', -12), + array('"quoted string"', 'quoted string'), + array("'quoted string'", 'quoted string'), + array('12.30e+02', 12.30e+02), + array('0x4D2', 0x4D2), + array('02333', 02333), + array('.Inf', -log(0)), + array('-.Inf', log(0)), + array("'686e444'", '686e444'), + array('686e444', 646e444), + array('123456789123456789123456789123456789', '123456789123456789123456789123456789'), + array('"foo\r\nbar"', "foo\r\nbar"), + array("'foo#bar'", 'foo#bar'), + array("'foo # bar'", 'foo # bar'), + array("'#cfcfcf'", '#cfcfcf'), + array('::form_base.html.twig', '::form_base.html.twig'), + + // Pre-YAML-1.2 booleans + array("'y'", 'y'), + array("'n'", 'n'), + array("'yes'", 'yes'), + array("'no'", 'no'), + array("'on'", 'on'), + array("'off'", 'off'), + + array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)), + array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)), + array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)), + + array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''), + array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''), + + // sequences + // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon + array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)), + array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)), + array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), + + // mappings + array('{foo:bar,bar:foo,false:false,null:null,integer:12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')), + array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', array('foo: ' => 'bar', 'bar: ' => 'foo: bar')), + + // nested sequences and mappings + array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))), + array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))), + array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))), + array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))), + + array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))), + + array('[{ foo: {bar: foo} }]', array(array('foo' => array('bar' => 'foo')))), + + array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))), + + array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))), + + array('[foo, bar: { foo: bar }]', array('foo', '1' => array('bar' => array('foo' => 'bar')))), + array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')), + ); + } + + public function getTestsForParseWithMapObjects() + { + return array( + array('', ''), + array('null', null), + array('false', false), + array('true', true), + array('12', 12), + array('-12', -12), + array('"quoted string"', 'quoted string'), + array("'quoted string'", 'quoted string'), + array('12.30e+02', 12.30e+02), + array('0x4D2', 0x4D2), + array('02333', 02333), + array('.Inf', -log(0)), + array('-.Inf', log(0)), + array("'686e444'", '686e444'), + array('686e444', 646e444), + array('123456789123456789123456789123456789', '123456789123456789123456789123456789'), + array('"foo\r\nbar"', "foo\r\nbar"), + array("'foo#bar'", 'foo#bar'), + array("'foo # bar'", 'foo # bar'), + array("'#cfcfcf'", '#cfcfcf'), + array('::form_base.html.twig', '::form_base.html.twig'), + + array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)), + array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)), + array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)), + + array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''), + array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''), + + // sequences + // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon + array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)), + array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)), + array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), + + // mappings + array('{foo:bar,bar:foo,false:false,null:null,integer:12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')), + array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) array('foo: ' => 'bar', 'bar: ' => 'foo: bar')), + + // nested sequences and mappings + array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))), + array('[foo, {bar: foo}]', array('foo', (object) array('bar' => 'foo'))), + array('{ foo: {bar: foo} }', (object) array('foo' => (object) array('bar' => 'foo'))), + array('{ foo: [bar, foo] }', (object) array('foo' => array('bar', 'foo'))), + + array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))), + + array('[{ foo: {bar: foo} }]', array((object) array('foo' => (object) array('bar' => 'foo')))), + + array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))), + + array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', (object) array('bar' => 'foo', 'foo' => array('foo', (object) array('bar' => 'foo'))), array('foo', (object) array('bar' => 'foo')))), + + array('[foo, bar: { foo: bar }]', array('foo', '1' => (object) array('bar' => (object) array('foo' => 'bar')))), + array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', (object) array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')), + + array('{}', new \stdClass()), + array('{ foo : bar, bar : {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())), + array('{ foo : [], bar : {} }', (object) array('foo' => array(), 'bar' => new \stdClass())), + array('{foo: \'bar\', bar: {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())), + array('{\'foo\': \'bar\', "bar": {}}', (object) array('foo' => 'bar', 'bar' => new \stdClass())), + array('{\'foo\': \'bar\', "bar": \'{}\'}', (object) array('foo' => 'bar', 'bar' => '{}')), + + array('[foo, [{}, {}]]', array('foo', array(new \stdClass(), new \stdClass()))), + array('[foo, [[], {}]]', array('foo', array(array(), new \stdClass()))), + array('[foo, [[{}, {}], {}]]', array('foo', array(array(new \stdClass(), new \stdClass()), new \stdClass()))), + array('[foo, {bar: {}}]', array('foo', '1' => (object) array('bar' => new \stdClass()))), + ); + } + + public function getTestsForDump() + { + return array( + array('null', null), + array('false', false), + array('true', true), + array('12', 12), + array("'quoted string'", 'quoted string'), + array('!!float 1230', 12.30e+02), + array('1234', 0x4D2), + array('1243', 02333), + array('.Inf', -log(0)), + array('-.Inf', log(0)), + array("'686e444'", '686e444'), + array('"foo\r\nbar"', "foo\r\nbar"), + array("'foo#bar'", 'foo#bar'), + array("'foo # bar'", 'foo # bar'), + array("'#cfcfcf'", '#cfcfcf'), + + array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''), + + array("'-dash'", '-dash'), + array("'-'", '-'), + + // Pre-YAML-1.2 booleans + array("'y'", 'y'), + array("'n'", 'n'), + array("'yes'", 'yes'), + array("'no'", 'no'), + array("'on'", 'on'), + array("'off'", 'off'), + + // sequences + array('[foo, bar, false, null, 12]', array('foo', 'bar', false, null, 12)), + array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), + + // mappings + array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')), + + // nested sequences and mappings + array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))), + + array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))), + + array('{ foo: { bar: foo } }', array('foo' => array('bar' => 'foo'))), + + array('[foo, { bar: foo }]', array('foo', array('bar' => 'foo'))), + + array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))), + + array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')), + + array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))), + ); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Malformed inline YAML string: {this, is not, supported}. + */ + public function testNotSupportedMissingValue() + { + Inline::parse('{this, is not, supported}'); + } + + public function testVeryLongQuotedStrings() + { + $longStringWithQuotes = str_repeat("x\r\n\\\"x\"x", 1000); + + $yamlString = Inline::dump(array('longStringWithQuotes' => $longStringWithQuotes)); + $arrayFromYaml = Inline::parse($yamlString); + + $this->assertEquals($longStringWithQuotes, $arrayFromYaml['longStringWithQuotes']); + } + + public function testBooleanMappingKeysAreConvertedToStrings() + { + $this->assertSame(array('false' => 'foo'), Inline::parse('{false: foo}')); + $this->assertSame(array('true' => 'foo'), Inline::parse('{true: foo}')); + } + + public function testTheEmptyStringIsAValidMappingKey() + { + $this->assertSame(array('' => 'foo'), Inline::parse('{ "": foo }')); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Unexpected end of line, expected one of ",}". + */ + public function testUnfinishedInlineMap() + { + Inline::parse("{abc: 'def'"); + } +} diff --git a/vendor/symfony/yaml/Tests/ParseExceptionTest.php b/vendor/symfony/yaml/Tests/ParseExceptionTest.php new file mode 100644 index 0000000..b7797fb --- /dev/null +++ b/vendor/symfony/yaml/Tests/ParseExceptionTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Exception\ParseException; + +class ParseExceptionTest extends TestCase +{ + public function testGetMessage() + { + $exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml'); + if (\PHP_VERSION_ID >= 50400) { + $message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")'; + } else { + $message = 'Error message in "\\/var\\/www\\/app\\/config.yml" at line 42 (near "foo: bar")'; + } + + $this->assertEquals($message, $exception->getMessage()); + } + + public function testGetMessageWithUnicodeInFilename() + { + $exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml'); + if (\PHP_VERSION_ID >= 50400) { + $message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")'; + } else { + $message = 'Error message in "\u00e4\u00f6\u00fc.yml" at line 42 (near "foo: bar")'; + } + + $this->assertEquals($message, $exception->getMessage()); + } +} diff --git a/vendor/symfony/yaml/Tests/ParserTest.php b/vendor/symfony/yaml/Tests/ParserTest.php new file mode 100644 index 0000000..0cf9bd4 --- /dev/null +++ b/vendor/symfony/yaml/Tests/ParserTest.php @@ -0,0 +1,1300 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Yaml; + +class ParserTest extends TestCase +{ + /** @var Parser */ + protected $parser; + + protected function setUp() + { + $this->parser = new Parser(); + } + + protected function tearDown() + { + $this->parser = null; + } + + /** + * @dataProvider getDataFormSpecifications + */ + public function testSpecifications($file, $expected, $yaml, $comment) + { + $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment); + } + + public function getDataFormSpecifications() + { + $parser = new Parser(); + $path = __DIR__.'/Fixtures'; + + $tests = array(); + $files = $parser->parse(file_get_contents($path.'/index.yml')); + foreach ($files as $file) { + $yamls = file_get_contents($path.'/'.$file.'.yml'); + + // split YAMLs documents + foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { + if (!$yaml) { + continue; + } + + $test = $parser->parse($yaml); + if (isset($test['todo']) && $test['todo']) { + // TODO + } else { + eval('$expected = '.trim($test['php']).';'); + + $tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']); + } + } + } + + return $tests; + } + + public function testTabsInYaml() + { + // test tabs in YAML + $yamls = array( + "foo:\n bar", + "foo:\n bar", + "foo:\n bar", + "foo:\n bar", + ); + + foreach ($yamls as $yaml) { + try { + $content = $this->parser->parse($yaml); + + $this->fail('YAML files must not contain tabs'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs'); + $this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs'); + } + } + } + + public function testEndOfTheDocumentMarker() + { + $yaml = <<<'EOF' +--- %YAML:1.0 +foo +... +EOF; + + $this->assertEquals('foo', $this->parser->parse($yaml)); + } + + public function getBlockChompingTests() + { + $tests = array(); + + $yaml = <<<'EOF' +foo: |- + one + two +bar: |- + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |- + one + two + +bar: |- + one + two + + +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +{} + + +EOF; + $expected = array(); + $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |- + one + two +bar: |- + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two +bar: | + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two + +bar: | + one + two + + +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: +- bar: | + one + + two +EOF; + $expected = array( + 'foo' => array( + array( + 'bar' => "one\n\ntwo", + ), + ), + ); + $tests['Literal block chomping clip with embedded blank line inside unindented collection'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two +bar: | + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two +bar: |+ + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two + +bar: |+ + one + two + + +EOF; + $expected = array( + 'foo' => "one\ntwo\n\n", + 'bar' => "one\ntwo\n\n", + ); + $tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two +bar: |+ + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two +bar: >- + one + two + +EOF; + $expected = array( + 'foo' => 'one two', + 'bar' => 'one two', + ); + $tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two + +bar: >- + one + two + + +EOF; + $expected = array( + 'foo' => 'one two', + 'bar' => 'one two', + ); + $tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two +bar: >- + one + two +EOF; + $expected = array( + 'foo' => 'one two', + 'bar' => 'one two', + ); + $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two +bar: > + one + two + +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two + +bar: > + one + two + + +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two +bar: > + one + two +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => 'one two', + ); + $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two +bar: >+ + one + two + +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two + +bar: >+ + one + two + + +EOF; + $expected = array( + 'foo' => "one two\n\n", + 'bar' => "one two\n\n", + ); + $tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two +bar: >+ + one + two +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => 'one two', + ); + $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml); + + return $tests; + } + + /** + * @dataProvider getBlockChompingTests + */ + public function testBlockChomping($expected, $yaml) + { + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * Regression test for issue #7989. + * + * @see https://github.com/symfony/symfony/issues/7989 + */ + public function testBlockLiteralWithLeadingNewlines() + { + $yaml = <<<'EOF' +foo: |- + + + bar + +EOF; + $expected = array( + 'foo' => "\n\nbar", + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testObjectSupportEnabled() + { + $input = <<<'EOF' +foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + + $input = <<<'EOF' +foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + } + + /** + * @dataProvider invalidDumpedObjectProvider + */ + public function testObjectSupportDisabledButNoExceptions($input) + { + $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects'); + } + + /** + * @dataProvider getObjectForMapTests + */ + public function testObjectForMap($yaml, $expected) + { + $this->assertEquals($expected, $this->parser->parse($yaml, false, false, true)); + } + + public function getObjectForMapTests() + { + $tests = array(); + + $yaml = <<<'EOF' +foo: + fiz: [cat] +EOF; + $expected = new \stdClass(); + $expected->foo = new \stdClass(); + $expected->foo->fiz = array('cat'); + $tests['mapping'] = array($yaml, $expected); + + $yaml = '{ "foo": "bar", "fiz": "cat" }'; + $expected = new \stdClass(); + $expected->foo = 'bar'; + $expected->fiz = 'cat'; + $tests['inline-mapping'] = array($yaml, $expected); + + $yaml = "foo: bar\nbaz: foobar"; + $expected = new \stdClass(); + $expected->foo = 'bar'; + $expected->baz = 'foobar'; + $tests['object-for-map-is-applied-after-parsing'] = array($yaml, $expected); + + $yaml = <<<'EOT' +array: + - key: one + - key: two +EOT; + $expected = new \stdClass(); + $expected->array = array(); + $expected->array[0] = new \stdClass(); + $expected->array[0]->key = 'one'; + $expected->array[1] = new \stdClass(); + $expected->array[1]->key = 'two'; + $tests['nest-map-and-sequence'] = array($yaml, $expected); + + $yaml = <<<'YAML' +map: + 1: one + 2: two +YAML; + $expected = new \stdClass(); + $expected->map = new \stdClass(); + $expected->map->{1} = 'one'; + $expected->map->{2} = 'two'; + $tests['numeric-keys'] = array($yaml, $expected); + + $yaml = <<<'YAML' +map: + 0: one + 1: two +YAML; + $expected = new \stdClass(); + $expected->map = new \stdClass(); + $expected->map->{0} = 'one'; + $expected->map->{1} = 'two'; + $tests['zero-indexed-numeric-keys'] = array($yaml, $expected); + + return $tests; + } + + /** + * @dataProvider invalidDumpedObjectProvider + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testObjectsSupportDisabledWithExceptions($yaml) + { + $this->parser->parse($yaml, true, false); + } + + public function invalidDumpedObjectProvider() + { + $yamlTag = <<<'EOF' +foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $localTag = <<<'EOF' +foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + + return array( + 'yaml-tag' => array($yamlTag), + 'local-tag' => array($localTag), + ); + } + + /** + * @requires extension iconv + */ + public function testNonUtf8Exception() + { + $yamls = array( + iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"), + iconv('UTF-8', 'ISO-8859-15', "euro: '€'"), + iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"), + ); + + foreach ($yamls as $yaml) { + try { + $this->parser->parse($yaml); + + $this->fail('charsets other than UTF-8 are rejected.'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.'); + } + } + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testUnindentedCollectionException() + { + $yaml = <<<'EOF' + +collection: +-item1 +-item2 +-item3 + +EOF; + + $this->parser->parse($yaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testShortcutKeyUnindentedCollectionException() + { + $yaml = <<<'EOF' + +collection: +- key: foo + foo: bar + +EOF; + + $this->parser->parse($yaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/ + */ + public function testMultipleDocumentsNotSupportedException() + { + Yaml::parse(<<<'EOL' +# Ranking of 1998 home runs +--- +- Mark McGwire +- Sammy Sosa +- Ken Griffey + +# Team ranking +--- +- Chicago Cubs +- St Louis Cardinals +EOL + ); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testSequenceInAMapping() + { + Yaml::parse(<<<'EOF' +yaml: + hash: me + - array stuff +EOF + ); + } + + public function testSequenceInMappingStartedBySingleDashLine() + { + $yaml = <<<'EOT' +a: +- + b: + - + bar: baz +- foo +d: e +EOT; + $expected = array( + 'a' => array( + array( + 'b' => array( + array( + 'bar' => 'baz', + ), + ), + ), + 'foo', + ), + 'd' => 'e', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testSequenceFollowedByCommentEmbeddedInMapping() + { + $yaml = <<<'EOT' +a: + b: + - c +# comment + d: e +EOT; + $expected = array( + 'a' => array( + 'b' => array('c'), + 'd' => 'e', + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testMappingInASequence() + { + Yaml::parse(<<<'EOF' +yaml: + - array stuff + hash: me +EOF + ); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage missing colon + */ + public function testScalarInSequence() + { + Yaml::parse(<<<'EOF' +foo: + - bar +"missing colon" + foo: bar +EOF + ); + } + + /** + * > It is an error for two equal keys to appear in the same mapping node. + * > In such a case the YAML processor may continue, ignoring the second + * > `key: value` pair and issuing an appropriate warning. This strategy + * > preserves a consistent information model for one-pass and random access + * > applications. + * + * @see http://yaml.org/spec/1.2/spec.html#id2759572 + * @see http://yaml.org/spec/1.1/#id932806 + */ + public function testMappingDuplicateKeyBlock() + { + $input = <<<'EOD' +parent: + child: first + child: duplicate +parent: + child: duplicate + child: duplicate +EOD; + $expected = array( + 'parent' => array( + 'child' => 'first', + ), + ); + $this->assertSame($expected, Yaml::parse($input)); + } + + public function testMappingDuplicateKeyFlow() + { + $input = <<<'EOD' +parent: { child: first, child: duplicate } +parent: { child: duplicate, child: duplicate } +EOD; + $expected = array( + 'parent' => array( + 'child' => 'first', + ), + ); + $this->assertSame($expected, Yaml::parse($input)); + } + + public function testEmptyValue() + { + $input = <<<'EOF' +hash: +EOF; + + $this->assertEquals(array('hash' => null), Yaml::parse($input)); + } + + public function testCommentAtTheRootIndent() + { + $this->assertEquals(array( + 'services' => array( + 'app.foo_service' => array( + 'class' => 'Foo', + ), + 'app/bar_service' => array( + 'class' => 'Bar', + ), + ), + ), Yaml::parse(<<<'EOF' +# comment 1 +services: +# comment 2 + # comment 3 + app.foo_service: + class: Foo +# comment 4 + # comment 5 + app/bar_service: + class: Bar +EOF + )); + } + + public function testStringBlockWithComments() + { + $this->assertEquals(array('content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + ), Yaml::parse(<<<'EOF' +content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testFoldedStringBlockWithComments() + { + $this->assertEquals(array(array('content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + )), Yaml::parse(<<<'EOF' +- + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testNestedFoldedStringBlockWithComments() + { + $this->assertEquals(array(array( + 'title' => 'some title', + 'content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + )), Yaml::parse(<<<'EOF' +- + title: some title + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testReferenceResolvingInInlineStrings() + { + $this->assertEquals(array( + 'var' => 'var-value', + 'scalar' => 'var-value', + 'list' => array('var-value'), + 'list_in_list' => array(array('var-value')), + 'map_in_list' => array(array('key' => 'var-value')), + 'embedded_mapping' => array(array('key' => 'var-value')), + 'map' => array('key' => 'var-value'), + 'list_in_map' => array('key' => array('var-value')), + 'map_in_map' => array('foo' => array('bar' => 'var-value')), + ), Yaml::parse(<<<'EOF' +var: &var var-value +scalar: *var +list: [ *var ] +list_in_list: [[ *var ]] +map_in_list: [ { key: *var } ] +embedded_mapping: [ key: *var ] +map: { key: *var } +list_in_map: { key: [*var] } +map_in_map: { foo: { bar: *var } } +EOF + )); + } + + public function testYamlDirective() + { + $yaml = <<<'EOF' +%YAML 1.2 +--- +foo: 1 +bar: 2 +EOF; + $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml)); + } + + public function testFloatKeys() + { + $yaml = <<<'EOF' +foo: + 1.2: "bar" + 1.3: "baz" +EOF; + + $expected = array( + 'foo' => array( + '1.2' => 'bar', + '1.3' => 'baz', + ), + ); + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + /** + * @group legacy + * @expectedDeprecation Using a colon in the unquoted mapping value "bar: baz" in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throw ParseException in Symfony 3.0 + */ + public function testColonInMappingValueException() + { + $yaml = <<<'EOF' +foo: bar: baz +EOF; + + $this->parser->parse($yaml); + } + + public function testColonInMappingValueExceptionNotTriggeredByColonInComment() + { + $yaml = <<<'EOT' +foo: + bar: foobar # Note: a comment after a colon +EOT; + + $this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml)); + } + + /** + * @dataProvider getCommentLikeStringInScalarBlockData + */ + public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult) + { + $this->assertSame($expectedParserResult, $this->parser->parse($yaml)); + } + + public function getCommentLikeStringInScalarBlockData() + { + $tests = array(); + + $yaml = <<<'EOT' +pages: + - + title: some title + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOT; + $expected = array( + 'pages' => array( + array( + 'title' => 'some title', + 'content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + , + ), + ), + ); + $tests[] = array($yaml, $expected); + + $yaml = <<<'EOT' +test: | + foo + # bar + baz +collection: + - one: | + foo + # bar + baz + - two: | + foo + # bar + baz +EOT; + $expected = array( + 'test' => <<<'EOT' +foo +# bar +baz + +EOT + , + 'collection' => array( + array( + 'one' => <<<'EOT' +foo +# bar +baz + +EOT + , + ), + array( + 'two' => <<<'EOT' +foo +# bar +baz +EOT + , + ), + ), + ); + $tests[] = array($yaml, $expected); + + $yaml = <<<'EOT' +foo: + bar: + scalar-block: > + line1 + line2> + baz: +# comment + foobar: ~ +EOT; + $expected = array( + 'foo' => array( + 'bar' => array( + 'scalar-block' => "line1 line2>\n", + ), + 'baz' => array( + 'foobar' => null, + ), + ), + ); + $tests[] = array($yaml, $expected); + + $yaml = <<<'EOT' +a: + b: hello +# c: | +# first row +# second row + d: hello +EOT; + $expected = array( + 'a' => array( + 'b' => 'hello', + 'd' => 'hello', + ), + ); + $tests[] = array($yaml, $expected); + + return $tests; + } + + public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks() + { + $yaml = <<<'EOT' +test: > +

A heading

+ +
    +
  • a list
  • +
  • may be a good example
  • +
+EOT; + + $this->assertSame( + array( + 'test' => <<<'EOT' +

A heading

+
  • a list
  • may be a good example
+EOT + , + ), + $this->parser->parse($yaml) + ); + } + + public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks() + { + $yaml = <<<'EOT' +test: > +

A heading

+ +
    +
  • a list
  • +
  • may be a good example
  • +
+EOT; + + $this->assertSame( + array( + 'test' => <<<'EOT' +

A heading

+
    +
  • a list
  • +
  • may be a good example
  • +
+EOT + , + ), + $this->parser->parse($yaml) + ); + } + + /** + * @param $lineNumber + * @param $yaml + * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider + */ + public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml) + { + if (method_exists($this, 'expectException')) { + $this->expectException('\Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + } else { + $this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + } + + $this->parser->parse($yaml); + } + + public function parserThrowsExceptionWithCorrectLineNumberProvider() + { + return array( + array( + 4, + <<<'YAML' +foo: + - + # bar + bar: "123", +YAML + ), + array( + 5, + <<<'YAML' +foo: + - + # bar + # bar + bar: "123", +YAML + ), + array( + 8, + <<<'YAML' +foo: + - + # foobar + baz: 123 +bar: + - + # bar + bar: "123", +YAML + ), + array( + 10, + <<<'YAML' +foo: + - + # foobar + # foobar + baz: 123 +bar: + - + # bar + # bar + bar: "123", +YAML + ), + ); + } + + public function testCanParseVeryLongValue() + { + $longStringWithSpaces = str_repeat('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ', 20000); + $trickyVal = array('x' => $longStringWithSpaces); + + $yamlString = Yaml::dump($trickyVal); + $arrayFromYaml = $this->parser->parse($yamlString); + + $this->assertEquals($trickyVal, $arrayFromYaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Reference "foo" does not exist at line 2 + */ + public function testParserCleansUpReferencesBetweenRuns() + { + $yaml = <<parser->parse($yaml); + + $yaml = <<parser->parse($yaml); + } + + public function testParseReferencesOnMergeKeys() + { + $yaml = << array( + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'baz', + ), + 'mergekeyderef' => array( + 'd' => 'quux', + 'b' => 'bar', + 'c' => 'baz', + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Reference "foo" does not exist + */ + public function testEvalRefException() + { + $yaml = <<parser->parse($yaml); + } +} + +class B +{ + public $b = 'foo'; +} diff --git a/vendor/symfony/yaml/Tests/YamlTest.php b/vendor/symfony/yaml/Tests/YamlTest.php new file mode 100644 index 0000000..9e776ca --- /dev/null +++ b/vendor/symfony/yaml/Tests/YamlTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Yaml; + +class YamlTest extends TestCase +{ + public function testParseAndDump() + { + $data = array('lorem' => 'ipsum', 'dolor' => 'sit'); + $yml = Yaml::dump($data); + $parsed = Yaml::parse($yml); + $this->assertEquals($data, $parsed); + } + + /** + * @group legacy + */ + public function testLegacyParseFromFile() + { + $filename = __DIR__.'/Fixtures/index.yml'; + $contents = file_get_contents($filename); + $parsedByFilename = Yaml::parse($filename); + $parsedByContents = Yaml::parse($contents); + $this->assertEquals($parsedByFilename, $parsedByContents); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testZeroIndentationThrowsException() + { + Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, 0); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testNegativeIndentationThrowsException() + { + Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, -4); + } +} diff --git a/vendor/symfony/yaml/Unescaper.php b/vendor/symfony/yaml/Unescaper.php new file mode 100644 index 0000000..d0dbcfa --- /dev/null +++ b/vendor/symfony/yaml/Unescaper.php @@ -0,0 +1,156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +/** + * Unescaper encapsulates unescaping rules for single and double-quoted + * YAML strings. + * + * @author Matthew Lewinski + * + * @internal + */ +class Unescaper +{ + /** + * Parser and Inline assume UTF-8 encoding, so escaped Unicode characters + * must be converted to that encoding. + * + * @deprecated since version 2.5, to be removed in 3.0 + * + * @internal + */ + const ENCODING = 'UTF-8'; + + /** + * Regex fragment that matches an escaped character in a double quoted string. + */ + const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)'; + + /** + * Unescapes a single quoted string. + * + * @param string $value A single quoted string + * + * @return string The unescaped string + */ + public function unescapeSingleQuotedString($value) + { + return str_replace('\'\'', '\'', $value); + } + + /** + * Unescapes a double quoted string. + * + * @param string $value A double quoted string + * + * @return string The unescaped string + */ + public function unescapeDoubleQuotedString($value) + { + $self = $this; + $callback = function ($match) use ($self) { + return $self->unescapeCharacter($match[0]); + }; + + // evaluate the string + return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value); + } + + /** + * Unescapes a character that was found in a double-quoted string. + * + * @param string $value An escaped character + * + * @return string The unescaped character + * + * @internal This method is public to be usable as callback. It should not + * be used in user code. Should be changed in 3.0. + */ + public function unescapeCharacter($value) + { + switch ($value[1]) { + case '0': + return "\x0"; + case 'a': + return "\x7"; + case 'b': + return "\x8"; + case 't': + return "\t"; + case "\t": + return "\t"; + case 'n': + return "\n"; + case 'v': + return "\xB"; + case 'f': + return "\xC"; + case 'r': + return "\r"; + case 'e': + return "\x1B"; + case ' ': + return ' '; + case '"': + return '"'; + case '/': + return '/'; + case '\\': + return '\\'; + case 'N': + // U+0085 NEXT LINE + return "\xC2\x85"; + case '_': + // U+00A0 NO-BREAK SPACE + return "\xC2\xA0"; + case 'L': + // U+2028 LINE SEPARATOR + return "\xE2\x80\xA8"; + case 'P': + // U+2029 PARAGRAPH SEPARATOR + return "\xE2\x80\xA9"; + case 'x': + return self::utf8chr(hexdec(substr($value, 2, 2))); + case 'u': + return self::utf8chr(hexdec(substr($value, 2, 4))); + case 'U': + return self::utf8chr(hexdec(substr($value, 2, 8))); + default: + @trigger_error('Not escaping a backslash in a double-quoted string is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', E_USER_DEPRECATED); + + return $value; + } + } + + /** + * Get the UTF-8 character for the given code point. + * + * @param int $c The unicode code point + * + * @return string The corresponding UTF-8 character + */ + private static function utf8chr($c) + { + if (0x80 > $c %= 0x200000) { + return \chr($c); + } + if (0x800 > $c) { + return \chr(0xC0 | $c >> 6).\chr(0x80 | $c & 0x3F); + } + if (0x10000 > $c) { + return \chr(0xE0 | $c >> 12).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); + } + + return \chr(0xF0 | $c >> 18).\chr(0x80 | $c >> 12 & 0x3F).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); + } +} diff --git a/vendor/symfony/yaml/Yaml.php b/vendor/symfony/yaml/Yaml.php new file mode 100644 index 0000000..3f93cba --- /dev/null +++ b/vendor/symfony/yaml/Yaml.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Exception\ParseException; + +/** + * Yaml offers convenience methods to load and dump YAML. + * + * @author Fabien Potencier + */ +class Yaml +{ + /** + * Parses YAML into a PHP value. + * + * Usage: + * + * $array = Yaml::parse(file_get_contents('config.yml')); + * print_r($array); + * + * As this method accepts both plain strings and file names as an input, + * you must validate the input before calling this method. Passing a file + * as an input is a deprecated feature and will be removed in 3.0. + * + * Note: the ability to pass file names to the Yaml::parse method is deprecated since Symfony 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead. + * + * @param string $input Path to a YAML file or a string containing YAML + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * @param bool $objectForMap True if maps should return a stdClass instead of array() + * + * @return mixed The YAML converted to a PHP value + * + * @throws ParseException If the YAML is not valid + */ + public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false) + { + // if input is a file, process it + $file = ''; + if (false === strpos($input, "\n") && is_file($input)) { + @trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since Symfony 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED); + + if (false === is_readable($input)) { + throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input)); + } + + $file = $input; + $input = file_get_contents($file); + } + + $yaml = new Parser(); + + try { + return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport, $objectForMap); + } catch (ParseException $e) { + if ($file) { + $e->setParsedFile($file); + } + + throw $e; + } + } + + /** + * Dumps a PHP value to a YAML string. + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. + * + * @param mixed $input The PHP value + * @param int $inline The level where you switch to inline YAML + * @param int $indent The amount of spaces to use for indentation of nested nodes + * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise + * @param bool $objectSupport True if object support is enabled, false otherwise + * + * @return string A YAML string representing the original PHP value + */ + public static function dump($input, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false) + { + if ($indent < 1) { + throw new \InvalidArgumentException('The indentation must be greater than zero.'); + } + + $yaml = new Dumper(); + $yaml->setIndentation($indent); + + return $yaml->dump($input, $inline, 0, $exceptionOnInvalidType, $objectSupport); + } +} diff --git a/vendor/symfony/yaml/composer.json b/vendor/symfony/yaml/composer.json new file mode 100644 index 0000000..d073236 --- /dev/null +++ b/vendor/symfony/yaml/composer.json @@ -0,0 +1,34 @@ +{ + "name": "symfony/yaml", + "type": "library", + "description": "Symfony Yaml Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Yaml\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + } +} diff --git a/vendor/symfony/yaml/phpunit.xml.dist b/vendor/symfony/yaml/phpunit.xml.dist new file mode 100644 index 0000000..b5d4d91 --- /dev/null +++ b/vendor/symfony/yaml/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + +