├── .gitignore ├── protected ├── tmp │ └── index.html ├── .htaccess ├── controller │ ├── admin │ │ ├── BaseController.php │ │ ├── MainController.php │ │ └── LoginController.php │ ├── MainController.php │ ├── BaseController.php │ ├── OtherController.php │ └── DbController.php ├── model │ └── User.php ├── view │ ├── db │ │ ├── inner.html │ │ ├── delete.html │ │ ├── update.html │ │ ├── create.html │ │ ├── execute.html │ │ ├── query.html │ │ └── find.html │ ├── custom_page.html │ ├── layout.html │ ├── other_tpl.html │ └── main_index.html ├── config.php └── lib │ └── speed.php ├── index.php ├── i ├── img │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png ├── css │ └── bootstrap-responsive.min.css └── js │ ├── bootstrap.min.js │ └── jquery.min.js ├── .htaccess ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /protected/tmp/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /protected/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 数据表

2 | 3 | <{foreach $findall as $v}> 4 | 5 | 6 | 7 | 8 | <{/foreach}> 9 |
<{$v.uid}><{$v.username}>
-------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine On 3 | RewriteRule ^index\.php$ - [L] 4 | RewriteCond %{REQUEST_FILENAME} !-f 5 | RewriteCond %{REQUEST_FILENAME} !-d 6 | RewriteRule . index.php [L] 7 | -------------------------------------------------------------------------------- /protected/controller/admin/MainController.php: -------------------------------------------------------------------------------- 1 |

2 |

3 | <{if $whoami}> 4 | 接收到参数$whoami:“<{$whoami}>”。 5 | <{else if $whoami == "yes"}> 6 | whoami = yes 7 | <{else}> 8 | 没有参数哦 9 | <{/if}> 10 |

11 |

12 | 本页面的模板是通过display()输出,其实如果模板名称是“控制器名_方法名.html”,那么也可以不写display(),只要有模板存在就自动输出了。 13 |

14 |

15 | 返回到Default/index 16 |

-------------------------------------------------------------------------------- /protected/view/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello SpeedPHP 6 | 7 | 8 | 9 | 10 | 11 |
12 | <{include file=$__template_file}> 13 |
14 | 15 | -------------------------------------------------------------------------------- /protected/view/db/delete.html: -------------------------------------------------------------------------------- 1 |

2 |

删除数据,影响行数是:<{$result}>

3 |

代码:

4 |
 5 | $user = new User();
 6 | // 删除uid为3的行
 7 | $uid = 3;
 8 | // 与insert,update等类似,delete也是输入条件数组
 9 | $this->result = $user->delete(array(
10 | 	"uid" => $uid
11 | ));
12 | // delete也是返回影响行数,没有匹配的结果会返回0
13 | 
14 | <{include file="db/inner.html"}> 15 |

16 | 返回到main/index 17 |

-------------------------------------------------------------------------------- /protected/view/db/update.html: -------------------------------------------------------------------------------- 1 |

2 |

修改数据,影响行数是:<{$result}>

3 |

代码:

4 |
 5 | $user = new User();
 6 | // 修改uid=2的名字为whoami
 7 | $result = $user->update(array(
 8 | 	"uid" => "2" // 条件
 9 | ), array(
10 | 	"username" => "whoami" // 修改的内容,键是字段名
11 | ));
12 | // update返回结果是影响行数,返回0证明查询不到对应条件的数据
13 | 
14 | <{include file="db/inner.html"}> 15 |

16 | 返回到main/index 17 |

-------------------------------------------------------------------------------- /protected/controller/MainController.php: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 这里是多维数据的演示哦! 5 |

20 |

21 |

22 | 返回到Main/index 23 |

-------------------------------------------------------------------------------- /protected/view/db/create.html: -------------------------------------------------------------------------------- 1 |

2 |

3 | <{if $newid}> 4 | 插入一行数据,新增的uid是:<{$newid}> 5 | <{else}> 6 | 插入数据失败! 7 | <{/if}> 8 |

9 |

代码:

10 |
11 | // 准备数据,一个“字段名”对应“值”的数组
12 | $data = array(
13 | 	"username" => "user".mt_rand(2,100),
14 | );
15 | $user = new User();
16 | // create返回的是最新插入的自增主键的值
17 | $this->newid = $user->create($data);
18 | 
19 | <{include file="db/inner.html"}> 20 |

21 | 返回到main/index 22 |

-------------------------------------------------------------------------------- /protected/view/db/execute.html: -------------------------------------------------------------------------------- 1 |

2 |

使用SQL语句删除数据,影响行数是:<{$result}>

3 |

代码:

4 |
 5 | $user = new User();
 6 | $username = "whoami";
 7 | // 准备SQL,要删除username是“whoami”的家伙
 8 | $sql = "DELETE * FROM test_user WHERE username = :username";
 9 | 
10 | // 同query,execute第一个参数是SQL语句,第二个参数是绑定参数的列表
11 | $this->result = $user->execute($sql, array(
12 | 		":username" => $username, // 注意这种绑定参数的做法,可以防止SQL注入
13 | ));
14 | // execute返回参数和create等相同,即是影响行数,为0则证明没有做任何的修改
15 | 
16 | <{include file="db/inner.html"}> 17 |

18 | 返回到main/index 19 |

-------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 新版的SpeedPHP框架speed.php 2 | 3 | 已经很快了,还能不能更快? 4 | 5 | 已经很轻量级了,还能不能更轻? 6 | 7 | 已经很容易学了,还能不能更容易? 8 | 9 | PHP框架真的要用尽Java的23种设计模式,才能开发项目? 10 | 11 | **所以我们有了新的SpeedPHP框架:** 12 | 13 | 1. 核心代码不到500行,简约易学但功能强大,速度飞快。 14 | 2. 易于使用的伪静态路由规则,构造各种各样的地址 15 | 3. 大部分的约定配置,更专注于业务功能 16 | 4. 直接使用new语法代替spClass,让代码提示更智能。 17 | 5. 适应PHP5.2以上版本的语法,调试模式打开STRICT语法要求,代码更健壮 18 | 6. 支持modules多应用开发架构 19 | 7. 增加BaseController父类,方便全局操作。 20 | 8. 新模板引擎支持Smarty日常全部语法,还有布局、自动输出等方便功能。 21 | 9. 默认支持MySQL多库访问、读写分离、分页,按需连接使得数据库更轻更快 22 | 10. 强安全策略,自动防止跨站脚本、SQL注入攻击等。 23 | 24 | **已经正式发布,望各位不吝指教。** 25 | 26 | 新版代码;https://github.com/SpeedPHP/speed 27 | 28 | 下载地址:https://github.com/SpeedPHP/speed/archive/master.zip 29 | 30 | 使用方法:https://github.com/SpeedPHP/manual/blob/master/README.md 31 | 32 | 新版求助和反馈:http://www.speedphp.com/forum-26-1.html 33 | 34 | -------------------------------------------------------------------------------- /protected/view/db/query.html: -------------------------------------------------------------------------------- 1 |

2 |

SQL查询query

3 |

代码:

4 |
 5 | $user = new User();
 6 | $uid = 3;
 7 | // 准备SQL,查询uid大于3的
 8 | $sql = "SELECT * FROM test_user WHERE uid > :uid";
 9 | 
10 | // query第一个参数是SQL语句,第二个参数是绑定参数的列表
11 | $this->findall = $user->query($sql, array(
12 | 	":uid" => $uid, // 注意这种绑定参数的做法,可以防止SQL注入
13 | ));
14 | 
15 |

结果:多维数组

16 | 17 | 18 | 19 | 20 | 21 | <{foreach $findall as $k => $v}> 22 | 23 | 24 | 34 | 35 | <{/foreach}> 36 |
<{$k}> 25 | 26 | <{foreach $v as $vk => $vv}> 27 | 28 | 29 | 30 | 31 | <{/foreach}> 32 |
<{$vk}><{$vv}>
33 |
37 |

38 | 返回到main/index 39 |

-------------------------------------------------------------------------------- /protected/controller/BaseController.php: -------------------------------------------------------------------------------- 1 | "; 12 | exit; 13 | } 14 | function jump($url, $delay = 0){ 15 | echo ""; 16 | exit; 17 | } 18 | 19 | //public static function err404($module, $controller, $action, $msg){ 20 | // header("HTTP/1.0 404 Not Found"); 21 | // exit; 22 | //} 23 | } -------------------------------------------------------------------------------- /protected/config.php: -------------------------------------------------------------------------------- 1 | array( 8 | 'admin/index.html' => 'admin/main/index', 9 | 'admin/_.html' => 'admin//', 10 | '//' => '//', 11 | '/' => '/', 12 | '/' => 'main/index', 13 | ), 14 | ); 15 | 16 | $domain = array( 17 | "localhost" => array( // 调试配置 18 | 'debug' => 1, 19 | 'mysql' => array( 20 | 21 | 'MYSQL_HOST' => 'localhost', 22 | 'MYSQL_PORT' => '3306', 23 | 'MYSQL_USER' => 'root', 24 | 'MYSQL_DB' => 'test', 25 | 'MYSQL_PASS' => '', 26 | 'MYSQL_CHARSET' => 'utf8', 27 | 28 | ), 29 | ), 30 | "speedphp.com" => array( //线上配置 31 | 'debug' => 0, 32 | 'mysql' => array(), 33 | ), 34 | ); 35 | // 为了避免开始使用时会不正确配置域名导致程序错误,加入判断 36 | if(empty($domain[$_SERVER["HTTP_HOST"]])) die("配置域名不正确,请确认".$_SERVER["HTTP_HOST"]."的配置是否存在!"); 37 | 38 | return $domain[$_SERVER["HTTP_HOST"]] + $config; 39 | -------------------------------------------------------------------------------- /protected/view/db/find.html: -------------------------------------------------------------------------------- 1 |

2 |

SQL查找query

3 |

代码:

4 |
 5 | $user = new User();
 6 | // 先查一条,uid为2的
 7 | $this->findone = $user->find(array("uid"=>"2"));
 8 | 
 9 | // 查全部,用findAll
10 | // findAll( $conditions=array(), $order=null, $field='*',  $limit=null )
11 | // findAll参数:$conditions数组形式的条件(同find),$field指定字段(默认是*),
12 | // $order是排序(如 “uid DESC”), $limit是限定条数(如“3,5”,第三条开始取五条)
13 | $this->findall = $user->findAll();
14 | 
15 |

结果(find):一位数组

16 | <{if !empty($findone)}> 17 | 18 | 19 | 20 | 21 | 22 | <{foreach $findone as $k => $v}> 23 | 24 | 25 | 26 | 27 | <{/foreach}> 28 |
<{$k}><{$v}>
29 | <{else}> 30 |

没有结果!

31 | <{/if}> 32 |

结果(findAll):多维数组

33 | <{if !empty($findall)}> 34 | 35 | 36 | 37 | 38 | 39 | <{foreach $findall as $k => $v}> 40 | 41 | 42 | 52 | 53 | <{/foreach}> 54 |
<{$k}> 43 | 44 | <{foreach $v as $vk => $vv}> 45 | 46 | 47 | 48 | 49 | <{/foreach}> 50 |
<{$vk}><{$vv}>
51 |
55 | <{else}> 56 |

没有结果!

57 | <{/if}> 58 |

59 | 返回到main/index 60 |

-------------------------------------------------------------------------------- /protected/controller/OtherController.php: -------------------------------------------------------------------------------- 1 | "静夜思", 6 | "code" => array( 7 | "one" => "床前明月光", 8 | "two" => "疑是地上霜", 9 | "three" => "举头望明月", 10 | "four" => "低头思故乡" 11 | ), 12 | "author" => "李白" 13 | ); 14 | // 默认入口 15 | function actionIndex(){ 16 | echo "这里是OtherController/actionIndex,"; 17 | $backurl = url("main", "index"); 18 | echo "请返回MainController/actionIndex"; 19 | } 20 | 21 | // 显示JSON格式的数据,其实只是显示不一样而已 22 | function actionJson(){ 23 | echo json_encode($this->fakedata); 24 | } 25 | 26 | // 接收提交参数,这里是GET方式的,直接用PHP的$_GET来接收 27 | function actionVal(){ 28 | // 用$this->的方法将值传递到模板中使用 29 | $this->whoami = $_GET["whoami"]; 30 | // 下面是模板输出了,模板输出可以用display方法 31 | $this->display("custom_page.html"); 32 | } 33 | 34 | // 模板显示,foreach循环,多维数据的演示 35 | function actionTpl(){ 36 | $this->data = $this->fakedata; 37 | // 这里模板输出就是不用display方法,因为模板名字是other_tpl.html(控制器名_方法名.html) 38 | } 39 | 40 | // 演示dump函数,这是最常用的工具哦 41 | function actionDump(){ 42 | echo "演示dump函数,这是最常用的工具哦"; 43 | 44 | dump($this->fakedata); 45 | dump($_POST); // 在提交表单的时候,先看看提交上来是什么 46 | dump($_GET); 47 | 48 | $backurl = url("main", "index"); 49 | echo "请返回MainController/actionIndex"; 50 | } 51 | } -------------------------------------------------------------------------------- /protected/controller/DbController.php: -------------------------------------------------------------------------------- 1 | "user".mt_rand(2,100), 8 | ); 9 | 10 | $user = new User(); 11 | 12 | // create返回的是最新插入的自增主键的值 13 | $this->newid = $user->create($data); 14 | 15 | 16 | $this->findall = $user->findAll(); 17 | $this->display("db/create.html"); 18 | } 19 | 20 | // 修改update 21 | function actionUpdate(){ 22 | $user = new User(); 23 | // 修改uid=2的名字为whoami 24 | $this->result = $user->update(array( 25 | "uid" => "2" // 条件 26 | ), array( 27 | "username" => "whoami" // 修改的内容,键是字段名 28 | )); 29 | // update返回结果是影响行数,返回0证明查询不到对应条件的数据 30 | 31 | $this->findall = $user->findAll(); 32 | $this->display("db/update.html"); 33 | } 34 | 35 | // 删除delete 36 | function actionDelete(){ 37 | $user = new User(); 38 | // 删除uid为3的行 39 | $uid = 3; 40 | // 与insert,update等类似,delete也是输入条件数组 41 | $this->result = $user->delete(array( 42 | "uid" => $uid 43 | )); 44 | // delete也是返回影响行数,没有匹配的结果会返回0 45 | 46 | $this->findall = $user->findAll(); 47 | $this->display("db/delete.html"); 48 | } 49 | 50 | // 查找findAll/find 51 | function actionFind(){ 52 | $user = new User(); 53 | // 先查一条,uid为2的 54 | $this->findone = $user->find(array("uid"=>"2")); 55 | 56 | // 查全部,用findAll 57 | // findAll( $conditions=array(), $order=null, $field='*', $limit=null ) 58 | // findAll参数:$conditions数组形式的条件(同find),$field指定字段(默认是*), 59 | // $order是排序(如 “uid DESC”), $limit是限定条数(如“3,5”,第三条开始取五条) 60 | $this->findall = $user->findAll(); 61 | 62 | $this->display("db/find.html"); 63 | } 64 | 65 | // SQL查询query 66 | function actionQuery(){ 67 | $user = new User(); 68 | $uid = 3; 69 | // 准备SQL,查询uid大于3的 70 | $sql = "SELECT * FROM test_user WHERE uid > :uid"; 71 | 72 | // query第一个参数是SQL语句,第二个参数是绑定参数的列表 73 | $this->findall = $user->query($sql, array( 74 | ":uid" => $uid, // 注意这种绑定参数的做法,可以防止SQL注入 75 | )); 76 | $this->display("db/query.html"); 77 | } 78 | 79 | // SQL执行execute 80 | function actionExecute(){ 81 | $user = new User(); 82 | $username = "whoami"; 83 | // 准备SQL,要删除username是“whoami”的家伙 84 | $sql = "DELETE FROM test_user WHERE username = :username"; 85 | 86 | // 同query,execute第一个参数是SQL语句,第二个参数是绑定参数的列表 87 | $this->result = $user->execute($sql, array( 88 | ":username" => $username, // 注意这种绑定参数的做法,可以防止SQL注入 89 | )); 90 | // execute返回参数和create等相同,即是影响行数,为0则证明没有做任何的修改 91 | 92 | 93 | $this->findall = $user->findAll(); 94 | $this->display("db/execute.html"); 95 | } 96 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | SpeedPHP框架是遵循BSD许可证发布的开源软件 2 | 3 | BSD许可证参考 http://www.opensource.org/licenses/bsd-license.php(英文) 4 | 维基中文对BSD许可证的解释:http://zh.wikipedia.org/wiki/BSD许可证 5 | 6 | 使用限制(通俗版) 7 | 8 | 简单而言,SpeedPHP框架可用于商业用途以及自由使用(修改,再发布),仅有以下两项使用限制: 9 | 在使用SpeedPHP框架的系统源代码中,需要附带上SpeedPHP的LICENSE说明。 10 | 需要使用 SpeedPHP框架 / speedphp.com 字样作商业推广时,务必告知本站。 11 | 12 | BSD开源协议的使用 13 | 14 | BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。 15 | 16 | 但”为所欲为”的前提当你发布使用了BSD协议的代码,或则以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件: 17 | 18 | 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。 19 | 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。 20 | 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。 21 | 22 | BSD 代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。 23 | 24 | SpeedPHP开源协议 25 | 26 | Copyright (c) 2010, speedphp.com 27 | Redistribution and use in source and binary forms, with or without 28 | modification, are permitted provided that the following conditions are met: 29 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 30 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 31 | Neither the name of the speedphp.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 32 | THIS SOFTWARE IS PROVIDED BY THE speedphp.com AND CONTRIBUTORS "AS IS" AND ANY 33 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 35 | DISCLAIMED. IN NO EVENT SHALL THE speedphp.com AND CONTRIBUTORS BE LIABLE FOR ANY 36 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 37 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 38 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 39 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | 著作权由speedphp.com所有。 43 | 这份授权条款,在使用者符合以下三条件的情形下,授予使用者使用及再散播本 44 | 软件包装原始码及二进位可执行形式的权利,无论此包装是否经改作皆然: 45 | 对于本软件源代码的再散播,必须保留上述的版权宣告、此三条件表列,以及下述的免责声明。 46 | 对于本套件二进位可执行形式的再散播,必须连带以文件以及/或者其他附于散播包装中的媒介方式,重制上述之版权宣告、此三条件表列,以及下述的免责声明。 47 | 未获事前取得书面许可,不得使用speedphp.com或本软件贡献者之名称,来为本软件之衍生物做任何表示支持、认可或推广、促销之行为。 48 | 免责声明:本软件是由speedphp.com及本软件之贡献者以现状("as is")提供, 49 | 本软件包装不负任何明示或默示之担保责任,包括但不限于就适售性以及特定目 50 | 的的适用性为默示性担保。speedphp.com及本软件之贡献者,无论任何条件、 51 | 无论成因或任何责任主义、无论此责任为因合约关系、无过失责任主义或因非违 52 | 约之侵权(包括过失或其他原因等)而起,对于任何因使用本软件包装所产生的 53 | 任何直接性、间接性、偶发性、特殊性、惩罚性或任何结果的损害(包括但不限 54 | 于替代商品或劳务之购用、使用损失、资料损失、利益损失、业务中断等等), 55 | 不负任何责任,即在该种使用已获事前告知可能会造成此类损害的情形下亦然。 -------------------------------------------------------------------------------- /protected/view/main_index.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Hello SpeedPHP!

5 |
6 |
7 |
8 |

提交表单,通过HTML的form标签

9 |
10 |
11 | 表单项 12 |
14 | 15 |
16 |
17 | $(".model").model; 18 | <{$nowtime = date("Y-m-d H:i:s")}> 19 |

当前时间是:<{$nowtime}>

20 |
21 |
22 |

进入其他控制器和方法(action)

23 | 30 |

进入Module Admin(多应用开发):

31 | 37 |
38 | 39 | 如果设置了URL重写,请注意观察以上链接。 40 |
41 | 42 |
43 |
44 |
45 |
46 |
47 |

数据库学习准备:

48 |

1. 首先得要配置好数据库链接信息及建表:

49 | 50 |

配置中是:(config.php文件)

51 | 52 |
53 | 'mysql' => array(
54 | 	'MYSQL_HOST' => '', // 数据库IP地址
55 | 	'MYSQL_PORT' => '', // 数据库端口,如3306
56 | 	'MYSQL_USER' => '', // 用户名
57 | 	'MYSQL_DB'   => '', // 数据库库名
58 | 	'MYSQL_PASS' => '', // 数据库密码
59 | 	'MYSQL_CHARSET' => 'utf8', // 一般不用修改
60 | ),
61 | 
62 |

建表,如我们例子是: test_user

63 |
64 | CREATE TABLE `test_user` (
65 |   `uid` int(11) NOT NULL AUTO_INCREMENT,
66 |   `username` varchar(20) DEFAULT NULL,
67 |   PRIMARY KEY (`uid`)
68 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
69 | 
70 |

2. 在model目录建立模型类,基本来说每个表建议建立一个模型类,方便扩展。

71 | 72 |

如model/User.php内容如下:

73 |
74 | class User extends Model{
75 | 	var $table_name = "test_user";
76 | }
77 | 
78 |

使用MySQL数据库的模型类务必要继承与Model类

79 |

完成以上操作后,请参考右边的教程。---->>>>>

80 |
81 |
82 |

数据操作基础:

83 | 91 | 92 |
93 |
94 |
95 |
96 |
97 | -------------------------------------------------------------------------------- /i/css/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.2.1 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} 10 | -------------------------------------------------------------------------------- /protected/lib/speed.php: -------------------------------------------------------------------------------- 1 | $mapper){ 23 | if('/' == $rule)$rule = '/$'; 24 | if(0!==stripos($rule, $GLOBALS['http_scheme'])) 25 | $rule = $GLOBALS['http_scheme'].$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/\\') .'/'.$rule; 26 | $rule = '/'.str_ireplace(array('\\\\', $GLOBALS['http_scheme'], '/', '<', '>', '.'), 27 | array('', '', '\/', '(?P<', '>[-\w]+)', '\.'), $rule).'/i'; 28 | if(preg_match($rule, $GLOBALS['http_scheme'].$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], $matchs)){ 29 | $route = explode("/", $mapper); 30 | 31 | if(isset($route[2])){ 32 | list($_GET['m'], $_GET['c'], $_GET['a']) = $route; 33 | }else{ 34 | list($_GET['c'], $_GET['a']) = $route; 35 | } 36 | foreach($matchs as $matchkey => $matchval){ 37 | if(!is_int($matchkey))$_GET[$matchkey] = $matchval; 38 | } 39 | break; 40 | } 41 | } 42 | } 43 | 44 | $_REQUEST = array_merge($_GET, $_POST, $_COOKIE); 45 | $__module = isset($_REQUEST['m']) ? strtolower($_REQUEST['m']) : ''; 46 | $__controller = isset($_REQUEST['c']) ? strtolower($_REQUEST['c']) : 'main'; 47 | $__action = isset($_REQUEST['a']) ? strtolower($_REQUEST['a']) : 'index'; 48 | 49 | spl_autoload_register('inner_autoload'); 50 | function inner_autoload($class){ 51 | GLOBAL $__module; 52 | $class = str_replace("\\","/",$class); 53 | foreach(array('model', 'include', 'controller'.(empty($__module)?'':DS.$__module)) as $dir){ 54 | $file = APP_DIR.DS.'protected'.DS.$dir.DS.$class.'.php'; 55 | if(file_exists($file)){ 56 | include $file; 57 | return; 58 | } 59 | $phpfiles = glob(APP_DIR.DS.'protected'.DS.$dir.DS.'*.php'); 60 | if(is_array($phpfiles)){ 61 | $lowerfile = strtolower($file); 62 | foreach($phpfiles as $file){ 63 | if(strtolower($file) === $lowerfile){ 64 | include $file; 65 | return; 66 | } 67 | } 68 | } 69 | } 70 | } 71 | 72 | $controller_name = $__controller.'Controller'; 73 | $action_name = 'action'.$__action; 74 | 75 | if(!empty($__module)){ 76 | if(!is_available_classname($__module))_err_router("Err: Module '$__module' is not correct!"); 77 | if(!is_dir(APP_DIR.DS.'protected'.DS.'controller'.DS.$__module))_err_router("Err: Module '$__module' is not exists!"); 78 | } 79 | if(!is_available_classname($__controller))_err_router("Err: Controller '$controller_name' is not correct!"); 80 | if(!class_exists($controller_name, true))_err_router("Err: Controller '$controller_name' is not exists!"); 81 | if(!method_exists($controller_name, $action_name))_err_router("Err: Method '$action_name' of '$controller_name' is not exists!"); 82 | 83 | $controller_obj = new $controller_name(); 84 | $controller_obj->$action_name(); 85 | 86 | if($controller_obj->_auto_display){ 87 | $auto_tpl_name = (empty($__module) ? '' : $__module.DS).$__controller.'_'.$__action.'.html'; 88 | if(file_exists(APP_DIR.DS.'protected'.DS.'view'.DS.$auto_tpl_name))$controller_obj->display($auto_tpl_name); 89 | } 90 | 91 | function url($c = 'main', $a = 'index', $param = array()){ 92 | if(is_array($c)){ 93 | $param = $c; 94 | if(isset($param['m'])) { 95 | $c = $param['m'] . '/' . $param['c']; 96 | unset($param['m'], $param['c']); 97 | } else { 98 | $c = $param['c']; unset($param['c']); 99 | } 100 | $a = $param['a']; unset($param['a']); 101 | } 102 | $params = empty($param) ? '' : '&'.http_build_query($param); 103 | if(strpos($c, '/') !== false){ 104 | list($m, $c) = explode('/', $c); 105 | $route = "$m/$c/$a"; 106 | $url = $_SERVER["SCRIPT_NAME"]."?m=$m&c=$c&a=$a$params"; 107 | }else{ 108 | $m = ''; 109 | $route = "$c/$a"; 110 | $url = $_SERVER["SCRIPT_NAME"]."?c=$c&a=$a$params"; 111 | } 112 | 113 | if(!empty($GLOBALS['rewrite'])){ 114 | if(!isset($GLOBALS['url_array_instances'][$url])){ 115 | foreach($GLOBALS['rewrite'] as $rule => $mapper){ 116 | $mapper = '/^'.str_ireplace(array('/', '', '', ''), array('\/', '(?P\w+)', '(?P\w+)', '(?P\w+)'), $mapper).'/i'; 117 | if(preg_match($mapper, $route, $matchs)){ 118 | $rule = str_ireplace(array('', '', ''), array($a, $c, $m), $rule); 119 | $match_param_count = 0; 120 | $param_in_rule = substr_count($rule, '<'); 121 | if(!empty($param) && $param_in_rule > 0){ 122 | foreach($param as $param_key => $param_v){ 123 | if(false !== stripos($rule, '<'.$param_key.'>'))$match_param_count++; 124 | } 125 | } 126 | if($param_in_rule == $match_param_count){ 127 | $GLOBALS['url_array_instances'][$url] = $rule; 128 | if(!empty($param)){ 129 | $_args = array(); 130 | foreach($param as $arg_key => $arg){ 131 | $count = 0; 132 | $GLOBALS['url_array_instances'][$url] = str_ireplace('<'.$arg_key.'>', $arg, $GLOBALS['url_array_instances'][$url], $count); 133 | if(!$count)$_args[$arg_key] = $arg; 134 | } 135 | $GLOBALS['url_array_instances'][$url] = preg_replace('/<\w+>/', '', $GLOBALS['url_array_instances'][$url]). (!empty($_args) ? '?'.http_build_query($_args) : ''); 136 | } 137 | 138 | if(0!==stripos($GLOBALS['url_array_instances'][$url], $GLOBALS['http_scheme'])){ 139 | $GLOBALS['url_array_instances'][$url] = $GLOBALS['http_scheme'].$_SERVER['HTTP_HOST'].rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/\\') .'/'.$GLOBALS['url_array_instances'][$url]; 140 | } 141 | return $GLOBALS['url_array_instances'][$url]; 142 | } 143 | } 144 | } 145 | return isset($GLOBALS['url_array_instances'][$url]) ? $GLOBALS['url_array_instances'][$url] : $url; 146 | } 147 | return $GLOBALS['url_array_instances'][$url]; 148 | } 149 | return $url; 150 | } 151 | 152 | function dump($var, $exit = false){ 153 | $output = print_r($var, true); 154 | if(!$GLOBALS['debug'])return error_log(str_replace("\n", '', $output)); 155 | echo "
" .htmlspecialchars($output). "
"; 156 | if($exit) exit(); 157 | } 158 | 159 | function is_available_classname($name){ 160 | return preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $name); 161 | } 162 | 163 | function arg($name = null, $default = null, $trim = false) { 164 | if($name){ 165 | if(!isset($_REQUEST[$name]))return $default; 166 | $arg = $_REQUEST[$name]; 167 | if($trim)$arg = trim($arg); 168 | }else{ 169 | $arg = $_REQUEST; 170 | } 171 | return $arg; 172 | } 173 | 174 | class Controller{ 175 | public $layout; 176 | public $_auto_display = true; 177 | protected $_v; 178 | private $_data = array(); 179 | 180 | public function init(){} 181 | public function __construct(){$this->init();} 182 | public function &__get($name){return $this->_data[$name];} 183 | public function __set($name, $value){$this->_data[$name] = $value;} 184 | 185 | public function display($tpl_name, $return = false){ 186 | if(!$this->_v){ 187 | $compile_dir = isset($GLOBALS['view']['compile_dir']) ? $GLOBALS['view']['compile_dir'] : APP_DIR.DS.'protected'.DS.'tmp'; 188 | $this->_v = new View(APP_DIR.DS.'protected'.DS.'view', $compile_dir); 189 | } 190 | $this->_v->assign(get_object_vars($this)); 191 | $this->_v->assign($this->_data); 192 | if($this->layout){ 193 | $this->_v->assign('__template_file', $tpl_name); 194 | $tpl_name = $this->layout; 195 | } 196 | $this->_auto_display = false; 197 | 198 | if($return){ 199 | return $this->_v->render($tpl_name); 200 | }else{ 201 | echo $this->_v->render($tpl_name); 202 | } 203 | } 204 | } 205 | 206 | class Model{ 207 | public $page; 208 | public $table_name; 209 | 210 | private $sql = array(); 211 | 212 | public function __construct($table_name = null){if($table_name)$this->table_name = $table_name;} 213 | public function findAll($conditions = array(), $sort = null, $fields = '*', $limit = null){ 214 | $sort = !empty($sort) ? ' ORDER BY '.$sort : ''; 215 | $conditions = $this->_where($conditions); 216 | 217 | $sql = ' FROM '.$this->table_name.$conditions["_where"]; 218 | if(is_array($limit)){ 219 | $total = $this->query('SELECT COUNT(*) as M_COUNTER '.$sql, $conditions["_bindParams"]); 220 | if(!isset($total[0]['M_COUNTER']) || $total[0]['M_COUNTER'] == 0)return array(); 221 | 222 | $limit = $limit + array(1, 10, 10); 223 | $limit = $this->pager($limit[0], $limit[1], $limit[2], $total[0]['M_COUNTER']); 224 | $limit = empty($limit) ? '' : ' LIMIT '.$limit['offset'].','.$limit['limit']; 225 | }else{ 226 | $limit = !empty($limit) ? ' LIMIT '.$limit : ''; 227 | } 228 | return $this->query('SELECT '. $fields . $sql . $sort . $limit, $conditions["_bindParams"]); 229 | } 230 | 231 | public function find($conditions = array(), $sort = null, $fields = '*'){ 232 | $res = $this->findAll($conditions, $sort, $fields, 1); 233 | return !empty($res) ? array_pop($res) : false; 234 | } 235 | 236 | public function update($conditions, $row){ 237 | $values = array(); 238 | foreach ($row as $k=>$v){ 239 | $values[":M_UPDATE_".$k] = $v; 240 | $setstr[] = "`{$k}` = ".":M_UPDATE_".$k; 241 | } 242 | $conditions = $this->_where( $conditions ); 243 | return $this->execute("UPDATE ".$this->table_name." SET ".implode(', ', $setstr).$conditions["_where"], $conditions["_bindParams"] + $values); 244 | } 245 | 246 | public function incr($conditions, $field, $optval = 1){ 247 | $conditions = $this->_where( $conditions ); 248 | return $this->execute("UPDATE ".$this->table_name." SET `{$field}` = `{$field}` + :M_INCR_VAL ".$conditions["_where"], $conditions["_bindParams"] + array(":M_INCR_VAL" => $optval)); 249 | } 250 | public function decr($conditions, $field, $optval = 1){return $this->incr($conditions, $field, - $optval);} 251 | 252 | public function delete($conditions){ 253 | $conditions = $this->_where( $conditions ); 254 | return $this->execute("DELETE FROM ".$this->table_name.$conditions["_where"], $conditions["_bindParams"]); 255 | } 256 | 257 | public function create($row){ 258 | $values = array(); 259 | foreach($row as $k=>$v){ 260 | $keys[] = "`{$k}`"; $values[":".$k] = $v; $marks[] = ":".$k; 261 | } 262 | $this->execute("INSERT INTO ".$this->table_name." (".implode(', ', $keys).") VALUES (".implode(', ', $marks).")", $values); 263 | return $this->dbInstance($GLOBALS['mysql'], 'master')->lastInsertId(); 264 | } 265 | 266 | public function findCount($conditions){ 267 | $conditions = $this->_where( $conditions ); 268 | $count = $this->query("SELECT COUNT(*) AS M_COUNTER FROM ".$this->table_name.$conditions["_where"], $conditions["_bindParams"]); 269 | return isset($count[0]['M_COUNTER']) && $count[0]['M_COUNTER'] ? $count[0]['M_COUNTER'] : 0; 270 | } 271 | 272 | public function dumpSql(){return $this->sql;} 273 | 274 | public function pager($page, $pageSize = 10, $scope = 10, $total){ 275 | $this->page = null; 276 | if($total > $pageSize){ 277 | $total_page = ceil($total / $pageSize); 278 | $page = min(intval(max($page, 1)), $total_page); 279 | $this->page = array( 280 | 'total_count' => $total, 281 | 'page_size' => $pageSize, 282 | 'total_page' => $total_page, 283 | 'first_page' => 1, 284 | 'prev_page' => ( ( 1 == $page ) ? 1 : ($page - 1) ), 285 | 'next_page' => ( ( $page == $total_page ) ? $total_page : ($page + 1)), 286 | 'last_page' => $total_page, 287 | 'current_page'=> $page, 288 | 'all_pages' => array(), 289 | 'offset' => ($page - 1) * $pageSize, 290 | 'limit' => $pageSize, 291 | ); 292 | $scope = (int)$scope; 293 | if($total_page <= $scope ){ 294 | $this->page['all_pages'] = range(1, $total_page); 295 | }elseif( $page <= $scope/2) { 296 | $this->page['all_pages'] = range(1, $scope); 297 | }elseif( $page <= $total_page - $scope/2 ){ 298 | $right = $page + (int)($scope/2); 299 | $this->page['all_pages'] = range($right-$scope+1, $right); 300 | }else{ 301 | $this->page['all_pages'] = range($total_page-$scope+1, $total_page); 302 | } 303 | } 304 | return $this->page; 305 | } 306 | 307 | public function query($sql, $params = array()){return $this->execute($sql, $params, true);} 308 | public function execute($sql, $params = array(), $readonly = false){ 309 | $this->sql[] = $sql; 310 | 311 | if($readonly && !empty($GLOBALS['mysql']['MYSQL_SLAVE'])){ 312 | $slave_key = array_rand($GLOBALS['mysql']['MYSQL_SLAVE']); 313 | $sth = $this->dbInstance($GLOBALS['mysql']['MYSQL_SLAVE'][$slave_key], 'slave_'.$slave_key)->prepare($sql); 314 | }else{ 315 | $sth = $this->dbInstance($GLOBALS['mysql'], 'master')->prepare($sql); 316 | } 317 | 318 | if(is_array($params) && !empty($params)){ 319 | foreach($params as $k => &$v){ 320 | if(is_int($v)){ 321 | $data_type = PDO::PARAM_INT; 322 | }elseif(is_bool($v)){ 323 | $data_type = PDO::PARAM_BOOL; 324 | }elseif(is_null($v)){ 325 | $data_type = PDO::PARAM_NULL; 326 | }else{ 327 | $data_type = PDO::PARAM_STR; 328 | } 329 | $sth->bindParam($k, $v, $data_type); 330 | } 331 | } 332 | 333 | if($sth->execute())return $readonly ? $sth->fetchAll(PDO::FETCH_ASSOC) : $sth->rowCount(); 334 | $err = $sth->errorInfo(); 335 | err('Database SQL: "' . $sql. '", ErrorInfo: '. $err[2], 1); 336 | } 337 | 338 | public function dbInstance($db_config, $db_config_key, $force_replace = false){ 339 | if($force_replace || empty($GLOBALS['mysql_instances'][$db_config_key])){ 340 | try { 341 | if(!class_exists("PDO") || !in_array("mysql",PDO::getAvailableDrivers(), true)){ 342 | err('Database Err: PDO or PDO_MYSQL doesn\'t exist!'); 343 | } 344 | $GLOBALS['mysql_instances'][$db_config_key] = new PDO('mysql:dbname='.$db_config['MYSQL_DB'].';host='.$db_config['MYSQL_HOST'].';port='.$db_config['MYSQL_PORT'], $db_config['MYSQL_USER'], $db_config['MYSQL_PASS'], array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES \''.$db_config['MYSQL_CHARSET'].'\'')); 345 | }catch(PDOException $e){err('Database Err: '.$e->getMessage());} 346 | } 347 | return $GLOBALS['mysql_instances'][$db_config_key]; 348 | } 349 | 350 | private function _where($conditions){ 351 | $result = array( "_where" => " ","_bindParams" => array()); 352 | if(is_array($conditions) && !empty($conditions)){ 353 | $fieldss = array(); $sql = null; $join = array(); 354 | if(isset($conditions[0]) && $sql = $conditions[0]) unset($conditions[0]); 355 | foreach( $conditions as $key => $condition ){ 356 | if(substr($key, 0, 1) != ":"){ 357 | unset($conditions[$key]); 358 | $conditions[":".$key] = $condition; 359 | } 360 | $join[] = "`{$key}` = :{$key}"; 361 | } 362 | if(!$sql) $sql = join(" AND ",$join); 363 | 364 | $result["_where"] = " WHERE ". $sql; 365 | $result["_bindParams"] = $conditions; 366 | } 367 | return $result; 368 | } 369 | } 370 | 371 | class View{ 372 | private $left_delimiter, $right_delimiter, $template_dir, $compile_dir; 373 | private $template_vals = array(); 374 | 375 | public function __construct($template_dir, $compile_dir, $left_delimiter = '<{', $right_delimiter = '}>'){ 376 | $this->left_delimiter = $left_delimiter; 377 | $this->right_delimiter = $right_delimiter; 378 | $this->template_dir = $template_dir; 379 | $this->compile_dir = $compile_dir; 380 | } 381 | 382 | public function render($tempalte_name){ 383 | $complied_file = $this->compile($tempalte_name); 384 | 385 | @ob_start(); 386 | extract($this->template_vals, EXTR_SKIP); 387 | $_view_obj = & $this; 388 | include $complied_file; 389 | 390 | return ob_get_clean(); 391 | } 392 | 393 | public function assign($mixed, $val = ''){ 394 | if(is_array($mixed)){ 395 | foreach($mixed as $k => $v){ 396 | if($k != '')$this->template_vals[$k] = $v; 397 | } 398 | }else{ 399 | if($mixed != '')$this->template_vals[$mixed] = $val; 400 | } 401 | } 402 | 403 | public function compile($tempalte_name){ 404 | $file = $this->template_dir.DS.$tempalte_name; 405 | if(!file_exists($file)) err('Err: "'.$file.'" is not exists!'); 406 | if(!is_writable($this->compile_dir) || !is_readable($this->compile_dir)) err('Err: Directory "'.$this->compile_dir.'" is not writable or readable'); 407 | 408 | $complied_file = $this->compile_dir.DS.md5(realpath($file)).'.'.filemtime($file).'.'.basename($tempalte_name).'.php'; 409 | if(file_exists($complied_file))return $complied_file; 410 | 411 | $template_data = file_get_contents($file); 412 | $template_data = $this->_compile_struct($template_data); 413 | $template_data = $this->_compile_function($template_data); 414 | $template_data = ''.$template_data; 415 | 416 | $this->_clear_compliedfile($tempalte_name); 417 | $tmp_file = $complied_file.uniqid('_tpl', true); 418 | if (!file_put_contents($tmp_file, $template_data)) err('Err: File "'.$tmp_file.'" can not be generated.'); 419 | 420 | $success = @rename($tmp_file, $complied_file); 421 | if(!$success){ 422 | if(is_file($complied_file)) @unlink($complied_file); 423 | $success = @rename($tmp_file, $complied_file); 424 | } 425 | if(!$success) err('Err: File "'.$complied_file.'" can not be generated.'); 426 | return $complied_file; 427 | } 428 | 429 | private function _compile_struct($template_data){ 430 | $foreach_inner_before = ''; 431 | $foreach_inner_after = ''; 432 | $pattern_map = array( 433 | '<{\*([\s\S]+?)\*}>' => '', 434 | '<{#(.*?)}>' => '', 435 | '(<{((?!}>).)*?)(\$[\w\"\'\[\]]+?)\.(\w+)(.*?}>)' => '$1$3[\'$4\']$5', 436 | '(<{.*?)(\$(\w+)@(index|iteration|first|last|total))+(.*?}>)' => '$1$_foreach_$3_$4$5', 437 | '<{(\$[\$\w\.\"\'\[\]]+?)\snofilter\s*}>' => '', 438 | '<{(\$[\$\w\"\'\[\]]+?)\s*=(.*?)\s*}>' => '', 439 | '<{(\$[\$\w\.\"\'\[\]]+?)\s*}>' => '', 440 | '<{if\s*(.+?)}>' => '', 441 | '<{else\s*if\s*(.+?)}>' => '', 442 | '<{else}>' => '', 443 | '<{break}>' => '', 444 | '<{continue}>' => '', 445 | '<{\/if}>' => '', 446 | '<{foreach\s*(\$[\$\w\.\"\'\[\]]+?)\s*as(\s*)\$([\w\"\'\[\]]+?)}>' => $foreach_inner_before.''.$foreach_inner_after, 447 | '<{foreach\s*(\$[\$\w\.\"\'\[\]]+?)\s*as\s*(\$[\w\"\'\[\]]+?)\s*=>\s*\$([\w\"\'\[\]]+?)}>' => $foreach_inner_before.' $$3 ) : ?>'.$foreach_inner_after, 448 | '<{\/foreach}>' => '', 449 | '<{include\s*file=(.+?)}>'=> 'compile($1); ?>', 450 | ); 451 | $pattern = $replacement = array(); 452 | foreach($pattern_map as $p => $r){ 453 | $pattern = '/'.str_replace(array("<{", "}>"), array($this->left_delimiter.'\s*','\s*'.$this->right_delimiter), $p).'/i'; 454 | $count = 1; 455 | while($count != 0){ 456 | $template_data = preg_replace($pattern, $r, $template_data, -1, $count); 457 | } 458 | } 459 | return $template_data; 460 | } 461 | 462 | private function _compile_function($template_data){ 463 | $pattern = '/'.$this->left_delimiter.'(\w+)\s*(.*?)'.$this->right_delimiter.'/'; 464 | return preg_replace_callback($pattern, array($this, '_compile_function_callback'), $template_data); 465 | } 466 | 467 | private function _compile_function_callback( $matches ){ 468 | if(empty($matches[2]))return ''; 469 | $sysfunc = preg_replace('/\((.*)\)\s*$/', '', $matches[2], -1, $count); 470 | if($count)return $sysfunc; 471 | 472 | $pattern_inner = '/\b([-\w]+?)\s*=\s*(\$[\w"\'\]\[\-_>\$]+|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|([->\w]+))\s*?/'; 473 | $params = ""; 474 | if(preg_match_all($pattern_inner, $matches[2], $matches_inner, PREG_SET_ORDER)){ 475 | $params = "array("; 476 | foreach($matches_inner as $m)$params .= '\''. $m[1]."'=>".$m[2].", "; 477 | $params .= ")"; 478 | }else{ 479 | err('Err: Parameters of \''.$matches[1].'\' is incorrect!'); 480 | } 481 | return ''; 482 | } 483 | 484 | private function _clear_compliedfile($tempalte_name){ 485 | $dir = scandir($this->compile_dir); 486 | if($dir){ 487 | $part = md5(realpath($this->template_dir.DS.$tempalte_name)); 488 | foreach($dir as $d){ 489 | if(substr($d, 0, strlen($part)) == $part){ 490 | @unlink($this->compile_dir.DS.$d); 491 | } 492 | } 493 | } 494 | } 495 | } 496 | function _err_router($msg){ 497 | Global $__module, $__controller, $__action; 498 | if(!method_exists('BaseController', 'err404')){ 499 | err($msg); 500 | }else{ 501 | BaseController::err404($__module, $__controller, $__action, $msg); 502 | } 503 | } 504 | function _err_handle($errno, $errstr, $errfile, $errline){ 505 | if(0 === error_reporting() || 30711 === error_reporting())return false; 506 | $msg = "ERROR"; 507 | if($errno == E_WARNING)$msg = "WARNING"; 508 | if($errno == E_NOTICE)$msg = "NOTICE"; 509 | if($errno == E_STRICT)$msg = "STRICT"; 510 | if($errno == 8192)$msg = "DEPRECATED"; 511 | err("$msg: $errstr in $errfile on line $errline"); 512 | } 513 | function err($msg){ 514 | $msg = htmlspecialchars($msg); 515 | $traces = debug_backtrace(); 516 | if(!empty($GLOBALS['err_handler'])){ 517 | call_user_func($GLOBALS['err_handler'], $msg, $traces); 518 | }else{ 519 | if(!$GLOBALS['debug']){ 520 | error_log($msg); 521 | }else{ 522 | if (ob_get_contents()) ob_end_clean(); 523 | function _err_highlight_code($code){if(preg_match('/\<\?(php)?[^[:graph:]]/i', $code)){return highlight_string($code, TRUE);}else{return preg_replace('/(<\?php )+/i', "", highlight_string(" $count) {$end = $count + 1;}$returns = array();for($i = $start; $i <= $end; $i++) {if($i == $line){$returns[] = "
".$i.". "._err_highlight_code($data[$i - 1], TRUE)."
";}else{$returns[] = $i.". "._err_highlight_code($data[$i - 1], TRUE);}}return $returns; 525 | }?><?php echo $msg;?>

  • on line
this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('