├── .gitignore ├── fonts └── mui.ttf ├── 打包素材 ├── logo.png ├── logo16.png ├── logo512.png ├── ios │ ├── 320x480.png │ ├── 640x960.png │ ├── 1242x2208.png │ ├── 1536x2008.png │ ├── 1536x2048.png │ ├── 640x1136.png │ ├── 750x1334.png │ ├── 768x1004.png │ └── 768x1024.png └── android │ ├── 240x282.png │ ├── 320x442.png │ ├── 480x762.png │ ├── 720x1242.png │ └── 1080x1882.png ├── images ├── avatar.jpg └── waiting.png ├── README.md ├── js ├── common.js ├── update.js ├── data.js ├── mui.picker.min.js ├── zepto.min.js └── underscore.js ├── .project ├── css ├── media.css ├── app.css └── mui.picker.min.css ├── news-detail.html ├── webview.html ├── search.html ├── topics.html ├── week-update.html ├── topic-news.html ├── about.html ├── lastest.html ├── hot.html ├── index-menu.html ├── news.html ├── search-result.html ├── topic-detail.html ├── index.html ├── index-sub.html ├── animate-7.html ├── animate-18.html ├── animate-detail.html └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea/ 3 | *.iml -------------------------------------------------------------------------------- /fonts/mui.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/fonts/mui.ttf -------------------------------------------------------------------------------- /打包素材/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/logo.png -------------------------------------------------------------------------------- /打包素材/logo16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/logo16.png -------------------------------------------------------------------------------- /images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/images/avatar.jpg -------------------------------------------------------------------------------- /打包素材/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/logo512.png -------------------------------------------------------------------------------- /images/waiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/images/waiting.png -------------------------------------------------------------------------------- /打包素材/ios/320x480.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/320x480.png -------------------------------------------------------------------------------- /打包素材/ios/640x960.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/640x960.png -------------------------------------------------------------------------------- /打包素材/ios/1242x2208.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/1242x2208.png -------------------------------------------------------------------------------- /打包素材/ios/1536x2008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/1536x2008.png -------------------------------------------------------------------------------- /打包素材/ios/1536x2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/1536x2048.png -------------------------------------------------------------------------------- /打包素材/ios/640x1136.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/640x1136.png -------------------------------------------------------------------------------- /打包素材/ios/750x1334.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/750x1334.png -------------------------------------------------------------------------------- /打包素材/ios/768x1004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/768x1004.png -------------------------------------------------------------------------------- /打包素材/ios/768x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/ios/768x1024.png -------------------------------------------------------------------------------- /打包素材/android/240x282.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/android/240x282.png -------------------------------------------------------------------------------- /打包素材/android/320x442.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/android/320x442.png -------------------------------------------------------------------------------- /打包素材/android/480x762.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/android/480x762.png -------------------------------------------------------------------------------- /打包素材/android/720x1242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/android/720x1242.png -------------------------------------------------------------------------------- /打包素材/android/1080x1882.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atjiu/hltmapp-mui/HEAD/打包素材/android/1080x1882.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > 一时兴起把红旅网站解析成接口了,有接口了,干脆就把app也写出来了,项目使用mui开发 2 | 3 | ## 如何开始 4 | 5 | 下载hbuilder,打开本项目即可 6 | 7 | ## APP下载/文档 8 | 9 | app下载地址:已失效 10 | 11 | 接口文档:已失效 12 | 13 | ## 贡献 14 | 15 | 欢迎提pr 16 | 17 | ## 捐赠 18 | 19 | ![image](https://cloud.githubusercontent.com/assets/6915570/18000010/9283d530-6bae-11e6-8c34-cd27060b9074.png) 20 | ![image](https://cloud.githubusercontent.com/assets/6915570/17999995/7c2a4db4-6bae-11e6-891c-4b6bc4f00f4b.png) 21 | 22 | **请朋也喝杯茶吧** 23 | 24 | ## 开源协议 25 | 26 | MIT 27 | -------------------------------------------------------------------------------- /js/common.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | if(typeof module !== 'undefined' && typeof exports === 'object') { 3 | module.exports = factory(root.Common); 4 | } else if(typeof define === "function" && define.amd) { 5 | define(["Common"], function(Common) { 6 | return(root.Common = factory(Common)); 7 | }); 8 | } else { 9 | root.Common = factory(root.Common); 10 | } 11 | }(this, function(Common) { 12 | Common = { 13 | version: "1.0.2", 14 | domain: "http://www.hltm.tv", 15 | api: "https://hltm-api.tomoya.cn", 16 | open: function(id, url, extras) { 17 | mui.openWindow({ 18 | id: id, 19 | url: url, 20 | waiting: { 21 | autoShow: false 22 | }, 23 | extras: extras || {} 24 | }); 25 | }, 26 | showWaiting: function(msg) { 27 | return plus.nativeUI.showWaiting(msg ? msg : "主淫,不要急嘛~", { 28 | loading: { 29 | icon: "/images/waiting.png" 30 | }, 31 | padlock: true 32 | }); 33 | }, 34 | closeWaiting: function(w) { 35 | w.close(); 36 | } 37 | }; 38 | return Common; 39 | })); -------------------------------------------------------------------------------- /js/update.js: -------------------------------------------------------------------------------- 1 | var newVer = 0, w; 2 | // 资源更新 3 | function updateResources() { 4 | var _newVer = plus.storage.getItem("_newVer"); 5 | $.ajax({ 6 | url: Common.api + '/resource', 7 | async: true, 8 | cache: false, 9 | method: 'get', 10 | dataType: 'json', 11 | data: {}, 12 | success: function(data) { 13 | if(data.code == 200) { 14 | newVer = data.version; 15 | if(_newVer == null) { 16 | _newVer = Common.version; 17 | } 18 | if(_newVer < newVer) { 19 | downWgt(data); // 下载升级包 20 | } 21 | } 22 | } 23 | }); 24 | } 25 | 26 | // 下载wgt文件 27 | function downWgt(data) { 28 | mui.confirm("发现新版本,约" + data.size + ",是否更新?", "红旅动漫", ["下次吧", "好哒~"], function(e) { 29 | if(e.index == 1) { 30 | w = Common.showWaiting("下载资源..."); 31 | plus.downloader.createDownload(data.url, { 32 | filename: "_doc/update/" 33 | }, function(d, status) { 34 | if(status == 200) { 35 | installWgt(d.filename); // 安装wgt包 36 | } else { 37 | mui.toast("更新失败"); 38 | Common.closeWaiting(w); 39 | } 40 | plus.nativeUI.closeWaiting(); 41 | }).start(); 42 | } 43 | }); 44 | } 45 | 46 | // 更新应用资源 47 | function installWgt(path) { 48 | w = Common.showWaiting("更新资源..."); 49 | plus.runtime.install(path, {}, function() { 50 | plus.nativeUI.closeWaiting(); 51 | plus.storage.setItem("_newVer", newVer); 52 | setTimeout(function() { 53 | plus.runtime.restart(); 54 | }, 500); 55 | }, function(e) { 56 | Common.closeWaiting(w); 57 | mui.toast("更新失败"); 58 | }); 59 | } -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | hltm-mui 4 | Create By HBuilder 5 | 6 | 7 | 8 | 9 | com.pandora.projects.ui.MKeyBuilder 10 | 11 | 12 | 13 | 14 | com.aptana.ide.core.unifiedBuilder 15 | 16 | 17 | 18 | 19 | 20 | com.pandora.projects.ui.MKeyNature 21 | com.aptana.projects.webnature 22 | 23 | 24 | 25 | 1469583486446 26 | 27 | 10 28 | 29 | org.eclipse.ui.ide.orFilterMatcher 30 | 31 | 32 | org.eclipse.ui.ide.multiFilter 33 | 1.0-projectRelativePath-matches-false-false-bin 34 | 35 | 36 | org.eclipse.ui.ide.multiFilter 37 | 1.0-projectRelativePath-matches-false-false-setting 38 | 39 | 40 | 41 | 42 | 43 | 1470982094043 44 | 45 | 26 46 | 47 | org.eclipse.ui.ide.multiFilter 48 | 1.0-name-matches-false-false-node_modules 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /css/media.css: -------------------------------------------------------------------------------- 1 | .media { 2 | /*margin-top: 15px;*/ 3 | } 4 | .media:first-child { 5 | margin-top: 0; 6 | } 7 | .media, 8 | .media-body { 9 | zoom: 1; 10 | overflow: hidden; 11 | } 12 | .media-body { 13 | width: 10000px; 14 | } 15 | .media-object { 16 | display: block; 17 | } 18 | .media-object.img-thumbnail { 19 | max-width: none; 20 | } 21 | .media-right, 22 | .media > .pull-right { 23 | padding-left: 10px; 24 | } 25 | .media-left, 26 | .media > .pull-left { 27 | padding-right: 10px; 28 | } 29 | .media-left, 30 | .media-right, 31 | .media-body { 32 | display: table-cell; 33 | vertical-align: top; 34 | } 35 | .media-middle { 36 | vertical-align: middle; 37 | } 38 | .media-bottom { 39 | vertical-align: bottom; 40 | } 41 | .media-heading { 42 | margin-top: 0; 43 | margin-bottom: 5px; 44 | } 45 | .media-list { 46 | padding-left: 0; 47 | list-style: none; 48 | } 49 | .clearfix:before, 50 | .clearfix:after { 51 | content: " "; 52 | display: table; 53 | } 54 | .clearfix:after { 55 | clear: both; 56 | } 57 | .center-block { 58 | display: block; 59 | margin-left: auto; 60 | margin-right: auto; 61 | } 62 | .pull-right { 63 | float: right !important; 64 | } 65 | .pull-left { 66 | float: left !important; 67 | } 68 | .hide { 69 | display: none !important; 70 | } 71 | .show { 72 | display: block !important; 73 | } 74 | .invisible { 75 | visibility: hidden; 76 | } 77 | .text-hide { 78 | font: 0/0 a; 79 | color: transparent; 80 | text-shadow: none; 81 | background-color: transparent; 82 | border: 0; 83 | } 84 | .hidden { 85 | display: none !important; 86 | } 87 | .affix { 88 | position: fixed; 89 | } 90 | -------------------------------------------------------------------------------- /js/data.js: -------------------------------------------------------------------------------- 1 | var verData = [{ 2 | text: '全部', 3 | value: '' 4 | }, { 5 | text: 'TV番组', 6 | value: '1' 7 | }, { 8 | text: 'OVA', 9 | value: '2' 10 | }, { 11 | text: 'OAD', 12 | value: '3' 13 | }, { 14 | text: '剧场版', 15 | value: '4' 16 | }, { 17 | text: '特别版', 18 | value: '5' 19 | }, { 20 | text: '真人版', 21 | value: '6' 22 | }, { 23 | text: '动画版', 24 | value: '7' 25 | }, { 26 | text: '其他', 27 | value: '100' 28 | }]; 29 | 30 | var letterData = [{ 31 | text: '全部', 32 | value: '' 33 | }, { 34 | text: 'A', 35 | value: 'A' 36 | }, { 37 | text: 'B', 38 | value: 'B' 39 | }, { 40 | text: 'C', 41 | value: 'C' 42 | }, { 43 | text: 'D', 44 | value: 'D' 45 | }, { 46 | text: 'E', 47 | value: 'E' 48 | }, { 49 | text: 'F', 50 | value: 'F' 51 | }, { 52 | text: 'G', 53 | value: 'G' 54 | }, { 55 | text: 'H', 56 | value: 'H' 57 | }, { 58 | text: 'I', 59 | value: 'I' 60 | }, { 61 | text: 'J', 62 | value: 'J' 63 | }, { 64 | text: 'K', 65 | value: 'K' 66 | }, { 67 | text: 'L', 68 | value: 'L' 69 | }, { 70 | text: 'M', 71 | value: 'M' 72 | }, { 73 | text: 'N', 74 | value: 'N' 75 | }, { 76 | text: 'O', 77 | value: 'O' 78 | }, { 79 | text: 'P', 80 | value: 'P' 81 | }, { 82 | text: 'Q', 83 | value: 'Q' 84 | }, { 85 | text: 'R', 86 | value: 'R' 87 | }, { 88 | text: 'S', 89 | value: 'S' 90 | }, { 91 | text: 'T', 92 | value: 'T' 93 | }, { 94 | text: 'U', 95 | value: 'U' 96 | }, { 97 | text: 'V', 98 | value: 'V' 99 | }, { 100 | text: 'W', 101 | value: 'W' 102 | }, { 103 | text: 'X', 104 | value: 'X' 105 | }, { 106 | text: 'Y', 107 | value: 'Y' 108 | }, { 109 | text: 'Z', 110 | value: 'Z' 111 | }, { 112 | text: '0-9', 113 | value: '100' 114 | }]; 115 | 116 | var sortData = [{ 117 | text: '最新播放', 118 | value: '' 119 | }, { 120 | text: '最热播放', 121 | value: '1' 122 | }] 123 | -------------------------------------------------------------------------------- /news-detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 | 22 |

23 |
24 |
25 |
26 |

27 |
28 |

29 |
30 |
31 | 32 | 33 | 34 | 35 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /webview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 | 22 |

23 |
24 | 25 | 26 | 27 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /css/app.css: -------------------------------------------------------------------------------- 1 | .comictype li em,.comictype .current em{ background: url('http://www.hltm.tv/statics/tp/images/bimg.png');} 2 | 3 | .comictype{ height:40px; border-bottom: 2px solid #f44434; width: 100%; float: left;} 4 | .comictype li{ float:left; width:180px; height:40px; line-height:40px; font-weight:normal; cursor:pointer; font-size:16px; overflow:hidden;} 5 | .comictype li a{ display:block; padding-left: 20px; width:160px; height:40px; color:#868686} 6 | .comictype .normal{ background:url(../images/index_tab.png) no-repeat -300px -50px;} 7 | .comictype span a{ line-height:30px; padding:0 8px; border-right:1px solid #8bc164; text-decoration:underline} 8 | .comictype .normal a{ color:#868686} 9 | .comictype .current{ background-position: 0 -300px; border-bottom: 2px solid #f44434; height: 38px;} 10 | .comictype .current a{color:#f44434} 11 | .tabcon01{ overflow:hidden; border-left:1px solid #e6e6e6; border-top:none; width:720px; float: left;} 12 | .tabcon01 .normal { display:none;} 13 | .tabcon01 .current { display:block;} 14 | .comictype li em{ width: 26px; height: 26px; display: block; float: left; margin: 7px;} 15 | .comictype li .ctype01{ background-position:0 -200px;} 16 | .comictype li a:hover .ctype01,.comictype .current .ctype01{ background-position: 0 -250px;} 17 | .comictype li .ctype02{ background-position:-50px -200px;} 18 | .comictype li a:hover .ctype02,.comictype .current .ctype02{ background-position: -50px -250px;} 19 | .comictype li .ctype03{ background-position:-100px -200px;} 20 | .comictype li a:hover .ctype03,.comictype .current .ctype03{ background-position: -100px -250px;} 21 | .comictype li .ctype04{ background-position:-150px -200px;} 22 | .comictype li a:hover .ctype04,.comictype .current .ctype04{ background-position: -150px -250px;} 23 | 24 | body, .mui-content { 25 | background-color: #FFFFFF; 26 | } 27 | .mui-segmented-control { 28 | background-color: #FFFFFF; 29 | } 30 | .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active { 31 | color: #f44434; 32 | border-bottom: 2px solid #f44434!important; 33 | } 34 | .mui-icon {color: #f44434;} 35 | .mui-table-view {background-color: #FFFFFF!important;} 36 | -------------------------------------------------------------------------------- /search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 | 22 |

搜索

23 |
24 |
25 |
26 | 29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /topics.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello MUI 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |

专题列表

16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | 35 | 36 | 37 | 38 | 39 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /week-update.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

一周更新

18 |
19 |
20 | 45 |
46 | 47 | 48 | 49 | 50 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /topic-news.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

榜单资讯

18 |
19 |
20 | 43 |
44 | 45 | 46 | 47 | 48 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 | 22 |

关于

23 |
24 |
25 | 26 | 63 |

Copyright © 2016 朋也

64 |
65 | 66 | 67 | 68 | 69 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /lastest.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 38 | 39 | 40 | 41 |
42 | 43 |

最新更新

44 |
45 |
46 | 62 |
63 | 64 | 65 | 66 | 67 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /hot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

热门新番

18 |
19 |
20 | 69 |
70 | 71 | 72 | 73 | 74 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /index-menu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 22 | 23 | 24 | 25 |
26 | 29 | 76 |
77 | 78 | 79 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /news.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 |

新闻列表

19 |
20 |
21 |
22 |
23 |
24 |
25 | 51 | 52 | 53 | 54 | 55 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /search-result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 |

搜索结果

19 |
20 |
21 |
22 |
23 |
24 |
25 | 47 | 48 | 49 | 50 | 51 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /topic-detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 |

19 |
20 |
21 |
22 |
23 |
24 |
25 | 47 | 48 | 49 | 50 | 51 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /css/mui.picker.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 选择列表插件 3 | * varstion 2.0.0 4 | * by Houfeng 5 | * Houfeng@DCloud.io 6 | **/ 7 | .mui-pciker-list li,.mui-picker,.mui-picker-inner{box-sizing:border-box;overflow:hidden}.mui-picker{background-color:#ddd;position:relative;height:200px;border:1px solid rgba(0,0,0,.1);-webkit-user-select:none;user-select:none}.mui-dtpicker,.mui-poppicker{left:0;background-color:#eee;box-shadow:0 -5px 7px 0 rgba(0,0,0,.1);-webkit-transition:.3s;width:100%}.mui-picker-inner{position:relative;width:100%;height:100%;-webkit-mask-box-image:-webkit-linear-gradient(bottom,transparent,transparent 5%,#fff 20%,#fff 80%,transparent 95%,transparent);-webkit-mask-box-image:linear-gradient(top,transparent,transparent 5%,#fff 20%,#fff 80%,transparent 95%,transparent)}.mui-pciker-list,.mui-pciker-rule{box-sizing:border-box;padding:0;margin:-18px 0 0;width:100%;height:36px;line-height:36px;position:absolute;left:0;top:50%}.mui-pciker-rule-bg{z-index:0}.mui-pciker-rule-ft{z-index:2;border-top:solid 1px rgba(0,0,0,.1);border-bottom:solid 1px rgba(0,0,0,.1)}.mui-pciker-list{z-index:1;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:perspective(750pt) rotateY(0) rotateX(0);transform:perspective(750pt) rotateY(0) rotateX(0)}.mui-pciker-list li{width:100%;height:100%;position:absolute;text-align:center;vertical-align:middle;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-size:1pc;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#888;padding:0 8px;white-space:nowrap;-webkit-text-overflow:ellipsis;text-overflow:ellipsis;cursor:default;visibility:hidden}.mui-pciker-list li.highlight,.mui-pciker-list li.visible{visibility:visible}.mui-pciker-list li.highlight{color:#222}.mui-poppicker{position:fixed;z-index:999;border-top:solid 1px #ccc;bottom:0;-webkit-transform:translateY(300px)}.mui-poppicker.mui-active{-webkit-transform:translateY(0)}.mui-android-5-1 .mui-poppicker{bottom:-300px;-webkit-transition-property:bottom;-webkit-transform:none}.mui-android-5-1 .mui-poppicker.mui-active{bottom:0;-webkit-transition-property:bottom;-webkit-transform:none}.mui-poppicker-header{padding:6px;font-size:14px;color:#888}.mui-poppicker-header .mui-btn{font-size:9pt;padding:5px 10px}.mui-poppicker-btn-cancel{float:left}.mui-poppicker-btn-ok{float:right}.mui-poppicker-clear{clear:both;height:0;line-height:0;font-size:0;overflow:hidden}.mui-poppicker-body{position:relative;width:100%;height:200px;border-top:solid 1px #ddd}.mui-poppicker-body .mui-picker{width:100%;height:100%;margin:0;border:none;float:left}.mui-dtpicker{position:fixed;z-index:999999;border-top:solid 1px #ccc;bottom:0;-webkit-transform:translateY(300px)}.mui-dtpicker.mui-active{-webkit-transform:translateY(0)}.mui-dtpicker-active-for-page{overflow:hidden!important}.mui-android-5-1 .mui-dtpicker{bottom:-300px;-webkit-transition-property:bottom;-webkit-transform:none}.mui-android-5-1 .mui-dtpicker.mui-active{bottom:0;-webkit-transition-property:bottom;-webkit-transform:none}.mui-dtpicker-header{padding:6px;font-size:14px;color:#888}.mui-dtpicker-header button{font-size:9pt;padding:5px 10px}.mui-dtpicker-header button:last-child{float:right}.mui-dtpicker-body{position:relative;width:100%;height:200px}.mui-ios .mui-dtpicker-body{-webkit-perspective:75pc;perspective:75pc;-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.mui-dtpicker-title h5{display:inline-block;width:20%;margin:0;padding:8px;text-align:center;border-top:solid 1px #ddd;background-color:#f0f0f0;border-bottom:solid 1px #ccc}[data-type=hour] [data-id=title-i],[data-type=hour] [data-id=picker-i],[data-type=month] [data-id=title-i],[data-type=month] [data-id=picker-d],[data-type=month] [data-id=title-d],[data-type=month] [data-id=picker-h],[data-type=month] [data-id=title-h],[data-type=month] [data-id=picker-i],[data-type=time] [data-id=picker-y],[data-type=time] [data-id=picker-m],[data-type=time] [data-id=picker-d],[data-type=time] [data-id=title-y],[data-type=time] [data-id=title-m],[data-type=time] [data-id=title-d],[data-type=date] [data-id=title-i],[data-type=date] [data-id=picker-h],[data-type=date] [data-id=title-h],[data-type=date] [data-id=picker-i]{display:none}.mui-dtpicker .mui-picker{width:20%;height:100%;margin:0;float:left;border:none}[data-type=hour] [data-id=picker-h],[data-type=hour] [data-id=title-h],[data-type=datetime] [data-id=picker-h],[data-type=datetime] [data-id=title-h]{border-left:dotted 1px #ccc}[data-type=datetime] .mui-picker,[data-type=time] .mui-dtpicker-title h5{width:20%}[data-type=date] .mui-dtpicker-title h5,[data-type=date] .mui-picker{width:33.3%}[data-type=hour] .mui-dtpicker-title h5,[data-type=hour] .mui-picker{width:25%}[data-type=month] .mui-dtpicker-title h5,[data-type=month] .mui-picker,[data-type=time] .mui-dtpicker-title h5,[data-type=time] .mui-picker{width:50%} -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 |

红旅动漫

20 |
21 | 22 | 23 | 24 | 25 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /index-sub.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 26 | 27 | 28 | 29 |
30 |
31 | 32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 73 | 82 | 112 | 113 | 114 | 115 | 116 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /animate-7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |

连载动漫

20 |
21 |
22 |
23 | 34 |
35 |
36 |
37 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /animate-18.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |

连载动漫

20 |
21 |
22 |
23 | 34 |
35 |
36 |
37 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /animate-detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello MUI 7 | 8 | 9 | 10 | 11 | 12 | 122 | 123 | 124 | 125 |
126 | 127 |

128 | 129 |
130 |
131 | 132 | 235 | 236 |
237 | 238 | 239 | 240 | 241 | 292 | 293 | 294 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "@platforms": [ 3 | "android", 4 | "iPhone", 5 | "iPad" 6 | ], 7 | "id": "H55F9AFA1",/*应用的标识,创建应用时自动生成,勿手动修改*/ 8 | "name": "红旅动漫",/*应用名称,程序桌面图标名称*/ 9 | "version": { 10 | "name": "1.0.2",/*应用版本名称*/ 11 | "code": "3" 12 | }, 13 | "description": "",/*应用描述信息*/ 14 | "icons": { 15 | "72": "icon.png" 16 | }, 17 | "launch_path": "index.html",/*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/ 18 | "developer": { 19 | "name": "tomoya",/*开发者名称*/ 20 | "email": "1956587218@qq.com",/*开发者邮箱地址*/ 21 | "url": "http://tomoya.cn" 22 | }, 23 | "permissions": { 24 | 25 | 26 | "Cache": { 27 | "description": "管理应用缓存" 28 | }, 29 | 30 | "Console": { 31 | "description": "跟踪调试输出日志" 32 | }, 33 | 34 | "Device": { 35 | "description": "访问设备信息" 36 | }, 37 | "Downloader": { 38 | "description": "文件下载管理" 39 | }, 40 | "Events": { 41 | "description": "应用扩展事件" 42 | }, 43 | "File": { 44 | "description": "访问本地文件系统" 45 | }, 46 | 47 | 48 | "Invocation": { 49 | "description": "使用Native.js能力" 50 | }, 51 | 52 | 53 | 54 | "Storage": { 55 | "description": "管理应用本地数据" 56 | }, 57 | 58 | 59 | "Runtime": { 60 | "description": "访问运行期环境" 61 | }, 62 | "XMLHttpRequest": { 63 | "description": "跨域网络访问" 64 | }, 65 | "Zip": { 66 | "description": "文件压缩与解压缩" 67 | }, 68 | 69 | 70 | 71 | "Webview": { 72 | "description": "窗口管理" 73 | }, 74 | "NativeUI": { 75 | "description": "原生UI控件" 76 | }, 77 | "Navigator": { 78 | "description": "浏览器信息" 79 | }, 80 | "NativeObj": { 81 | "description": "原生对象" 82 | }, 83 | "Statistic": {}, 84 | "Share": {},"Push":{},"OAuth":{} 85 | }, 86 | "plus": { 87 | "splashscreen": { 88 | "autoclose": true,/*是否自动关闭程序启动界面,true表示应用加载应用入口页面后自动关闭;false则需调plus.navigator.closeSplashscreen()关闭*/ 89 | "waiting": true 90 | }, 91 | "runmode": "liberate",/*应用的首次启动运行模式,可取liberate或normal,liberate模式在第一次启动时将解压应用资源(Android平台File API才可正常访问_www目录)*/ 92 | "signature": "Sk9JTiBVUyBtYWlsdG86aHIyMDEzQGRjbG91ZC5pbw==",/*可选,保留给应用签名,暂不使用*/ 93 | "distribute": { 94 | "plugins": {"push":{"igexin":{"appid":"OTemIMbYiz55QD0yViYcq3","appkey":"7AP9qzX5zm9lBvBSgkLnF9","appsecret":"AI1gcdKORB89KZ2unmKux1"}},"oauth":{"qq":{"appid":"1105504525"}}, 95 | "share": { 96 | "qq": { 97 | "appid": "1105504525", 98 | "description": "QQ分享" 99 | } 100 | }, 101 | "statics": { 102 | "umeng": { 103 | "appkey_ios": "579adcb9e0f55a2bbe0036d2", 104 | "channelid_ios": "appstore", 105 | "appkey_android": "579adc3ce0f55ac091003347", 106 | "channelid_android": "360" 107 | } 108 | } 109 | }, 110 | "apple": { 111 | "appid": "",/*iOS应用标识,苹果开发网站申请的appid,如io.dcloud.HelloH5*/ 112 | "mobileprovision": "",/*iOS应用打包配置文件*/ 113 | "password": "",/*iOS应用打包个人证书导入密码*/ 114 | "p12": "",/*iOS应用打包个人证书,打包配置文件关联的个人证书*/ 115 | "devices": "universal",/*iOS应用支持的设备类型,可取值iphone/ipad/universal*/ 116 | "frameworks": [] 117 | }, 118 | "google": { 119 | "packagename": "",/*Android应用包名,如io.dcloud.HelloH5*/ 120 | "keystore": "",/*Android应用打包使用的密钥库文件*/ 121 | "password": "",/*Android应用打包使用密钥库中证书的密码*/ 122 | "aliasname": "",/*Android应用打包使用密钥库中证书的别名*/ 123 | "permissions": ["","","","","","","","","","","","",""] 124 | }, 125 | "orientation": [ 126 | "portrait-primary" 127 | ],/*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/ 128 | "icons": { 129 | "ios": { 130 | "prerendered": true, /*应用图标是否已经高亮处理,在iOS6及以下设备上有效*/ 131 | "auto": "", /*应用图标,分辨率:512x512,用于自动生成各种尺寸程序图标*/ 132 | "iphone": { 133 | "normal": "unpackage/res/icons/57x57.png",/*iPhone普通屏幕程序图标,分辨率:57x57*/ 134 | "retina": "unpackage/res/icons/114x114.png",/*iPhone高分屏程序图标,分辨率:114x114*/ 135 | "retina7": "unpackage/res/icons/120x120.png",/*iPhone iOS7高分屏程序图标,分辨率:120x120*/ 136 | "spotlight-normal": "unpackage/res/icons/29x29.png", /*iPhone Spotlight搜索程序图标,分辨率:29x29*/ 137 | "spotlight-retina": "unpackage/res/icons/58x58.png", /*iPhone高分屏Spotlight搜索程序图标,分辨率:58x58*/ 138 | "spotlight-retina7": "unpackage/res/icons/80x80.png",/*iPhone iOS7高分屏Spotlight搜索程序图标,分辨率:80x80*/ 139 | "settings-normal": "unpackage/res/icons/29x29.png", /*iPhone设置页面程序图标,分辨率:29x29*/ 140 | "settings-retina": "unpackage/res/icons/58x58.png", 141 | "retina8": "unpackage/res/icons/180x180.png", 142 | "settings-retina8": "unpackage/res/icons/87x87.png" 143 | }, 144 | "ipad": { 145 | "normal": "unpackage/res/icons/72x72.png", /*iPad普通屏幕程序图标,分辨率:72x72*/ 146 | "retina": "unpackage/res/icons/144x144.png", /*iPad高分屏程序图标,分辨率:144x144*/ 147 | "normal7": "unpackage/res/icons/76x76.png", /*iPad iOS7程序图标,分辨率:76x76*/ 148 | "retina7": "unpackage/res/icons/152x152.png", /*iPad iOS7高分屏程序图标,分辨率:152x152*/ 149 | "spotlight-normal": "unpackage/res/icons/50x50.png", /*iPad Spotlight搜索程序图标,分辨率:50x50*/ 150 | "spotlight-retina": "unpackage/res/icons/100x100.png", /*iPad高分屏Spotlight搜索程序图标,分辨率:100x100*/ 151 | "spotlight-normal7": "unpackage/res/icons/40x40.png",/*iPad iOS7 Spotlight搜索程序图标,分辨率:40x40*/ 152 | "spotlight-retina7": "unpackage/res/icons/80x80.png",/*iPad iOS7高分屏Spotlight搜索程序图标,分辨率:80x80*/ 153 | "settings-normal": "unpackage/res/icons/29x29.png",/*iPad设置页面程序图标,分辨率:29x29*/ 154 | "settings-retina": "unpackage/res/icons/58x58.png" 155 | } 156 | }, 157 | "android": { 158 | "mdpi": "unpackage/res/icons/48x48.png", /*普通屏程序图标,分辨率:48x48*/ 159 | "ldpi": "unpackage/res/icons/48x48.png", /*大屏程序图标,分辨率:48x48*/ 160 | "hdpi": "unpackage/res/icons/72x72.png", /*高分屏程序图标,分辨率:72x72*/ 161 | "xhdpi": "unpackage/res/icons/96x96.png",/*720P高分屏程序图标,分辨率:96x96*/ 162 | "xxhdpi": "unpackage/res/icons/144x144.png" 163 | } 164 | }, 165 | "splashscreen": { 166 | "ios": { 167 | "iphone": { 168 | "default": "/Users/tomoya/Downloads/hltm-api/ios/320x480.png", /*iPhone3启动图片选,分辨率:320x480*/ 169 | "retina35": "/Users/tomoya/Downloads/hltm-api/ios/640x960.png",/*3.5英寸设备(iPhone4)启动图片,分辨率:640x960*/ 170 | "retina40": "/Users/tomoya/Downloads/hltm-api/ios/640x1136.png", 171 | "retina55": "/Users/tomoya/Downloads/hltm-api/ios/1242x2208.png", 172 | "retina47": "/Users/tomoya/Downloads/hltm-api/ios/750x1334.png", 173 | "retina55l": "/Users/tomoya/Downloads/hltm-api/ios/1242x2208.png" 174 | }, 175 | "ipad": { 176 | "portrait": "/Users/tomoya/Downloads/hltm-api/ios/768x1004.png", /*iPad竖屏启动图片,分辨率:768x1004*/ 177 | "portrait-retina": "/Users/tomoya/Downloads/hltm-api/ios/1536x2008.png",/*iPad高分屏竖屏图片,分辨率:1536x2008*/ 178 | "landscape": "/Users/tomoya/Downloads/hltm-api/ios/768x1024.png", /*iPad横屏启动图片,分辨率:1024x748*/ 179 | "landscape-retina": "/Users/tomoya/Downloads/hltm-api/ios/1536x2048.png", /*iPad高分屏横屏启动图片,分辨率:2048x1496*/ 180 | "portrait7": "/Users/tomoya/Downloads/hltm-api/ios/768x1024.png", /*iPad iOS7竖屏启动图片,分辨率:768x1024*/ 181 | "portrait-retina7": "/Users/tomoya/Downloads/hltm-api/ios/1536x2048.png",/*iPad iOS7高分屏竖屏图片,分辨率:1536x2048*/ 182 | "landscape7": "/Users/tomoya/Downloads/hltm-api/ios/768x1024.png", /*iPad iOS7横屏启动图片,分辨率:1024x768*/ 183 | "landscape-retina7": "/Users/tomoya/Downloads/hltm-api/ios/1536x2048.png" 184 | } 185 | }, 186 | "android": { 187 | "mdpi": "/Users/tomoya/Desktop/U盘/图片/hltm-api打包素材/android/240x282.png", /*普通屏启动图片,分辨率:240x282*/ 188 | "ldpi": "/Users/tomoya/Desktop/U盘/图片/hltm-api打包素材/android/320x442.png", /*大屏启动图片,分辨率:320x442*/ 189 | "hdpi": "/Users/tomoya/Desktop/U盘/图片/hltm-api打包素材/android/480x762.png", /*高分屏启动图片,分辨率:480x762*/ 190 | "xhdpi": "/Users/tomoya/Desktop/U盘/图片/hltm-api打包素材/android/720x1242.png", /*720P高分屏启动图片,分辨率:720x1242*/ 191 | "xxhdpi": "/Users/tomoya/Desktop/U盘/图片/hltm-api打包素材/android/1080x1882.png" 192 | } 193 | } 194 | } 195 | }, 196 | "dependencies": { 197 | "pages": { 198 | "index-sub.html": { 199 | "resources": [ 200 | "js/underscore.js", 201 | "js/common.js", 202 | "js/zepto.min.js", 203 | "css/mui.min.css", 204 | "js/mui.min.js", 205 | "css/app.css" 206 | ], 207 | "refer": [ 208 | "news-detail.html", 209 | "animate-detail.html" 210 | ], 211 | "priority": 0 212 | }, 213 | "index.html": { 214 | "resources": [ 215 | "index-sub.html", 216 | "js/mui.min.js", 217 | "fonts/mui.ttf", 218 | "css/mui.min.css", 219 | "js/common.js", 220 | "js/zepto.min.js", 221 | "css/app.css", 222 | "js/update.js" 223 | ], 224 | "refer": [ 225 | "index-menu.html", 226 | "search.html" 227 | ], 228 | "priority": 0 229 | }, 230 | "index-menu.html": { 231 | "resources": [ 232 | "js/mui.min.js", 233 | "css/mui.min.css", 234 | "fonts/mui.ttf", 235 | "js/common.js", 236 | "css/app.css" 237 | ], 238 | "refer": [ 239 | "week-update.html", 240 | "hot.html", 241 | "lastest.html", 242 | "topic-news.html", 243 | "topics.html", 244 | "about.html", 245 | "animate-7.html", 246 | "animate-18.html", 247 | "news.html" 248 | ], 249 | "priority": 0 250 | }, 251 | "news-detail.html": { 252 | "resources": [ 253 | "js/underscore.js", 254 | "js/common.js", 255 | "js/mui.min.js", 256 | "js/zepto.min.js", 257 | "fonts/mui.ttf", 258 | "css/mui.min.css", 259 | "css/app.css" 260 | ], 261 | "refer": [], 262 | "priority": 0 263 | }, 264 | "search.html": { 265 | "resources": [ 266 | "js/underscore.js", 267 | "js/common.js", 268 | "js/mui.min.js", 269 | "css/app.css", 270 | "js/zepto.min.js", 271 | "fonts/mui.ttf", 272 | "css/mui.min.css" 273 | ], 274 | "refer": [ 275 | "search-result.html" 276 | ], 277 | "priority": 0 278 | }, 279 | "search-result.html": { 280 | "resources": [ 281 | "css/media.css", 282 | "js/underscore.js", 283 | "js/common.js", 284 | "js/mui.min.js", 285 | "js/zepto.min.js", 286 | "fonts/mui.ttf", 287 | "css/mui.min.css", 288 | "css/app.css" 289 | ], 290 | "refer": [], 291 | "priority": 0 292 | }, 293 | "week-update.html": { 294 | "resources": [ 295 | "js/underscore.js", 296 | "js/common.js", 297 | "js/mui.min.js", 298 | "js/zepto.min.js", 299 | "fonts/mui.ttf", 300 | "css/mui.min.css" 301 | ], 302 | "refer": [ 303 | "search-result.html" 304 | ], 305 | "priority": 0 306 | }, 307 | "animate-detail.html": { 308 | "resources": [ 309 | "js/underscore.js", 310 | "js/common.js", 311 | "js/mui.min.js", 312 | "js/zepto.min.js", 313 | "fonts/mui.ttf", 314 | "css/mui.min.css", 315 | "css/app.css", 316 | "js/ZeroClipboard.js" 317 | ], 318 | "refer": [], 319 | "priority": 0 320 | }, 321 | "hot.html": { 322 | "resources": [ 323 | "js/underscore.js", 324 | "js/common.js", 325 | "js/mui.min.js", 326 | "js/zepto.min.js", 327 | "fonts/mui.ttf", 328 | "css/mui.min.css" 329 | ], 330 | "refer": [ 331 | "animate-detail.html" 332 | ], 333 | "priority": 0 334 | }, 335 | "lastest.html": { 336 | "resources": [ 337 | "js/underscore.js", 338 | "js/common.js", 339 | "js/mui.min.js", 340 | "js/zepto.min.js", 341 | "fonts/mui.ttf", 342 | "css/mui.min.css" 343 | ], 344 | "refer": [ 345 | "animate-detail.html" 346 | ], 347 | "priority": 0 348 | }, 349 | "topic-news.html": { 350 | "resources": [ 351 | "js/underscore.js", 352 | "js/common.js", 353 | "js/mui.min.js", 354 | "js/zepto.min.js", 355 | "fonts/mui.ttf", 356 | "css/mui.min.css" 357 | ], 358 | "refer": [], 359 | "priority": 0 360 | }, 361 | "topics.html": { 362 | "resources": [ 363 | "js/underscore.js", 364 | "js/common.js", 365 | "js/mui.min.js", 366 | "js/zepto.min.js", 367 | "fonts/mui.ttf", 368 | "css/mui.min.css", 369 | "css/app.css" 370 | ], 371 | "refer": [ 372 | "topic-detail.html" 373 | ], 374 | "priority": 0 375 | }, 376 | "topic-detail.html": { 377 | "resources": [ 378 | "css/mui.min.css", 379 | "css/media.css" 380 | ], 381 | "refer": [ 382 | "animate-detail.html" 383 | ], 384 | "priority": 0 385 | }, 386 | "about.html": { 387 | "resources": [ 388 | "images/avatar.jpg", 389 | "js/underscore.js", 390 | "js/common.js", 391 | "js/mui.min.js", 392 | "css/app.css", 393 | "js/zepto.min.js", 394 | "fonts/mui.ttf", 395 | "css/mui.min.css" 396 | ], 397 | "refer": [ 398 | "webview.html" 399 | ], 400 | "priority": 0 401 | }, 402 | "webview.html": { 403 | "resources": [ 404 | "js/common.js", 405 | "js/mui.min.js", 406 | "js/zepto.min.js", 407 | "css/mui.min.css", 408 | "css/app.css", 409 | "fonts/mui.ttf" 410 | ], 411 | "refer": [], 412 | "priority": 0 413 | }, 414 | "animate-7.html": { 415 | "resources": [ 416 | "js/mui.picker.min.js", 417 | "js/data.js", 418 | "css/mui.picker.min.css", 419 | "css/media.css", 420 | "js/underscore.js", 421 | "js/common.js", 422 | "js/mui.min.js", 423 | "css/app.css", 424 | "js/zepto.min.js", 425 | "fonts/mui.ttf", 426 | "css/mui.min.css" 427 | ], 428 | "refer": [], 429 | "priority": 0 430 | }, 431 | "animate-18.html": { 432 | "resources": [ 433 | "js/underscore.js", 434 | "js/common.js", 435 | "js/mui.picker.min.js", 436 | "js/mui.min.js", 437 | "css/app.css", 438 | "js/zepto.min.js", 439 | "fonts/mui.ttf", 440 | "css/mui.min.css", 441 | "js/data.js", 442 | "css/mui.picker.min.css", 443 | "css/media.css" 444 | ], 445 | "refer": [], 446 | "priority": 0 447 | }, 448 | "news.html": { 449 | "resources": [ 450 | "js/underscore.js", 451 | "js/common.js", 452 | "js/mui.min.js", 453 | "css/app.css", 454 | "js/zepto.min.js", 455 | "fonts/mui.ttf", 456 | "css/mui.min.css", 457 | "css/media.css" 458 | ], 459 | "refer": [ 460 | "news-detail.html" 461 | ], 462 | "priority": 0 463 | } 464 | }, 465 | "idle": { 466 | "resources": [ 467 | "js/underscore-min.js", 468 | "js/mui.js" 469 | ] 470 | } 471 | } 472 | } -------------------------------------------------------------------------------- /js/mui.picker.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 选择列表插件 3 | * varstion 2.0.0 4 | * by Houfeng 5 | * Houfeng@DCloud.io 6 | **/ 7 | !function(e,t,i,n){var a=30,r=90,s=40,c=10,l=e.rad2deg=function(e){return e/(Math.PI/180)},o=(e.deg2rad=function(e){return e*(Math.PI/180)},navigator.platform.toLowerCase()),d=navigator.userAgent.toLowerCase(),u=(d.indexOf("iphone")>-1||d.indexOf("ipad")>-1||d.indexOf("ipod")>-1)&&(o.indexOf("iphone")>-1||o.indexOf("ipad")>-1||o.indexOf("ipod")>-1),p=e.Picker=function(e,t){var i=this;i.holder=e,i.options=t||{},i.init(),i.initInertiaParams(),i.calcElementItemPostion(!0),i.bindEvent()};p.prototype.findElementItems=function(){var e=this;return e.elementItems=[].slice.call(e.holder.querySelectorAll("li")),e.elementItems},p.prototype.init=function(){var e=this;e.list=e.holder.querySelector("ul"),e.findElementItems(),e.height=e.holder.offsetHeight,e.r=e.height/2-c,e.d=2*e.r,e.itemHeight=e.elementItems.length>0?e.elementItems[0].offsetHeight:s,e.itemAngle=parseInt(e.calcAngle(.8*e.itemHeight)),e.hightlightRange=e.itemAngle/2,e.visibleRange=r,e.beginAngle=0,e.beginExceed=e.beginAngle-a,e.list.angle=e.beginAngle,u&&(e.list.style.webkitTransformOrigin="center center "+e.r+"px")},p.prototype.calcElementItemPostion=function(e){var t=this;e&&(t.items=[]),t.elementItems.forEach(function(i){var n=t.elementItems.indexOf(i);if(t.endAngle=t.itemAngle*n,i.angle=t.endAngle,i.style.webkitTransformOrigin="center center -"+t.r+"px",i.style.webkitTransform="translateZ("+t.r+"px) rotateX("+-t.endAngle+"deg)",e){var a={};a.text=i.innerHTML||"",a.value=i.getAttribute("data-value")||a.text,t.items.push(a)}}),t.endExceed=t.endAngle+a,t.calcElementItemVisibility(t.beginAngle)},p.prototype.calcAngle=function(e){var t=this,i=b=parseFloat(t.r);e=Math.abs(e);var n=180*parseInt(e/t.d);e%=t.d;var a=(i*i+b*b-e*e)/(2*i*b),r=n+l(Math.acos(a));return r},p.prototype.calcElementItemVisibility=function(e){var t=this;t.elementItems.forEach(function(i){var n=Math.abs(i.angle-e);n0?i-c:i+c;l>t.endExceed&&(l=t.endExceed),l300&&(i.lastMoveTime=a,i.lastMoveStart=n.pageY)}i.stopInertiaMove=!0},p.prototype.startInertiaScroll=function(e){var t=this,i=e.changedTouches?e.changedTouches[0]:e,n=e.timeStamp||Date.now(),a=(i.pageY-t.lastMoveStart)/(n-t.lastMoveTime),r=a>0?-1:1,s=6e-4*r*-1,c=Math.abs(a/s),l=a*c/2,o=t.list.angle,d=t.calcAngle(l)*r,u=d;return o+dt.endExceed&&(d=t.endExceed-o,c=c*(d/u)*.6),0==d?void t.endScroll():void t.scrollDistAngle(n,o,d,c)},p.prototype.scrollDistAngle=function(e,t,i,n){var a=this;a.stopInertiaMove=!1,function(e,t,i,n){var r=13,s=n/r,c=0;!function l(){if(!a.stopInertiaMove){var e=a.quartEaseOut(c,t,i,s);return a.setAngle(e),c++,c>s-1||ea.endExceed?void a.endScroll():void setTimeout(l,r)}}()}(e,t,i,n)},p.prototype.quartEaseOut=function(e,t,i,n){return-i*((e=e/n-1)*e*e*e-1)+t},p.prototype.endScroll=function(){var e=this;if(e.list.anglee.endAngle)e.list.style.webkitTransition="150ms ease-out",e.setAngle(e.endAngle);else{var t=parseInt((e.list.angle/e.itemAngle).toFixed(0));e.list.style.webkitTransition="100ms ease-out",e.setAngle(e.itemAngle*t)}e.triggerChange()},p.prototype.triggerChange=function(t){var i=this;setTimeout(function(){var n=i.getSelectedIndex(),a=i.items[n];!e.trigger||n==i.lastIndex&&t!==!0||e.trigger(i.holder,"change",{index:n,item:a}),i.lastIndex=n,"function"==typeof t&&t()},0)},p.prototype.correctAngle=function(e){var t=this;return et.endAngle?t.endAngle:e},p.prototype.setItems=function(e){var t=this;t.items=e||[];var i=[];t.items.forEach(function(e){null!==e&&e!==n&&i.push("
  • "+(e.text||e)+"
  • ")}),t.list.innerHTML=i.join(""),t.findElementItems(),t.calcElementItemPostion(),t.setAngle(t.correctAngle(t.list.angle)),t.triggerChange(!0)},p.prototype.getItems=function(){var e=this;return e.items},p.prototype.getSelectedIndex=function(){var e=this;return parseInt((e.list.angle/e.itemAngle).toFixed(0))},p.prototype.setSelectedIndex=function(e,t,i){var n=this;n.list.style.webkitTransition="";var a=n.correctAngle(n.itemAngle*e);if(t&&t>0){var r=a-n.list.angle;n.scrollDistAngle(Date.now(),n.list.angle,r,t)}else n.setAngle(a);n.triggerChange(i)},p.prototype.getSelectedItem=function(){var e=this;return e.items[e.getSelectedIndex()]},p.prototype.getSelectedValue=function(){var e=this;return(e.items[e.getSelectedIndex()]||{}).value},p.prototype.getSelectedText=function(){var e=this;return(e.items[e.getSelectedIndex()]||{}).text},p.prototype.setSelectedValue=function(e,t,i){var n=this;for(var a in n.items){var r=n.items[a];if(r.value==e)return void n.setSelectedIndex(a,t,i)}},e.fn&&(e.fn.picker=function(e){return this.each(function(t,i){if(!i.picker)if(e)i.picker=new p(i,e);else{var n=i.getAttribute("data-picker-options"),a=n?JSON.parse(n):{};i.picker=new p(i,a)}}),this[0]?this[0].picker:null},e.ready(function(){e(".mui-picker").picker()}))}(window.mui||window,window,document,void 0),function(e,t){e.dom=function(i){return"string"!=typeof i?i instanceof Array||i[0]&&i.length?[].slice.call(i):[i]:(e.__create_dom_div__||(e.__create_dom_div__=t.createElement("div")),e.__create_dom_div__.innerHTML=i,[].slice.call(e.__create_dom_div__.childNodes))};var i='
    ',n='
    ';e.PopPicker=e.Class.extend({init:function(n){var a=this;a.options=n||{},a.options.buttons=a.options.buttons||["取消","确定"],a.panel=e.dom(i)[0],t.body.appendChild(a.panel),a.ok=a.panel.querySelector(".mui-poppicker-btn-ok"),a.cancel=a.panel.querySelector(".mui-poppicker-btn-cancel"),a.body=a.panel.querySelector(".mui-poppicker-body"),a.mask=e.createMask(),a.cancel.innerText=a.options.buttons[0],a.ok.innerText=a.options.buttons[1],a.cancel.addEventListener("tap",function(e){a.hide()},!1),a.ok.addEventListener("tap",function(e){if(a.callback){var t=a.callback(a.getSelectedItems());t!==!1&&a.hide()}},!1),a.mask[0].addEventListener("tap",function(){a.hide()},!1),a._createPicker(),a.panel.addEventListener(e.EVENT_START,function(e){e.preventDefault()},!1),a.panel.addEventListener(e.EVENT_MOVE,function(e){e.preventDefault()},!1)},_createPicker:function(){var t=this,i=t.options.layer||1,a=100/i+"%";t.pickers=[];for(var r=1;i>=r;r++){var s=e.dom(n)[0];s.style.width=a,t.body.appendChild(s);var c=e(s).picker();t.pickers.push(c),s.addEventListener("change",function(e){var t=this.nextSibling;if(t&&t.picker){var i=e.detail||{},n=i.item||{};t.picker.setItems(n.children)}},!1)}},setData:function(e){var t=this;e=e||[],t.pickers[0].setItems(e)},getSelectedItems:function(){var e=this,t=[];for(var i in e.pickers){var n=e.pickers[i];t.push(n.getSelectedItem()||{})}return t},show:function(i){var n=this;n.callback=i,n.mask.show(),t.body.classList.add(e.className("poppicker-active-for-page")),n.panel.classList.add(e.className("active")),n.__back=e.back,e.back=function(){n.hide()}},hide:function(){var i=this;i.disposed||(i.panel.classList.remove(e.className("active")),i.mask.close(),t.body.classList.remove(e.className("poppicker-active-for-page")),e.back=i.__back)},dispose:function(){var e=this;e.hide(),setTimeout(function(){e.panel.parentNode.removeChild(e.panel);for(var t in e)e[t]=null,delete e[t];e.disposed=!0},300)}})}(mui,document),function(e,t){e.dom=function(i){return"string"!=typeof i?i instanceof Array||i[0]&&i.length?[].slice.call(i):[i]:(e.__create_dom_div__||(e.__create_dom_div__=t.createElement("div")),e.__create_dom_div__.innerHTML=i,[].slice.call(e.__create_dom_div__.childNodes))};var i='
    ';e.DtPicker=e.Class.extend({init:function(n){var a=this,r=e.dom(i)[0];t.body.appendChild(r),e('[data-id*="picker"]',r).picker();var s=a.ui={picker:r,mask:e.createMask(),ok:e('[data-id="btn-ok"]',r)[0],cancel:e('[data-id="btn-cancel"]',r)[0],y:e('[data-id="picker-y"]',r)[0],m:e('[data-id="picker-m"]',r)[0],d:e('[data-id="picker-d"]',r)[0],h:e('[data-id="picker-h"]',r)[0],i:e('[data-id="picker-i"]',r)[0],labels:e('[data-id*="title-"]',r)};s.cancel.addEventListener("tap",function(){a.hide()},!1),s.ok.addEventListener("tap",function(){var e=a.callback(a.getSelected());e!==!1&&a.hide()},!1),s.y.addEventListener("change",function(e){a.options.beginMonth||a.options.endMonth?a._createMonth():a._createDay()},!1),s.m.addEventListener("change",function(e){a._createDay()},!1),s.d.addEventListener("change",function(e){(a.options.beginMonth||a.options.endMonth)&&a._createHours()},!1),s.h.addEventListener("change",function(e){(a.options.beginMonth||a.options.endMonth)&&a._createMinutes()},!1),s.mask[0].addEventListener("tap",function(){a.hide()},!1),a._create(n),a.ui.picker.addEventListener(e.EVENT_START,function(e){e.preventDefault()},!1),a.ui.picker.addEventListener(e.EVENT_MOVE,function(e){e.preventDefault()},!1)},getSelected:function(){var e=this,t=e.ui,i=e.options.type,n={type:i,y:t.y.picker.getSelectedItem(),m:t.m.picker.getSelectedItem(),d:t.d.picker.getSelectedItem(),h:t.h.picker.getSelectedItem(),i:t.i.picker.getSelectedItem(),toString:function(){return this.value}};switch(i){case"datetime":n.value=n.y.value+"-"+n.m.value+"-"+n.d.value+" "+n.h.value+":"+n.i.value,n.text=n.y.text+"-"+n.m.text+"-"+n.d.text+" "+n.h.text+":"+n.i.text;break;case"date":n.value=n.y.value+"-"+n.m.value+"-"+n.d.value,n.text=n.y.text+"-"+n.m.text+"-"+n.d.text;break;case"time":n.value=n.h.value+":"+n.i.value,n.text=n.h.text+":"+n.i.text;break;case"month":n.value=n.y.value+"-"+n.m.value,n.text=n.y.text+"-"+n.m.text;break;case"hour":n.value=n.y.value+"-"+n.m.value+"-"+n.d.value+" "+n.h.value,n.text=n.y.text+"-"+n.m.text+"-"+n.d.text+" "+n.h.text}return n},setSelectedValue:function(e){var t=this,i=t.ui,n=t._parseValue(e);i.y.picker.setSelectedValue(n.y,0,function(){i.m.picker.setSelectedValue(n.m,0,function(){i.d.picker.setSelectedValue(n.d,0,function(){i.h.picker.setSelectedValue(n.h,0,function(){i.i.picker.setSelectedValue(n.i,0)})})})})},isLeapYear:function(e){return e%4==0&&e%100!=0||e%400==0},_inArray:function(e,t){for(var i in e){var n=e[i];if(n===t)return!0}return!1},getDayNum:function(e,t){var i=this;return i._inArray([1,3,5,7,8,10,12],t)?31:i._inArray([4,6,9,11],t)?30:i.isLeapYear(e)?29:28},_fill:function(e){return e=e.toString(),e.length<2&&(e=0+e),e},_isBeginYear:function(){return this.options.beginYear===parseInt(this.ui.y.picker.getSelectedValue())},_isBeginMonth:function(){return this.options.beginMonth&&this._isBeginYear()&&this.options.beginMonth===parseInt(this.ui.m.picker.getSelectedValue())},_isBeginDay:function(){return this._isBeginMonth()&&this.options.beginDay===parseInt(this.ui.d.picker.getSelectedValue())},_isBeginHours:function(){return this._isBeginDay()&&this.options.beginHours===parseInt(this.ui.h.picker.getSelectedValue())},_isEndYear:function(){return this.options.endYear===parseInt(this.ui.y.picker.getSelectedValue())},_isEndMonth:function(){return this.options.endMonth&&this._isEndYear()&&this.options.endMonth===parseInt(this.ui.m.picker.getSelectedValue())},_isEndDay:function(){return this._isEndMonth()&&this.options.endDay===parseInt(this.ui.d.picker.getSelectedValue())},_isEndHours:function(){return this._isEndDay()&&this.options.endHours===parseInt(this.ui.h.picker.getSelectedValue())},_createYear:function(e){var t=this,i=t.options,n=t.ui,a=[];if(i.customData.y)a=i.customData.y;else for(var r=i.beginYear,s=i.endYear,c=r;s>=c;c++)a.push({text:c+"",value:c});n.y.picker.setItems(a)},_createMonth:function(e){var t=this,i=t.options,n=t.ui,a=[];if(i.customData.m)a=i.customData.m;else for(var r=i.beginMonth&&t._isBeginYear()?i.beginMonth:1,s=i.endMonth&&t._isEndYear()?i.endMonth:12;s>=r;r++){var c=t._fill(r);a.push({text:c,value:c})}n.m.picker.setItems(a)},_createDay:function(e){var t=this,i=t.options,n=t.ui,a=[];if(i.customData.d)a=i.customData.d;else for(var r=t._isBeginMonth()?i.beginDay:1,s=t._isEndMonth()?i.endDay:t.getDayNum(parseInt(this.ui.y.picker.getSelectedValue()),parseInt(this.ui.m.picker.getSelectedValue()));s>=r;r++){var c=t._fill(r);a.push({text:c,value:c})}n.d.picker.setItems(a),e=e||n.d.picker.getSelectedValue()},_createHours:function(e){var t=this,i=t.options,n=t.ui,a=[];if(i.customData.h)a=i.customData.h;else for(var r=t._isBeginDay()?i.beginHours:0,s=t._isEndDay()?i.endHours:23;s>=r;r++){var c=t._fill(r);a.push({text:c,value:c})}n.h.picker.setItems(a)},_createMinutes:function(e){var t=this,i=t.options,n=t.ui,a=[];if(i.customData.i)a=i.customData.i;else for(var r=t._isBeginHours()?i.beginMinutes:0,s=t._isEndHours()?i.endMinutes:59;s>=r;r++){var c=t._fill(r);a.push({text:c,value:c})}n.i.picker.setItems(a)},_setLabels:function(){var e=this,t=e.options,i=e.ui;i.labels.each(function(e,i){i.innerText=t.labels[e]})},_setButtons:function(){var e=this,t=e.options,i=e.ui;i.cancel.innerText=t.buttons[0],i.ok.innerText=t.buttons[1]},_parseValue:function(e){var t={};if(e){var i=e.replace(":","-").replace(" ","-").split("-");t.y=i[0],t.m=i[1],t.d=i[2],t.h=i[3],t.i=i[4]}else{var n=new Date;t.y=n.getFullYear(),t.m=n.getMonth()+1,t.d=n.getDate(),t.h=n.getHours(),t.i=n.getMinutes()}return t},_create:function(e){var t=this;e=e||{},e.labels=e.labels||["年","月","日","时","分"],e.buttons=e.buttons||["取消","确定"],e.type=e.type||"datetime",e.customData=e.customData||{},t.options=e;var i=new Date,n=e.beginDate;n instanceof Date&&!isNaN(n.valueOf())&&(e.beginYear=n.getFullYear(),e.beginMonth=n.getMonth()+1,e.beginDay=n.getDate(),e.beginHours=n.getHours(),e.beginMinutes=n.getMinutes());var a=e.endDate;a instanceof Date&&!isNaN(a.valueOf())&&(e.endYear=a.getFullYear(),e.endMonth=a.getMonth()+1,e.endDay=a.getDate(),e.endHours=a.getHours(),e.endMinutes=a.getMinutes()),e.beginYear=e.beginYear||i.getFullYear()-5,e.endYear=e.endYear||i.getFullYear()+5;var r=t.ui;t._setLabels(),t._setButtons(),r.picker.setAttribute("data-type",e.type),t._createYear(),t._createMonth(),t._createDay(),t._createHours(),t._createMinutes(),t.setSelectedValue(e.value)},show:function(i){var n=this,a=n.ui;n.callback=i||e.noop,a.mask.show(),t.body.classList.add(e.className("dtpicker-active-for-page")),a.picker.classList.add(e.className("active")),n.__back=e.back,e.back=function(){n.hide()}},hide:function(){var i=this;if(!i.disposed){var n=i.ui;n.picker.classList.remove(e.className("active")),n.mask.close(),t.body.classList.remove(e.className("dtpicker-active-for-page")),e.back=i.__back}},dispose:function(){var e=this;e.hide(),setTimeout(function(){e.ui.picker.parentNode.removeChild(e.ui.picker);for(var t in e)e[t]=null,delete e[t];e.disposed=!0},300)}})}(mui,document); -------------------------------------------------------------------------------- /js/zepto.min.js: -------------------------------------------------------------------------------- 1 | /* Zepto v1.1.6 - zepto event ajax form ie - zeptojs.com/license */ 2 | var Zepto=function(){function L(t){return null==t?String(t):j[S.call(t)]||"object"}function Z(t){return"function"==L(t)}function _(t){return null!=t&&t==t.window}function $(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function D(t){return"object"==L(t)}function M(t){return D(t)&&!_(t)&&Object.getPrototypeOf(t)==Object.prototype}function R(t){return"number"==typeof t.length}function k(t){return s.call(t,function(t){return null!=t})}function z(t){return t.length>0?n.fn.concat.apply([],t):t}function F(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function q(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function H(t,e){return"number"!=typeof e||c[F(t)]?e:e+"px"}function I(t){var e,n;return u[t]||(e=a.createElement(t),a.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),u[t]=n),u[t]}function V(t){return"children"in t?o.call(t.children):n.map(t.childNodes,function(t){return 1==t.nodeType?t:void 0})}function B(n,i,r){for(e in i)r&&(M(i[e])||A(i[e]))?(M(i[e])&&!M(n[e])&&(n[e]={}),A(i[e])&&!A(n[e])&&(n[e]=[]),B(n[e],i[e],r)):i[e]!==t&&(n[e]=i[e])}function U(t,e){return null==e?n(t):n(t).filter(e)}function J(t,e,n,i){return Z(e)?e.call(t,n,i):e}function X(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function W(e,n){var i=e.className||"",r=i&&i.baseVal!==t;return n===t?r?i.baseVal:i:void(r?i.baseVal=n:e.className=n)}function Y(t){try{return t?"true"==t||("false"==t?!1:"null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?n.parseJSON(t):t):t}catch(e){return t}}function G(t,e){e(t);for(var n=0,i=t.childNodes.length;i>n;n++)G(t.childNodes[n],e)}var t,e,n,i,C,N,r=[],o=r.slice,s=r.filter,a=window.document,u={},f={},c={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},l=/^\s*<(\w+|!)[^>]*>/,h=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,p=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,d=/^(?:body|html)$/i,m=/([A-Z])/g,g=["val","css","html","text","data","width","height","offset"],v=["after","prepend","before","append"],y=a.createElement("table"),x=a.createElement("tr"),b={tr:a.createElement("tbody"),tbody:y,thead:y,tfoot:y,td:x,th:x,"*":a.createElement("div")},w=/complete|loaded|interactive/,E=/^[\w-]*$/,j={},S=j.toString,T={},O=a.createElement("div"),P={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},A=Array.isArray||function(t){return t instanceof Array};return T.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,r=t.parentNode,o=!r;return o&&(r=O).appendChild(t),i=~T.qsa(r,e).indexOf(t),o&&O.removeChild(t),i},C=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},N=function(t){return s.call(t,function(e,n){return t.indexOf(e)==n})},T.fragment=function(e,i,r){var s,u,f;return h.test(e)&&(s=n(a.createElement(RegExp.$1))),s||(e.replace&&(e=e.replace(p,"<$1>")),i===t&&(i=l.test(e)&&RegExp.$1),i in b||(i="*"),f=b[i],f.innerHTML=""+e,s=n.each(o.call(f.childNodes),function(){f.removeChild(this)})),M(r)&&(u=n(s),n.each(r,function(t,e){g.indexOf(t)>-1?u[t](e):u.attr(t,e)})),s},T.Z=function(t,e){return t=t||[],t.__proto__=n.fn,t.selector=e||"",t},T.isZ=function(t){return t instanceof T.Z},T.init=function(e,i){var r;if(!e)return T.Z();if("string"==typeof e)if(e=e.trim(),"<"==e[0]&&l.test(e))r=T.fragment(e,RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}else{if(Z(e))return n(a).ready(e);if(T.isZ(e))return e;if(A(e))r=k(e);else if(D(e))r=[e],e=null;else if(l.test(e))r=T.fragment(e.trim(),RegExp.$1,i),e=null;else{if(i!==t)return n(i).find(e);r=T.qsa(a,e)}}return T.Z(r,e)},n=function(t,e){return T.init(t,e)},n.extend=function(t){var e,n=o.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){B(t,n,e)}),t},T.qsa=function(t,e){var n,i="#"==e[0],r=!i&&"."==e[0],s=i||r?e.slice(1):e,a=E.test(s);return $(t)&&a&&i?(n=t.getElementById(s))?[n]:[]:1!==t.nodeType&&9!==t.nodeType?[]:o.call(a&&!i?r?t.getElementsByClassName(s):t.getElementsByTagName(e):t.querySelectorAll(e))},n.contains=a.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},n.type=L,n.isFunction=Z,n.isWindow=_,n.isArray=A,n.isPlainObject=M,n.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},n.inArray=function(t,e,n){return r.indexOf.call(e,t,n)},n.camelCase=C,n.trim=function(t){return null==t?"":String.prototype.trim.call(t)},n.uuid=0,n.support={},n.expr={},n.map=function(t,e){var n,r,o,i=[];if(R(t))for(r=0;r=0?e:e+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return r.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return Z(t)?this.not(this.not(t)):n(s.call(this,function(e){return T.matches(e,t)}))},add:function(t,e){return n(N(this.concat(n(t,e))))},is:function(t){return this.length>0&&T.matches(this[0],t)},not:function(e){var i=[];if(Z(e)&&e.call!==t)this.each(function(t){e.call(this,t)||i.push(this)});else{var r="string"==typeof e?this.filter(e):R(e)&&Z(e.item)?o.call(e):n(e);this.forEach(function(t){r.indexOf(t)<0&&i.push(t)})}return n(i)},has:function(t){return this.filter(function(){return D(t)?n.contains(this,t):n(this).find(t).size()})},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!D(t)?t:n(t)},last:function(){var t=this[this.length-1];return t&&!D(t)?t:n(t)},find:function(t){var e,i=this;return e=t?"object"==typeof t?n(t).filter(function(){var t=this;return r.some.call(i,function(e){return n.contains(e,t)})}):1==this.length?n(T.qsa(this[0],t)):this.map(function(){return T.qsa(this,t)}):n()},closest:function(t,e){var i=this[0],r=!1;for("object"==typeof t&&(r=n(t));i&&!(r?r.indexOf(i)>=0:T.matches(i,t));)i=i!==e&&!$(i)&&i.parentNode;return n(i)},parents:function(t){for(var e=[],i=this;i.length>0;)i=n.map(i,function(t){return(t=t.parentNode)&&!$(t)&&e.indexOf(t)<0?(e.push(t),t):void 0});return U(e,t)},parent:function(t){return U(N(this.pluck("parentNode")),t)},children:function(t){return U(this.map(function(){return V(this)}),t)},contents:function(){return this.map(function(){return o.call(this.childNodes)})},siblings:function(t){return U(this.map(function(t,e){return s.call(V(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return n.map(this,function(e){return e[t]})},show:function(){return this.each(function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=I(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=Z(t);if(this[0]&&!e)var i=n(t).get(0),r=i.parentNode||this.length>1;return this.each(function(o){n(this).wrapAll(e?t.call(this,o):r?i.cloneNode(!0):i)})},wrapAll:function(t){if(this[0]){n(this[0]).before(t=n(t));for(var e;(e=t.children()).length;)t=e.first();n(t).append(this)}return this},wrapInner:function(t){var e=Z(t);return this.each(function(i){var r=n(this),o=r.contents(),s=e?t.call(this,i):t;o.length?o.wrapAll(s):r.append(s)})},unwrap:function(){return this.parent().each(function(){n(this).replaceWith(n(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(e){return this.each(function(){var i=n(this);(e===t?"none"==i.css("display"):e)?i.show():i.hide()})},prev:function(t){return n(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return n(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var i=this.innerHTML;n(this).empty().append(J(this,t,e,i))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=J(this,t,e,this.textContent);this.textContent=null==n?"":""+n}):0 in this?this[0].textContent:null},attr:function(n,i){var r;return"string"!=typeof n||1 in arguments?this.each(function(t){if(1===this.nodeType)if(D(n))for(e in n)X(this,e,n[e]);else X(this,n,J(this,i,t,this.getAttribute(n)))}):this.length&&1===this[0].nodeType?!(r=this[0].getAttribute(n))&&n in this[0]?this[0][n]:r:t},removeAttr:function(t){return this.each(function(){1===this.nodeType&&t.split(" ").forEach(function(t){X(this,t)},this)})},prop:function(t,e){return t=P[t]||t,1 in arguments?this.each(function(n){this[t]=J(this,e,n,this[t])}):this[0]&&this[0][t]},data:function(e,n){var i="data-"+e.replace(m,"-$1").toLowerCase(),r=1 in arguments?this.attr(i,n):this.attr(i);return null!==r?Y(r):t},val:function(t){return 0 in arguments?this.each(function(e){this.value=J(this,t,e,this.value)}):this[0]&&(this[0].multiple?n(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var i=n(this),r=J(this,t,e,i.offset()),o=i.offsetParent().offset(),s={top:r.top-o.top,left:r.left-o.left};"static"==i.css("position")&&(s.position="relative"),i.css(s)});if(!this.length)return null;var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(t,i){if(arguments.length<2){var r,o=this[0];if(!o)return;if(r=getComputedStyle(o,""),"string"==typeof t)return o.style[C(t)]||r.getPropertyValue(t);if(A(t)){var s={};return n.each(t,function(t,e){s[e]=o.style[C(e)]||r.getPropertyValue(e)}),s}}var a="";if("string"==L(t))i||0===i?a=F(t)+":"+H(t,i):this.each(function(){this.style.removeProperty(F(t))});else for(e in t)t[e]||0===t[e]?a+=F(e)+":"+H(e,t[e])+";":this.each(function(){this.style.removeProperty(F(e))});return this.each(function(){this.style.cssText+=";"+a})},index:function(t){return t?this.indexOf(n(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return t?r.some.call(this,function(t){return this.test(W(t))},q(t)):!1},addClass:function(t){return t?this.each(function(e){if("className"in this){i=[];var r=W(this),o=J(this,t,e,r);o.split(/\s+/g).forEach(function(t){n(this).hasClass(t)||i.push(t)},this),i.length&&W(this,r+(r?" ":"")+i.join(" "))}}):this},removeClass:function(e){return this.each(function(n){if("className"in this){if(e===t)return W(this,"");i=W(this),J(this,e,n,i).split(/\s+/g).forEach(function(t){i=i.replace(q(t)," ")}),W(this,i.trim())}})},toggleClass:function(e,i){return e?this.each(function(r){var o=n(this),s=J(this,e,r,W(this));s.split(/\s+/g).forEach(function(e){(i===t?!o.hasClass(e):i)?o.addClass(e):o.removeClass(e)})}):this},scrollTop:function(e){if(this.length){var n="scrollTop"in this[0];return e===t?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=e}:function(){this.scrollTo(this.scrollX,e)})}},scrollLeft:function(e){if(this.length){var n="scrollLeft"in this[0];return e===t?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=e}:function(){this.scrollTo(e,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),i=this.offset(),r=d.test(e[0].nodeName)?{top:0,left:0}:e.offset();return i.top-=parseFloat(n(t).css("margin-top"))||0,i.left-=parseFloat(n(t).css("margin-left"))||0,r.top+=parseFloat(n(e[0]).css("border-top-width"))||0,r.left+=parseFloat(n(e[0]).css("border-left-width"))||0,{top:i.top-r.top,left:i.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||a.body;t&&!d.test(t.nodeName)&&"static"==n(t).css("position");)t=t.offsetParent;return t})}},n.fn.detach=n.fn.remove,["width","height"].forEach(function(e){var i=e.replace(/./,function(t){return t[0].toUpperCase()});n.fn[e]=function(r){var o,s=this[0];return r===t?_(s)?s["inner"+i]:$(s)?s.documentElement["scroll"+i]:(o=this.offset())&&o[e]:this.each(function(t){s=n(this),s.css(e,J(this,r,t,s[e]()))})}}),v.forEach(function(t,e){var i=e%2;n.fn[t]=function(){var t,o,r=n.map(arguments,function(e){return t=L(e),"object"==t||"array"==t||null==e?e:T.fragment(e)}),s=this.length>1;return r.length<1?this:this.each(function(t,u){o=i?u:u.parentNode,u=0==e?u.nextSibling:1==e?u.firstChild:2==e?u:null;var f=n.contains(a.documentElement,o);r.forEach(function(t){if(s)t=t.cloneNode(!0);else if(!o)return n(t).remove();o.insertBefore(t,u),f&&G(t,function(t){null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src||window.eval.call(window,t.innerHTML)})})})},n.fn[i?t+"To":"insert"+(e?"Before":"After")]=function(e){return n(e)[t](this),this}}),T.Z.prototype=n.fn,T.uniq=N,T.deserializeValue=Y,n.zepto=T,n}();window.Zepto=Zepto,void 0===window.$&&(window.$=Zepto),function(t){function l(t){return t._zid||(t._zid=e++)}function h(t,e,n,i){if(e=p(e),e.ns)var r=d(e.ns);return(s[l(t)]||[]).filter(function(t){return!(!t||e.e&&t.e!=e.e||e.ns&&!r.test(t.ns)||n&&l(t.fn)!==l(n)||i&&t.sel!=i)})}function p(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function d(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!u&&t.e in f||!!e}function g(t){return c[t]||u&&f[t]||t}function v(e,i,r,o,a,u,f){var h=l(e),d=s[h]||(s[h]=[]);i.split(/\s/).forEach(function(i){if("ready"==i)return t(document).ready(r);var s=p(i);s.fn=r,s.sel=a,s.e in c&&(r=function(e){var n=e.relatedTarget;return!n||n!==this&&!t.contains(this,n)?s.fn.apply(this,arguments):void 0}),s.del=u;var l=u||r;s.proxy=function(t){if(t=j(t),!t.isImmediatePropagationStopped()){t.data=o;var i=l.apply(e,t._args==n?[t]:[t].concat(t._args));return i===!1&&(t.preventDefault(),t.stopPropagation()),i}},s.i=d.length,d.push(s),"addEventListener"in e&&e.addEventListener(g(s.e),s.proxy,m(s,f))})}function y(t,e,n,i,r){var o=l(t);(e||"").split(/\s/).forEach(function(e){h(t,e,n,i).forEach(function(e){delete s[o][e.i],"removeEventListener"in t&&t.removeEventListener(g(e.e),e.proxy,m(e,r))})})}function j(e,i){return(i||!e.isDefaultPrevented)&&(i||(i=e),t.each(E,function(t,n){var r=i[t];e[t]=function(){return this[n]=x,r&&r.apply(i,arguments)},e[n]=b}),(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?i.returnValue===!1:i.getPreventDefault&&i.getPreventDefault())&&(e.isDefaultPrevented=x)),e}function S(t){var e,i={originalEvent:t};for(e in t)w.test(e)||t[e]===n||(i[e]=t[e]);return j(i,t)}var n,e=1,i=Array.prototype.slice,r=t.isFunction,o=function(t){return"string"==typeof t},s={},a={},u="onfocusin"in window,f={focus:"focusin",blur:"focusout"},c={mouseenter:"mouseover",mouseleave:"mouseout"};a.click=a.mousedown=a.mouseup=a.mousemove="MouseEvents",t.event={add:v,remove:y},t.proxy=function(e,n){var s=2 in arguments&&i.call(arguments,2);if(r(e)){var a=function(){return e.apply(n,s?s.concat(i.call(arguments)):arguments)};return a._zid=l(e),a}if(o(n))return s?(s.unshift(e[n],e),t.proxy.apply(null,s)):t.proxy(e[n],e);throw new TypeError("expected function")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var x=function(){return!0},b=function(){return!1},w=/^([A-Z]|returnValue$|layer[XY]$)/,E={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,s,a,u,f){var c,l,h=this;return e&&!o(e)?(t.each(e,function(t,e){h.on(t,s,a,e,f)}),h):(o(s)||r(u)||u===!1||(u=a,a=s,s=n),(r(a)||a===!1)&&(u=a,a=n),u===!1&&(u=b),h.each(function(n,r){f&&(c=function(t){return y(r,t.type,u),u.apply(this,arguments)}),s&&(l=function(e){var n,o=t(e.target).closest(s,r).get(0);return o&&o!==r?(n=t.extend(S(e),{currentTarget:o,liveFired:r}),(c||u).apply(o,[n].concat(i.call(arguments,1)))):void 0}),v(r,e,u,a,s,l||c)}))},t.fn.off=function(e,i,s){var a=this;return e&&!o(e)?(t.each(e,function(t,e){a.off(t,i,e)}),a):(o(i)||r(s)||s===!1||(s=i,i=n),s===!1&&(s=b),a.each(function(){y(this,e,s,i)}))},t.fn.trigger=function(e,n){return e=o(e)||t.isPlainObject(e)?t.Event(e):j(e),e._args=n,this.each(function(){e.type in f&&"function"==typeof this[e.type]?this[e.type]():"dispatchEvent"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,n){var i,r;return this.each(function(s,a){i=S(o(e)?t.Event(e):e),i._args=n,i.target=a,t.each(h(a,e.type||e),function(t,e){return r=e.proxy(i),i.isImmediatePropagationStopped()?!1:void 0})}),r},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e){t.fn[e]=function(t){return 0 in arguments?this.bind(e,t):this.trigger(e)}}),t.Event=function(t,e){o(t)||(e=t,t=e.type);var n=document.createEvent(a[t]||"Events"),i=!0;if(e)for(var r in e)"bubbles"==r?i=!!e[r]:n[r]=e[r];return n.initEvent(t,i,!0),j(n)}}(Zepto),function(t){function h(e,n,i){var r=t.Event(n);return t(e).trigger(r,i),!r.isDefaultPrevented()}function p(t,e,i,r){return t.global?h(e||n,i,r):void 0}function d(e){e.global&&0===t.active++&&p(e,null,"ajaxStart")}function m(e){e.global&&!--t.active&&p(e,null,"ajaxStop")}function g(t,e){var n=e.context;return e.beforeSend.call(n,t,e)===!1||p(e,n,"ajaxBeforeSend",[t,e])===!1?!1:void p(e,n,"ajaxSend",[t,e])}function v(t,e,n,i){var r=n.context,o="success";n.success.call(r,t,o,e),i&&i.resolveWith(r,[t,o,e]),p(n,r,"ajaxSuccess",[e,n,t]),x(o,e,n)}function y(t,e,n,i,r){var o=i.context;i.error.call(o,n,e,t),r&&r.rejectWith(o,[n,e,t]),p(i,o,"ajaxError",[n,i,t||e]),x(e,n,i)}function x(t,e,n){var i=n.context;n.complete.call(i,e,t),p(n,i,"ajaxComplete",[e,n]),m(n)}function b(){}function w(t){return t&&(t=t.split(";",2)[0]),t&&(t==f?"html":t==u?"json":s.test(t)?"script":a.test(t)&&"xml")||"text"}function E(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function j(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()||(e.url=E(e.url,e.data),e.data=void 0)}function S(e,n,i,r){return t.isFunction(n)&&(r=i,i=n,n=void 0),t.isFunction(i)||(r=i,i=void 0),{url:e,data:n,success:i,dataType:r}}function C(e,n,i,r){var o,s=t.isArray(n),a=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),r&&(n=i?r:r+"["+(a||"object"==o||"array"==o?n:"")+"]"),!r&&s?e.add(u.name,u.value):"array"==o||!i&&"object"==o?C(e,u,i,n):e.add(n,u)})}var i,r,e=0,n=window.document,o=/)<[^<]*)*<\/script>/gi,s=/^(?:text|application)\/javascript/i,a=/^(?:text|application)\/xml/i,u="application/json",f="text/html",c=/^\s*$/,l=n.createElement("a");l.href=window.location.href,t.active=0,t.ajaxJSONP=function(i,r){if(!("type"in i))return t.ajax(i);var f,h,o=i.jsonpCallback,s=(t.isFunction(o)?o():o)||"jsonp"+ ++e,a=n.createElement("script"),u=window[s],c=function(e){t(a).triggerHandler("error",e||"abort")},l={abort:c};return r&&r.promise(l),t(a).on("load error",function(e,n){clearTimeout(h),t(a).off().remove(),"error"!=e.type&&f?v(f[0],l,i,r):y(null,n||"error",l,i,r),window[s]=u,f&&t.isFunction(u)&&u(f[0]),u=f=void 0}),g(l,i)===!1?(c("abort"),l):(window[s]=function(){f=arguments},a.src=i.url.replace(/\?(.+)=\?/,"?$1="+s),n.head.appendChild(a),i.timeout>0&&(h=setTimeout(function(){c("timeout")},i.timeout)),l)},t.ajaxSettings={type:"GET",beforeSend:b,success:b,error:b,complete:b,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:u,xml:"application/xml, text/xml",html:f,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0},t.ajax=function(e){var a,o=t.extend({},e||{}),s=t.Deferred&&t.Deferred();for(i in t.ajaxSettings)void 0===o[i]&&(o[i]=t.ajaxSettings[i]);d(o),o.crossDomain||(a=n.createElement("a"),a.href=o.url,a.href=a.href,o.crossDomain=l.protocol+"//"+l.host!=a.protocol+"//"+a.host),o.url||(o.url=window.location.toString()),j(o);var u=o.dataType,f=/\?.+=\?/.test(o.url);if(f&&(u="jsonp"),o.cache!==!1&&(e&&e.cache===!0||"script"!=u&&"jsonp"!=u)||(o.url=E(o.url,"_="+Date.now())),"jsonp"==u)return f||(o.url=E(o.url,o.jsonp?o.jsonp+"=?":o.jsonp===!1?"":"callback=?")),t.ajaxJSONP(o,s);var C,h=o.accepts[u],p={},m=function(t,e){p[t.toLowerCase()]=[t,e]},x=/^([\w-]+:)\/\//.test(o.url)?RegExp.$1:window.location.protocol,S=o.xhr(),T=S.setRequestHeader;if(s&&s.promise(S),o.crossDomain||m("X-Requested-With","XMLHttpRequest"),m("Accept",h||"*/*"),(h=o.mimeType||h)&&(h.indexOf(",")>-1&&(h=h.split(",",2)[0]),S.overrideMimeType&&S.overrideMimeType(h)),(o.contentType||o.contentType!==!1&&o.data&&"GET"!=o.type.toUpperCase())&&m("Content-Type",o.contentType||"application/x-www-form-urlencoded"),o.headers)for(r in o.headers)m(r,o.headers[r]);if(S.setRequestHeader=m,S.onreadystatechange=function(){if(4==S.readyState){S.onreadystatechange=b,clearTimeout(C);var e,n=!1;if(S.status>=200&&S.status<300||304==S.status||0==S.status&&"file:"==x){u=u||w(o.mimeType||S.getResponseHeader("content-type")),e=S.responseText;try{"script"==u?(1,eval)(e):"xml"==u?e=S.responseXML:"json"==u&&(e=c.test(e)?null:t.parseJSON(e))}catch(i){n=i}n?y(n,"parsererror",S,o,s):v(e,S,o,s)}else y(S.statusText||null,S.status?"error":"abort",S,o,s)}},g(S,o)===!1)return S.abort(),y(null,"abort",S,o,s),S;if(o.xhrFields)for(r in o.xhrFields)S[r]=o.xhrFields[r];var N="async"in o?o.async:!0;S.open(o.type,o.url,N,o.username,o.password);for(r in p)T.apply(S,p[r]);return o.timeout>0&&(C=setTimeout(function(){S.onreadystatechange=b,S.abort(),y(null,"timeout",S,o,s)},o.timeout)),S.send(o.data?o.data:null),S},t.get=function(){return t.ajax(S.apply(null,arguments))},t.post=function(){var e=S.apply(null,arguments);return e.type="POST",t.ajax(e)},t.getJSON=function(){var e=S.apply(null,arguments);return e.dataType="json",t.ajax(e)},t.fn.load=function(e,n,i){if(!this.length)return this;var a,r=this,s=e.split(/\s/),u=S(e,n,i),f=u.success;return s.length>1&&(u.url=s[0],a=s[1]),u.success=function(e){r.html(a?t("
    ").html(e.replace(o,"")).find(a):e),f&&f.apply(r,arguments)},t.ajax(u),this};var T=encodeURIComponent;t.param=function(e,n){var i=[];return i.add=function(e,n){t.isFunction(n)&&(n=n()),null==n&&(n=""),this.push(T(e)+"="+T(n))},C(i,e,n),i.join("&").replace(/%20/g,"+")}}(Zepto),function(t){t.fn.serializeArray=function(){var e,n,i=[],r=function(t){return t.forEach?t.forEach(r):void i.push({name:e,value:t})};return this[0]&&t.each(this[0].elements,function(i,o){n=o.type,e=o.name,e&&"fieldset"!=o.nodeName.toLowerCase()&&!o.disabled&&"submit"!=n&&"reset"!=n&&"button"!=n&&"file"!=n&&("radio"!=n&&"checkbox"!=n||o.checked)&&r(t(o).val())}),i},t.fn.serialize=function(){var t=[];return this.serializeArray().forEach(function(e){t.push(encodeURIComponent(e.name)+"="+encodeURIComponent(e.value))}),t.join("&")},t.fn.submit=function(e){if(0 in arguments)this.bind("submit",e);else if(this.length){var n=t.Event("submit");this.eq(0).trigger(n),n.isDefaultPrevented()||this.get(0).submit()}return this}}(Zepto),function(t){"__proto__"in{}||t.extend(t.zepto,{Z:function(e,n){return e=e||[],t.extend(e,t.fn),e.selector=n||"",e.__Z=!0,e},isZ:function(e){return"array"===t.type(e)&&"__Z"in e}});try{getComputedStyle(void 0)}catch(e){var n=getComputedStyle;window.getComputedStyle=function(t){try{return n(t)}catch(e){return null}}}}(Zepto); -------------------------------------------------------------------------------- /js/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.8.3 2 | // http://underscorejs.org 3 | // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | 6 | (function() { 7 | 8 | // Baseline setup 9 | // -------------- 10 | 11 | // Establish the root object, `window` in the browser, or `exports` on the server. 12 | var root = this; 13 | 14 | // Save the previous value of the `_` variable. 15 | var previousUnderscore = root._; 16 | 17 | // Save bytes in the minified (but not gzipped) version: 18 | var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; 19 | 20 | // Create quick reference variables for speed access to core prototypes. 21 | var 22 | push = ArrayProto.push, 23 | slice = ArrayProto.slice, 24 | toString = ObjProto.toString, 25 | hasOwnProperty = ObjProto.hasOwnProperty; 26 | 27 | // All **ECMAScript 5** native function implementations that we hope to use 28 | // are declared here. 29 | var 30 | nativeIsArray = Array.isArray, 31 | nativeKeys = Object.keys, 32 | nativeBind = FuncProto.bind, 33 | nativeCreate = Object.create; 34 | 35 | // Naked function reference for surrogate-prototype-swapping. 36 | var Ctor = function(){}; 37 | 38 | // Create a safe reference to the Underscore object for use below. 39 | var _ = function(obj) { 40 | if (obj instanceof _) return obj; 41 | if (!(this instanceof _)) return new _(obj); 42 | this._wrapped = obj; 43 | }; 44 | 45 | // Export the Underscore object for **Node.js**, with 46 | // backwards-compatibility for the old `require()` API. If we're in 47 | // the browser, add `_` as a global object. 48 | if (typeof exports !== 'undefined') { 49 | if (typeof module !== 'undefined' && module.exports) { 50 | exports = module.exports = _; 51 | } 52 | exports._ = _; 53 | } else { 54 | root._ = _; 55 | } 56 | 57 | // Current version. 58 | _.VERSION = '1.8.3'; 59 | 60 | // Internal function that returns an efficient (for current engines) version 61 | // of the passed-in callback, to be repeatedly applied in other Underscore 62 | // functions. 63 | var optimizeCb = function(func, context, argCount) { 64 | if (context === void 0) return func; 65 | switch (argCount == null ? 3 : argCount) { 66 | case 1: return function(value) { 67 | return func.call(context, value); 68 | }; 69 | case 2: return function(value, other) { 70 | return func.call(context, value, other); 71 | }; 72 | case 3: return function(value, index, collection) { 73 | return func.call(context, value, index, collection); 74 | }; 75 | case 4: return function(accumulator, value, index, collection) { 76 | return func.call(context, accumulator, value, index, collection); 77 | }; 78 | } 79 | return function() { 80 | return func.apply(context, arguments); 81 | }; 82 | }; 83 | 84 | // A mostly-internal function to generate callbacks that can be applied 85 | // to each element in a collection, returning the desired result 鈥� either 86 | // identity, an arbitrary callback, a property matcher, or a property accessor. 87 | var cb = function(value, context, argCount) { 88 | if (value == null) return _.identity; 89 | if (_.isFunction(value)) return optimizeCb(value, context, argCount); 90 | if (_.isObject(value)) return _.matcher(value); 91 | return _.property(value); 92 | }; 93 | _.iteratee = function(value, context) { 94 | return cb(value, context, Infinity); 95 | }; 96 | 97 | // An internal function for creating assigner functions. 98 | var createAssigner = function(keysFunc, undefinedOnly) { 99 | return function(obj) { 100 | var length = arguments.length; 101 | if (length < 2 || obj == null) return obj; 102 | for (var index = 1; index < length; index++) { 103 | var source = arguments[index], 104 | keys = keysFunc(source), 105 | l = keys.length; 106 | for (var i = 0; i < l; i++) { 107 | var key = keys[i]; 108 | if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; 109 | } 110 | } 111 | return obj; 112 | }; 113 | }; 114 | 115 | // An internal function for creating a new object that inherits from another. 116 | var baseCreate = function(prototype) { 117 | if (!_.isObject(prototype)) return {}; 118 | if (nativeCreate) return nativeCreate(prototype); 119 | Ctor.prototype = prototype; 120 | var result = new Ctor; 121 | Ctor.prototype = null; 122 | return result; 123 | }; 124 | 125 | var property = function(key) { 126 | return function(obj) { 127 | return obj == null ? void 0 : obj[key]; 128 | }; 129 | }; 130 | 131 | // Helper for collection methods to determine whether a collection 132 | // should be iterated as an array or as an object 133 | // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength 134 | // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 135 | var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; 136 | var getLength = property('length'); 137 | var isArrayLike = function(collection) { 138 | var length = getLength(collection); 139 | return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; 140 | }; 141 | 142 | // Collection Functions 143 | // -------------------- 144 | 145 | // The cornerstone, an `each` implementation, aka `forEach`. 146 | // Handles raw objects in addition to array-likes. Treats all 147 | // sparse array-likes as if they were dense. 148 | _.each = _.forEach = function(obj, iteratee, context) { 149 | iteratee = optimizeCb(iteratee, context); 150 | var i, length; 151 | if (isArrayLike(obj)) { 152 | for (i = 0, length = obj.length; i < length; i++) { 153 | iteratee(obj[i], i, obj); 154 | } 155 | } else { 156 | var keys = _.keys(obj); 157 | for (i = 0, length = keys.length; i < length; i++) { 158 | iteratee(obj[keys[i]], keys[i], obj); 159 | } 160 | } 161 | return obj; 162 | }; 163 | 164 | // Return the results of applying the iteratee to each element. 165 | _.map = _.collect = function(obj, iteratee, context) { 166 | iteratee = cb(iteratee, context); 167 | var keys = !isArrayLike(obj) && _.keys(obj), 168 | length = (keys || obj).length, 169 | results = Array(length); 170 | for (var index = 0; index < length; index++) { 171 | var currentKey = keys ? keys[index] : index; 172 | results[index] = iteratee(obj[currentKey], currentKey, obj); 173 | } 174 | return results; 175 | }; 176 | 177 | // Create a reducing function iterating left or right. 178 | function createReduce(dir) { 179 | // Optimized iterator function as using arguments.length 180 | // in the main function will deoptimize the, see #1991. 181 | function iterator(obj, iteratee, memo, keys, index, length) { 182 | for (; index >= 0 && index < length; index += dir) { 183 | var currentKey = keys ? keys[index] : index; 184 | memo = iteratee(memo, obj[currentKey], currentKey, obj); 185 | } 186 | return memo; 187 | } 188 | 189 | return function(obj, iteratee, memo, context) { 190 | iteratee = optimizeCb(iteratee, context, 4); 191 | var keys = !isArrayLike(obj) && _.keys(obj), 192 | length = (keys || obj).length, 193 | index = dir > 0 ? 0 : length - 1; 194 | // Determine the initial value if none is provided. 195 | if (arguments.length < 3) { 196 | memo = obj[keys ? keys[index] : index]; 197 | index += dir; 198 | } 199 | return iterator(obj, iteratee, memo, keys, index, length); 200 | }; 201 | } 202 | 203 | // **Reduce** builds up a single result from a list of values, aka `inject`, 204 | // or `foldl`. 205 | _.reduce = _.foldl = _.inject = createReduce(1); 206 | 207 | // The right-associative version of reduce, also known as `foldr`. 208 | _.reduceRight = _.foldr = createReduce(-1); 209 | 210 | // Return the first value which passes a truth test. Aliased as `detect`. 211 | _.find = _.detect = function(obj, predicate, context) { 212 | var key; 213 | if (isArrayLike(obj)) { 214 | key = _.findIndex(obj, predicate, context); 215 | } else { 216 | key = _.findKey(obj, predicate, context); 217 | } 218 | if (key !== void 0 && key !== -1) return obj[key]; 219 | }; 220 | 221 | // Return all the elements that pass a truth test. 222 | // Aliased as `select`. 223 | _.filter = _.select = function(obj, predicate, context) { 224 | var results = []; 225 | predicate = cb(predicate, context); 226 | _.each(obj, function(value, index, list) { 227 | if (predicate(value, index, list)) results.push(value); 228 | }); 229 | return results; 230 | }; 231 | 232 | // Return all the elements for which a truth test fails. 233 | _.reject = function(obj, predicate, context) { 234 | return _.filter(obj, _.negate(cb(predicate)), context); 235 | }; 236 | 237 | // Determine whether all of the elements match a truth test. 238 | // Aliased as `all`. 239 | _.every = _.all = function(obj, predicate, context) { 240 | predicate = cb(predicate, context); 241 | var keys = !isArrayLike(obj) && _.keys(obj), 242 | length = (keys || obj).length; 243 | for (var index = 0; index < length; index++) { 244 | var currentKey = keys ? keys[index] : index; 245 | if (!predicate(obj[currentKey], currentKey, obj)) return false; 246 | } 247 | return true; 248 | }; 249 | 250 | // Determine if at least one element in the object matches a truth test. 251 | // Aliased as `any`. 252 | _.some = _.any = function(obj, predicate, context) { 253 | predicate = cb(predicate, context); 254 | var keys = !isArrayLike(obj) && _.keys(obj), 255 | length = (keys || obj).length; 256 | for (var index = 0; index < length; index++) { 257 | var currentKey = keys ? keys[index] : index; 258 | if (predicate(obj[currentKey], currentKey, obj)) return true; 259 | } 260 | return false; 261 | }; 262 | 263 | // Determine if the array or object contains a given item (using `===`). 264 | // Aliased as `includes` and `include`. 265 | _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { 266 | if (!isArrayLike(obj)) obj = _.values(obj); 267 | if (typeof fromIndex != 'number' || guard) fromIndex = 0; 268 | return _.indexOf(obj, item, fromIndex) >= 0; 269 | }; 270 | 271 | // Invoke a method (with arguments) on every item in a collection. 272 | _.invoke = function(obj, method) { 273 | var args = slice.call(arguments, 2); 274 | var isFunc = _.isFunction(method); 275 | return _.map(obj, function(value) { 276 | var func = isFunc ? method : value[method]; 277 | return func == null ? func : func.apply(value, args); 278 | }); 279 | }; 280 | 281 | // Convenience version of a common use case of `map`: fetching a property. 282 | _.pluck = function(obj, key) { 283 | return _.map(obj, _.property(key)); 284 | }; 285 | 286 | // Convenience version of a common use case of `filter`: selecting only objects 287 | // containing specific `key:value` pairs. 288 | _.where = function(obj, attrs) { 289 | return _.filter(obj, _.matcher(attrs)); 290 | }; 291 | 292 | // Convenience version of a common use case of `find`: getting the first object 293 | // containing specific `key:value` pairs. 294 | _.findWhere = function(obj, attrs) { 295 | return _.find(obj, _.matcher(attrs)); 296 | }; 297 | 298 | // Return the maximum element (or element-based computation). 299 | _.max = function(obj, iteratee, context) { 300 | var result = -Infinity, lastComputed = -Infinity, 301 | value, computed; 302 | if (iteratee == null && obj != null) { 303 | obj = isArrayLike(obj) ? obj : _.values(obj); 304 | for (var i = 0, length = obj.length; i < length; i++) { 305 | value = obj[i]; 306 | if (value > result) { 307 | result = value; 308 | } 309 | } 310 | } else { 311 | iteratee = cb(iteratee, context); 312 | _.each(obj, function(value, index, list) { 313 | computed = iteratee(value, index, list); 314 | if (computed > lastComputed || computed === -Infinity && result === -Infinity) { 315 | result = value; 316 | lastComputed = computed; 317 | } 318 | }); 319 | } 320 | return result; 321 | }; 322 | 323 | // Return the minimum element (or element-based computation). 324 | _.min = function(obj, iteratee, context) { 325 | var result = Infinity, lastComputed = Infinity, 326 | value, computed; 327 | if (iteratee == null && obj != null) { 328 | obj = isArrayLike(obj) ? obj : _.values(obj); 329 | for (var i = 0, length = obj.length; i < length; i++) { 330 | value = obj[i]; 331 | if (value < result) { 332 | result = value; 333 | } 334 | } 335 | } else { 336 | iteratee = cb(iteratee, context); 337 | _.each(obj, function(value, index, list) { 338 | computed = iteratee(value, index, list); 339 | if (computed < lastComputed || computed === Infinity && result === Infinity) { 340 | result = value; 341 | lastComputed = computed; 342 | } 343 | }); 344 | } 345 | return result; 346 | }; 347 | 348 | // Shuffle a collection, using the modern version of the 349 | // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher鈥揧ates_shuffle). 350 | _.shuffle = function(obj) { 351 | var set = isArrayLike(obj) ? obj : _.values(obj); 352 | var length = set.length; 353 | var shuffled = Array(length); 354 | for (var index = 0, rand; index < length; index++) { 355 | rand = _.random(0, index); 356 | if (rand !== index) shuffled[index] = shuffled[rand]; 357 | shuffled[rand] = set[index]; 358 | } 359 | return shuffled; 360 | }; 361 | 362 | // Sample **n** random values from a collection. 363 | // If **n** is not specified, returns a single random element. 364 | // The internal `guard` argument allows it to work with `map`. 365 | _.sample = function(obj, n, guard) { 366 | if (n == null || guard) { 367 | if (!isArrayLike(obj)) obj = _.values(obj); 368 | return obj[_.random(obj.length - 1)]; 369 | } 370 | return _.shuffle(obj).slice(0, Math.max(0, n)); 371 | }; 372 | 373 | // Sort the object's values by a criterion produced by an iteratee. 374 | _.sortBy = function(obj, iteratee, context) { 375 | iteratee = cb(iteratee, context); 376 | return _.pluck(_.map(obj, function(value, index, list) { 377 | return { 378 | value: value, 379 | index: index, 380 | criteria: iteratee(value, index, list) 381 | }; 382 | }).sort(function(left, right) { 383 | var a = left.criteria; 384 | var b = right.criteria; 385 | if (a !== b) { 386 | if (a > b || a === void 0) return 1; 387 | if (a < b || b === void 0) return -1; 388 | } 389 | return left.index - right.index; 390 | }), 'value'); 391 | }; 392 | 393 | // An internal function used for aggregate "group by" operations. 394 | var group = function(behavior) { 395 | return function(obj, iteratee, context) { 396 | var result = {}; 397 | iteratee = cb(iteratee, context); 398 | _.each(obj, function(value, index) { 399 | var key = iteratee(value, index, obj); 400 | behavior(result, value, key); 401 | }); 402 | return result; 403 | }; 404 | }; 405 | 406 | // Groups the object's values by a criterion. Pass either a string attribute 407 | // to group by, or a function that returns the criterion. 408 | _.groupBy = group(function(result, value, key) { 409 | if (_.has(result, key)) result[key].push(value); else result[key] = [value]; 410 | }); 411 | 412 | // Indexes the object's values by a criterion, similar to `groupBy`, but for 413 | // when you know that your index values will be unique. 414 | _.indexBy = group(function(result, value, key) { 415 | result[key] = value; 416 | }); 417 | 418 | // Counts instances of an object that group by a certain criterion. Pass 419 | // either a string attribute to count by, or a function that returns the 420 | // criterion. 421 | _.countBy = group(function(result, value, key) { 422 | if (_.has(result, key)) result[key]++; else result[key] = 1; 423 | }); 424 | 425 | // Safely create a real, live array from anything iterable. 426 | _.toArray = function(obj) { 427 | if (!obj) return []; 428 | if (_.isArray(obj)) return slice.call(obj); 429 | if (isArrayLike(obj)) return _.map(obj, _.identity); 430 | return _.values(obj); 431 | }; 432 | 433 | // Return the number of elements in an object. 434 | _.size = function(obj) { 435 | if (obj == null) return 0; 436 | return isArrayLike(obj) ? obj.length : _.keys(obj).length; 437 | }; 438 | 439 | // Split a collection into two arrays: one whose elements all satisfy the given 440 | // predicate, and one whose elements all do not satisfy the predicate. 441 | _.partition = function(obj, predicate, context) { 442 | predicate = cb(predicate, context); 443 | var pass = [], fail = []; 444 | _.each(obj, function(value, key, obj) { 445 | (predicate(value, key, obj) ? pass : fail).push(value); 446 | }); 447 | return [pass, fail]; 448 | }; 449 | 450 | // Array Functions 451 | // --------------- 452 | 453 | // Get the first element of an array. Passing **n** will return the first N 454 | // values in the array. Aliased as `head` and `take`. The **guard** check 455 | // allows it to work with `_.map`. 456 | _.first = _.head = _.take = function(array, n, guard) { 457 | if (array == null) return void 0; 458 | if (n == null || guard) return array[0]; 459 | return _.initial(array, array.length - n); 460 | }; 461 | 462 | // Returns everything but the last entry of the array. Especially useful on 463 | // the arguments object. Passing **n** will return all the values in 464 | // the array, excluding the last N. 465 | _.initial = function(array, n, guard) { 466 | return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); 467 | }; 468 | 469 | // Get the last element of an array. Passing **n** will return the last N 470 | // values in the array. 471 | _.last = function(array, n, guard) { 472 | if (array == null) return void 0; 473 | if (n == null || guard) return array[array.length - 1]; 474 | return _.rest(array, Math.max(0, array.length - n)); 475 | }; 476 | 477 | // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. 478 | // Especially useful on the arguments object. Passing an **n** will return 479 | // the rest N values in the array. 480 | _.rest = _.tail = _.drop = function(array, n, guard) { 481 | return slice.call(array, n == null || guard ? 1 : n); 482 | }; 483 | 484 | // Trim out all falsy values from an array. 485 | _.compact = function(array) { 486 | return _.filter(array, _.identity); 487 | }; 488 | 489 | // Internal implementation of a recursive `flatten` function. 490 | var flatten = function(input, shallow, strict, startIndex) { 491 | var output = [], idx = 0; 492 | for (var i = startIndex || 0, length = getLength(input); i < length; i++) { 493 | var value = input[i]; 494 | if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { 495 | //flatten current level of array or arguments object 496 | if (!shallow) value = flatten(value, shallow, strict); 497 | var j = 0, len = value.length; 498 | output.length += len; 499 | while (j < len) { 500 | output[idx++] = value[j++]; 501 | } 502 | } else if (!strict) { 503 | output[idx++] = value; 504 | } 505 | } 506 | return output; 507 | }; 508 | 509 | // Flatten out an array, either recursively (by default), or just one level. 510 | _.flatten = function(array, shallow) { 511 | return flatten(array, shallow, false); 512 | }; 513 | 514 | // Return a version of the array that does not contain the specified value(s). 515 | _.without = function(array) { 516 | return _.difference(array, slice.call(arguments, 1)); 517 | }; 518 | 519 | // Produce a duplicate-free version of the array. If the array has already 520 | // been sorted, you have the option of using a faster algorithm. 521 | // Aliased as `unique`. 522 | _.uniq = _.unique = function(array, isSorted, iteratee, context) { 523 | if (!_.isBoolean(isSorted)) { 524 | context = iteratee; 525 | iteratee = isSorted; 526 | isSorted = false; 527 | } 528 | if (iteratee != null) iteratee = cb(iteratee, context); 529 | var result = []; 530 | var seen = []; 531 | for (var i = 0, length = getLength(array); i < length; i++) { 532 | var value = array[i], 533 | computed = iteratee ? iteratee(value, i, array) : value; 534 | if (isSorted) { 535 | if (!i || seen !== computed) result.push(value); 536 | seen = computed; 537 | } else if (iteratee) { 538 | if (!_.contains(seen, computed)) { 539 | seen.push(computed); 540 | result.push(value); 541 | } 542 | } else if (!_.contains(result, value)) { 543 | result.push(value); 544 | } 545 | } 546 | return result; 547 | }; 548 | 549 | // Produce an array that contains the union: each distinct element from all of 550 | // the passed-in arrays. 551 | _.union = function() { 552 | return _.uniq(flatten(arguments, true, true)); 553 | }; 554 | 555 | // Produce an array that contains every item shared between all the 556 | // passed-in arrays. 557 | _.intersection = function(array) { 558 | var result = []; 559 | var argsLength = arguments.length; 560 | for (var i = 0, length = getLength(array); i < length; i++) { 561 | var item = array[i]; 562 | if (_.contains(result, item)) continue; 563 | for (var j = 1; j < argsLength; j++) { 564 | if (!_.contains(arguments[j], item)) break; 565 | } 566 | if (j === argsLength) result.push(item); 567 | } 568 | return result; 569 | }; 570 | 571 | // Take the difference between one array and a number of other arrays. 572 | // Only the elements present in just the first array will remain. 573 | _.difference = function(array) { 574 | var rest = flatten(arguments, true, true, 1); 575 | return _.filter(array, function(value){ 576 | return !_.contains(rest, value); 577 | }); 578 | }; 579 | 580 | // Zip together multiple lists into a single array -- elements that share 581 | // an index go together. 582 | _.zip = function() { 583 | return _.unzip(arguments); 584 | }; 585 | 586 | // Complement of _.zip. Unzip accepts an array of arrays and groups 587 | // each array's elements on shared indices 588 | _.unzip = function(array) { 589 | var length = array && _.max(array, getLength).length || 0; 590 | var result = Array(length); 591 | 592 | for (var index = 0; index < length; index++) { 593 | result[index] = _.pluck(array, index); 594 | } 595 | return result; 596 | }; 597 | 598 | // Converts lists into objects. Pass either a single array of `[key, value]` 599 | // pairs, or two parallel arrays of the same length -- one of keys, and one of 600 | // the corresponding values. 601 | _.object = function(list, values) { 602 | var result = {}; 603 | for (var i = 0, length = getLength(list); i < length; i++) { 604 | if (values) { 605 | result[list[i]] = values[i]; 606 | } else { 607 | result[list[i][0]] = list[i][1]; 608 | } 609 | } 610 | return result; 611 | }; 612 | 613 | // Generator function to create the findIndex and findLastIndex functions 614 | function createPredicateIndexFinder(dir) { 615 | return function(array, predicate, context) { 616 | predicate = cb(predicate, context); 617 | var length = getLength(array); 618 | var index = dir > 0 ? 0 : length - 1; 619 | for (; index >= 0 && index < length; index += dir) { 620 | if (predicate(array[index], index, array)) return index; 621 | } 622 | return -1; 623 | }; 624 | } 625 | 626 | // Returns the first index on an array-like that passes a predicate test 627 | _.findIndex = createPredicateIndexFinder(1); 628 | _.findLastIndex = createPredicateIndexFinder(-1); 629 | 630 | // Use a comparator function to figure out the smallest index at which 631 | // an object should be inserted so as to maintain order. Uses binary search. 632 | _.sortedIndex = function(array, obj, iteratee, context) { 633 | iteratee = cb(iteratee, context, 1); 634 | var value = iteratee(obj); 635 | var low = 0, high = getLength(array); 636 | while (low < high) { 637 | var mid = Math.floor((low + high) / 2); 638 | if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; 639 | } 640 | return low; 641 | }; 642 | 643 | // Generator function to create the indexOf and lastIndexOf functions 644 | function createIndexFinder(dir, predicateFind, sortedIndex) { 645 | return function(array, item, idx) { 646 | var i = 0, length = getLength(array); 647 | if (typeof idx == 'number') { 648 | if (dir > 0) { 649 | i = idx >= 0 ? idx : Math.max(idx + length, i); 650 | } else { 651 | length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; 652 | } 653 | } else if (sortedIndex && idx && length) { 654 | idx = sortedIndex(array, item); 655 | return array[idx] === item ? idx : -1; 656 | } 657 | if (item !== item) { 658 | idx = predicateFind(slice.call(array, i, length), _.isNaN); 659 | return idx >= 0 ? idx + i : -1; 660 | } 661 | for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { 662 | if (array[idx] === item) return idx; 663 | } 664 | return -1; 665 | }; 666 | } 667 | 668 | // Return the position of the first occurrence of an item in an array, 669 | // or -1 if the item is not included in the array. 670 | // If the array is large and already in sort order, pass `true` 671 | // for **isSorted** to use binary search. 672 | _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); 673 | _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); 674 | 675 | // Generate an integer Array containing an arithmetic progression. A port of 676 | // the native Python `range()` function. See 677 | // [the Python documentation](http://docs.python.org/library/functions.html#range). 678 | _.range = function(start, stop, step) { 679 | if (stop == null) { 680 | stop = start || 0; 681 | start = 0; 682 | } 683 | step = step || 1; 684 | 685 | var length = Math.max(Math.ceil((stop - start) / step), 0); 686 | var range = Array(length); 687 | 688 | for (var idx = 0; idx < length; idx++, start += step) { 689 | range[idx] = start; 690 | } 691 | 692 | return range; 693 | }; 694 | 695 | // Function (ahem) Functions 696 | // ------------------ 697 | 698 | // Determines whether to execute a function as a constructor 699 | // or a normal function with the provided arguments 700 | var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { 701 | if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); 702 | var self = baseCreate(sourceFunc.prototype); 703 | var result = sourceFunc.apply(self, args); 704 | if (_.isObject(result)) return result; 705 | return self; 706 | }; 707 | 708 | // Create a function bound to a given object (assigning `this`, and arguments, 709 | // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if 710 | // available. 711 | _.bind = function(func, context) { 712 | if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); 713 | if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); 714 | var args = slice.call(arguments, 2); 715 | var bound = function() { 716 | return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); 717 | }; 718 | return bound; 719 | }; 720 | 721 | // Partially apply a function by creating a version that has had some of its 722 | // arguments pre-filled, without changing its dynamic `this` context. _ acts 723 | // as a placeholder, allowing any combination of arguments to be pre-filled. 724 | _.partial = function(func) { 725 | var boundArgs = slice.call(arguments, 1); 726 | var bound = function() { 727 | var position = 0, length = boundArgs.length; 728 | var args = Array(length); 729 | for (var i = 0; i < length; i++) { 730 | args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; 731 | } 732 | while (position < arguments.length) args.push(arguments[position++]); 733 | return executeBound(func, bound, this, this, args); 734 | }; 735 | return bound; 736 | }; 737 | 738 | // Bind a number of an object's methods to that object. Remaining arguments 739 | // are the method names to be bound. Useful for ensuring that all callbacks 740 | // defined on an object belong to it. 741 | _.bindAll = function(obj) { 742 | var i, length = arguments.length, key; 743 | if (length <= 1) throw new Error('bindAll must be passed function names'); 744 | for (i = 1; i < length; i++) { 745 | key = arguments[i]; 746 | obj[key] = _.bind(obj[key], obj); 747 | } 748 | return obj; 749 | }; 750 | 751 | // Memoize an expensive function by storing its results. 752 | _.memoize = function(func, hasher) { 753 | var memoize = function(key) { 754 | var cache = memoize.cache; 755 | var address = '' + (hasher ? hasher.apply(this, arguments) : key); 756 | if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); 757 | return cache[address]; 758 | }; 759 | memoize.cache = {}; 760 | return memoize; 761 | }; 762 | 763 | // Delays a function for the given number of milliseconds, and then calls 764 | // it with the arguments supplied. 765 | _.delay = function(func, wait) { 766 | var args = slice.call(arguments, 2); 767 | return setTimeout(function(){ 768 | return func.apply(null, args); 769 | }, wait); 770 | }; 771 | 772 | // Defers a function, scheduling it to run after the current call stack has 773 | // cleared. 774 | _.defer = _.partial(_.delay, _, 1); 775 | 776 | // Returns a function, that, when invoked, will only be triggered at most once 777 | // during a given window of time. Normally, the throttled function will run 778 | // as much as it can, without ever going more than once per `wait` duration; 779 | // but if you'd like to disable the execution on the leading edge, pass 780 | // `{leading: false}`. To disable execution on the trailing edge, ditto. 781 | _.throttle = function(func, wait, options) { 782 | var context, args, result; 783 | var timeout = null; 784 | var previous = 0; 785 | if (!options) options = {}; 786 | var later = function() { 787 | previous = options.leading === false ? 0 : _.now(); 788 | timeout = null; 789 | result = func.apply(context, args); 790 | if (!timeout) context = args = null; 791 | }; 792 | return function() { 793 | var now = _.now(); 794 | if (!previous && options.leading === false) previous = now; 795 | var remaining = wait - (now - previous); 796 | context = this; 797 | args = arguments; 798 | if (remaining <= 0 || remaining > wait) { 799 | if (timeout) { 800 | clearTimeout(timeout); 801 | timeout = null; 802 | } 803 | previous = now; 804 | result = func.apply(context, args); 805 | if (!timeout) context = args = null; 806 | } else if (!timeout && options.trailing !== false) { 807 | timeout = setTimeout(later, remaining); 808 | } 809 | return result; 810 | }; 811 | }; 812 | 813 | // Returns a function, that, as long as it continues to be invoked, will not 814 | // be triggered. The function will be called after it stops being called for 815 | // N milliseconds. If `immediate` is passed, trigger the function on the 816 | // leading edge, instead of the trailing. 817 | _.debounce = function(func, wait, immediate) { 818 | var timeout, args, context, timestamp, result; 819 | 820 | var later = function() { 821 | var last = _.now() - timestamp; 822 | 823 | if (last < wait && last >= 0) { 824 | timeout = setTimeout(later, wait - last); 825 | } else { 826 | timeout = null; 827 | if (!immediate) { 828 | result = func.apply(context, args); 829 | if (!timeout) context = args = null; 830 | } 831 | } 832 | }; 833 | 834 | return function() { 835 | context = this; 836 | args = arguments; 837 | timestamp = _.now(); 838 | var callNow = immediate && !timeout; 839 | if (!timeout) timeout = setTimeout(later, wait); 840 | if (callNow) { 841 | result = func.apply(context, args); 842 | context = args = null; 843 | } 844 | 845 | return result; 846 | }; 847 | }; 848 | 849 | // Returns the first function passed as an argument to the second, 850 | // allowing you to adjust arguments, run code before and after, and 851 | // conditionally execute the original function. 852 | _.wrap = function(func, wrapper) { 853 | return _.partial(wrapper, func); 854 | }; 855 | 856 | // Returns a negated version of the passed-in predicate. 857 | _.negate = function(predicate) { 858 | return function() { 859 | return !predicate.apply(this, arguments); 860 | }; 861 | }; 862 | 863 | // Returns a function that is the composition of a list of functions, each 864 | // consuming the return value of the function that follows. 865 | _.compose = function() { 866 | var args = arguments; 867 | var start = args.length - 1; 868 | return function() { 869 | var i = start; 870 | var result = args[start].apply(this, arguments); 871 | while (i--) result = args[i].call(this, result); 872 | return result; 873 | }; 874 | }; 875 | 876 | // Returns a function that will only be executed on and after the Nth call. 877 | _.after = function(times, func) { 878 | return function() { 879 | if (--times < 1) { 880 | return func.apply(this, arguments); 881 | } 882 | }; 883 | }; 884 | 885 | // Returns a function that will only be executed up to (but not including) the Nth call. 886 | _.before = function(times, func) { 887 | var memo; 888 | return function() { 889 | if (--times > 0) { 890 | memo = func.apply(this, arguments); 891 | } 892 | if (times <= 1) func = null; 893 | return memo; 894 | }; 895 | }; 896 | 897 | // Returns a function that will be executed at most one time, no matter how 898 | // often you call it. Useful for lazy initialization. 899 | _.once = _.partial(_.before, 2); 900 | 901 | // Object Functions 902 | // ---------------- 903 | 904 | // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. 905 | var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); 906 | var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 907 | 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; 908 | 909 | function collectNonEnumProps(obj, keys) { 910 | var nonEnumIdx = nonEnumerableProps.length; 911 | var constructor = obj.constructor; 912 | var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; 913 | 914 | // Constructor is a special case. 915 | var prop = 'constructor'; 916 | if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); 917 | 918 | while (nonEnumIdx--) { 919 | prop = nonEnumerableProps[nonEnumIdx]; 920 | if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { 921 | keys.push(prop); 922 | } 923 | } 924 | } 925 | 926 | // Retrieve the names of an object's own properties. 927 | // Delegates to **ECMAScript 5**'s native `Object.keys` 928 | _.keys = function(obj) { 929 | if (!_.isObject(obj)) return []; 930 | if (nativeKeys) return nativeKeys(obj); 931 | var keys = []; 932 | for (var key in obj) if (_.has(obj, key)) keys.push(key); 933 | // Ahem, IE < 9. 934 | if (hasEnumBug) collectNonEnumProps(obj, keys); 935 | return keys; 936 | }; 937 | 938 | // Retrieve all the property names of an object. 939 | _.allKeys = function(obj) { 940 | if (!_.isObject(obj)) return []; 941 | var keys = []; 942 | for (var key in obj) keys.push(key); 943 | // Ahem, IE < 9. 944 | if (hasEnumBug) collectNonEnumProps(obj, keys); 945 | return keys; 946 | }; 947 | 948 | // Retrieve the values of an object's properties. 949 | _.values = function(obj) { 950 | var keys = _.keys(obj); 951 | var length = keys.length; 952 | var values = Array(length); 953 | for (var i = 0; i < length; i++) { 954 | values[i] = obj[keys[i]]; 955 | } 956 | return values; 957 | }; 958 | 959 | // Returns the results of applying the iteratee to each element of the object 960 | // In contrast to _.map it returns an object 961 | _.mapObject = function(obj, iteratee, context) { 962 | iteratee = cb(iteratee, context); 963 | var keys = _.keys(obj), 964 | length = keys.length, 965 | results = {}, 966 | currentKey; 967 | for (var index = 0; index < length; index++) { 968 | currentKey = keys[index]; 969 | results[currentKey] = iteratee(obj[currentKey], currentKey, obj); 970 | } 971 | return results; 972 | }; 973 | 974 | // Convert an object into a list of `[key, value]` pairs. 975 | _.pairs = function(obj) { 976 | var keys = _.keys(obj); 977 | var length = keys.length; 978 | var pairs = Array(length); 979 | for (var i = 0; i < length; i++) { 980 | pairs[i] = [keys[i], obj[keys[i]]]; 981 | } 982 | return pairs; 983 | }; 984 | 985 | // Invert the keys and values of an object. The values must be serializable. 986 | _.invert = function(obj) { 987 | var result = {}; 988 | var keys = _.keys(obj); 989 | for (var i = 0, length = keys.length; i < length; i++) { 990 | result[obj[keys[i]]] = keys[i]; 991 | } 992 | return result; 993 | }; 994 | 995 | // Return a sorted list of the function names available on the object. 996 | // Aliased as `methods` 997 | _.functions = _.methods = function(obj) { 998 | var names = []; 999 | for (var key in obj) { 1000 | if (_.isFunction(obj[key])) names.push(key); 1001 | } 1002 | return names.sort(); 1003 | }; 1004 | 1005 | // Extend a given object with all the properties in passed-in object(s). 1006 | _.extend = createAssigner(_.allKeys); 1007 | 1008 | // Assigns a given object with all the own properties in the passed-in object(s) 1009 | // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) 1010 | _.extendOwn = _.assign = createAssigner(_.keys); 1011 | 1012 | // Returns the first key on an object that passes a predicate test 1013 | _.findKey = function(obj, predicate, context) { 1014 | predicate = cb(predicate, context); 1015 | var keys = _.keys(obj), key; 1016 | for (var i = 0, length = keys.length; i < length; i++) { 1017 | key = keys[i]; 1018 | if (predicate(obj[key], key, obj)) return key; 1019 | } 1020 | }; 1021 | 1022 | // Return a copy of the object only containing the whitelisted properties. 1023 | _.pick = function(object, oiteratee, context) { 1024 | var result = {}, obj = object, iteratee, keys; 1025 | if (obj == null) return result; 1026 | if (_.isFunction(oiteratee)) { 1027 | keys = _.allKeys(obj); 1028 | iteratee = optimizeCb(oiteratee, context); 1029 | } else { 1030 | keys = flatten(arguments, false, false, 1); 1031 | iteratee = function(value, key, obj) { return key in obj; }; 1032 | obj = Object(obj); 1033 | } 1034 | for (var i = 0, length = keys.length; i < length; i++) { 1035 | var key = keys[i]; 1036 | var value = obj[key]; 1037 | if (iteratee(value, key, obj)) result[key] = value; 1038 | } 1039 | return result; 1040 | }; 1041 | 1042 | // Return a copy of the object without the blacklisted properties. 1043 | _.omit = function(obj, iteratee, context) { 1044 | if (_.isFunction(iteratee)) { 1045 | iteratee = _.negate(iteratee); 1046 | } else { 1047 | var keys = _.map(flatten(arguments, false, false, 1), String); 1048 | iteratee = function(value, key) { 1049 | return !_.contains(keys, key); 1050 | }; 1051 | } 1052 | return _.pick(obj, iteratee, context); 1053 | }; 1054 | 1055 | // Fill in a given object with default properties. 1056 | _.defaults = createAssigner(_.allKeys, true); 1057 | 1058 | // Creates an object that inherits from the given prototype object. 1059 | // If additional properties are provided then they will be added to the 1060 | // created object. 1061 | _.create = function(prototype, props) { 1062 | var result = baseCreate(prototype); 1063 | if (props) _.extendOwn(result, props); 1064 | return result; 1065 | }; 1066 | 1067 | // Create a (shallow-cloned) duplicate of an object. 1068 | _.clone = function(obj) { 1069 | if (!_.isObject(obj)) return obj; 1070 | return _.isArray(obj) ? obj.slice() : _.extend({}, obj); 1071 | }; 1072 | 1073 | // Invokes interceptor with the obj, and then returns obj. 1074 | // The primary purpose of this method is to "tap into" a method chain, in 1075 | // order to perform operations on intermediate results within the chain. 1076 | _.tap = function(obj, interceptor) { 1077 | interceptor(obj); 1078 | return obj; 1079 | }; 1080 | 1081 | // Returns whether an object has a given set of `key:value` pairs. 1082 | _.isMatch = function(object, attrs) { 1083 | var keys = _.keys(attrs), length = keys.length; 1084 | if (object == null) return !length; 1085 | var obj = Object(object); 1086 | for (var i = 0; i < length; i++) { 1087 | var key = keys[i]; 1088 | if (attrs[key] !== obj[key] || !(key in obj)) return false; 1089 | } 1090 | return true; 1091 | }; 1092 | 1093 | 1094 | // Internal recursive comparison function for `isEqual`. 1095 | var eq = function(a, b, aStack, bStack) { 1096 | // Identical objects are equal. `0 === -0`, but they aren't identical. 1097 | // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). 1098 | if (a === b) return a !== 0 || 1 / a === 1 / b; 1099 | // A strict comparison is necessary because `null == undefined`. 1100 | if (a == null || b == null) return a === b; 1101 | // Unwrap any wrapped objects. 1102 | if (a instanceof _) a = a._wrapped; 1103 | if (b instanceof _) b = b._wrapped; 1104 | // Compare `[[Class]]` names. 1105 | var className = toString.call(a); 1106 | if (className !== toString.call(b)) return false; 1107 | switch (className) { 1108 | // Strings, numbers, regular expressions, dates, and booleans are compared by value. 1109 | case '[object RegExp]': 1110 | // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') 1111 | case '[object String]': 1112 | // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is 1113 | // equivalent to `new String("5")`. 1114 | return '' + a === '' + b; 1115 | case '[object Number]': 1116 | // `NaN`s are equivalent, but non-reflexive. 1117 | // Object(NaN) is equivalent to NaN 1118 | if (+a !== +a) return +b !== +b; 1119 | // An `egal` comparison is performed for other numeric values. 1120 | return +a === 0 ? 1 / +a === 1 / b : +a === +b; 1121 | case '[object Date]': 1122 | case '[object Boolean]': 1123 | // Coerce dates and booleans to numeric primitive values. Dates are compared by their 1124 | // millisecond representations. Note that invalid dates with millisecond representations 1125 | // of `NaN` are not equivalent. 1126 | return +a === +b; 1127 | } 1128 | 1129 | var areArrays = className === '[object Array]'; 1130 | if (!areArrays) { 1131 | if (typeof a != 'object' || typeof b != 'object') return false; 1132 | 1133 | // Objects with different constructors are not equivalent, but `Object`s or `Array`s 1134 | // from different frames are. 1135 | var aCtor = a.constructor, bCtor = b.constructor; 1136 | if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && 1137 | _.isFunction(bCtor) && bCtor instanceof bCtor) 1138 | && ('constructor' in a && 'constructor' in b)) { 1139 | return false; 1140 | } 1141 | } 1142 | // Assume equality for cyclic structures. The algorithm for detecting cyclic 1143 | // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. 1144 | 1145 | // Initializing stack of traversed objects. 1146 | // It's done here since we only need them for objects and arrays comparison. 1147 | aStack = aStack || []; 1148 | bStack = bStack || []; 1149 | var length = aStack.length; 1150 | while (length--) { 1151 | // Linear search. Performance is inversely proportional to the number of 1152 | // unique nested structures. 1153 | if (aStack[length] === a) return bStack[length] === b; 1154 | } 1155 | 1156 | // Add the first object to the stack of traversed objects. 1157 | aStack.push(a); 1158 | bStack.push(b); 1159 | 1160 | // Recursively compare objects and arrays. 1161 | if (areArrays) { 1162 | // Compare array lengths to determine if a deep comparison is necessary. 1163 | length = a.length; 1164 | if (length !== b.length) return false; 1165 | // Deep compare the contents, ignoring non-numeric properties. 1166 | while (length--) { 1167 | if (!eq(a[length], b[length], aStack, bStack)) return false; 1168 | } 1169 | } else { 1170 | // Deep compare objects. 1171 | var keys = _.keys(a), key; 1172 | length = keys.length; 1173 | // Ensure that both objects contain the same number of properties before comparing deep equality. 1174 | if (_.keys(b).length !== length) return false; 1175 | while (length--) { 1176 | // Deep compare each member 1177 | key = keys[length]; 1178 | if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; 1179 | } 1180 | } 1181 | // Remove the first object from the stack of traversed objects. 1182 | aStack.pop(); 1183 | bStack.pop(); 1184 | return true; 1185 | }; 1186 | 1187 | // Perform a deep comparison to check if two objects are equal. 1188 | _.isEqual = function(a, b) { 1189 | return eq(a, b); 1190 | }; 1191 | 1192 | // Is a given array, string, or object empty? 1193 | // An "empty" object has no enumerable own-properties. 1194 | _.isEmpty = function(obj) { 1195 | if (obj == null) return true; 1196 | if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; 1197 | return _.keys(obj).length === 0; 1198 | }; 1199 | 1200 | // Is a given value a DOM element? 1201 | _.isElement = function(obj) { 1202 | return !!(obj && obj.nodeType === 1); 1203 | }; 1204 | 1205 | // Is a given value an array? 1206 | // Delegates to ECMA5's native Array.isArray 1207 | _.isArray = nativeIsArray || function(obj) { 1208 | return toString.call(obj) === '[object Array]'; 1209 | }; 1210 | 1211 | // Is a given variable an object? 1212 | _.isObject = function(obj) { 1213 | var type = typeof obj; 1214 | return type === 'function' || type === 'object' && !!obj; 1215 | }; 1216 | 1217 | // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. 1218 | _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { 1219 | _['is' + name] = function(obj) { 1220 | return toString.call(obj) === '[object ' + name + ']'; 1221 | }; 1222 | }); 1223 | 1224 | // Define a fallback version of the method in browsers (ahem, IE < 9), where 1225 | // there isn't any inspectable "Arguments" type. 1226 | if (!_.isArguments(arguments)) { 1227 | _.isArguments = function(obj) { 1228 | return _.has(obj, 'callee'); 1229 | }; 1230 | } 1231 | 1232 | // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, 1233 | // IE 11 (#1621), and in Safari 8 (#1929). 1234 | if (typeof /./ != 'function' && typeof Int8Array != 'object') { 1235 | _.isFunction = function(obj) { 1236 | return typeof obj == 'function' || false; 1237 | }; 1238 | } 1239 | 1240 | // Is a given object a finite number? 1241 | _.isFinite = function(obj) { 1242 | return isFinite(obj) && !isNaN(parseFloat(obj)); 1243 | }; 1244 | 1245 | // Is the given value `NaN`? (NaN is the only number which does not equal itself). 1246 | _.isNaN = function(obj) { 1247 | return _.isNumber(obj) && obj !== +obj; 1248 | }; 1249 | 1250 | // Is a given value a boolean? 1251 | _.isBoolean = function(obj) { 1252 | return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; 1253 | }; 1254 | 1255 | // Is a given value equal to null? 1256 | _.isNull = function(obj) { 1257 | return obj === null; 1258 | }; 1259 | 1260 | // Is a given variable undefined? 1261 | _.isUndefined = function(obj) { 1262 | return obj === void 0; 1263 | }; 1264 | 1265 | // Shortcut function for checking if an object has a given property directly 1266 | // on itself (in other words, not on a prototype). 1267 | _.has = function(obj, key) { 1268 | return obj != null && hasOwnProperty.call(obj, key); 1269 | }; 1270 | 1271 | // Utility Functions 1272 | // ----------------- 1273 | 1274 | // Run Underscore.js in *noConflict* mode, returning the `_` variable to its 1275 | // previous owner. Returns a reference to the Underscore object. 1276 | _.noConflict = function() { 1277 | root._ = previousUnderscore; 1278 | return this; 1279 | }; 1280 | 1281 | // Keep the identity function around for default iteratees. 1282 | _.identity = function(value) { 1283 | return value; 1284 | }; 1285 | 1286 | // Predicate-generating functions. Often useful outside of Underscore. 1287 | _.constant = function(value) { 1288 | return function() { 1289 | return value; 1290 | }; 1291 | }; 1292 | 1293 | _.noop = function(){}; 1294 | 1295 | _.property = property; 1296 | 1297 | // Generates a function for a given object that returns a given property. 1298 | _.propertyOf = function(obj) { 1299 | return obj == null ? function(){} : function(key) { 1300 | return obj[key]; 1301 | }; 1302 | }; 1303 | 1304 | // Returns a predicate for checking whether an object has a given set of 1305 | // `key:value` pairs. 1306 | _.matcher = _.matches = function(attrs) { 1307 | attrs = _.extendOwn({}, attrs); 1308 | return function(obj) { 1309 | return _.isMatch(obj, attrs); 1310 | }; 1311 | }; 1312 | 1313 | // Run a function **n** times. 1314 | _.times = function(n, iteratee, context) { 1315 | var accum = Array(Math.max(0, n)); 1316 | iteratee = optimizeCb(iteratee, context, 1); 1317 | for (var i = 0; i < n; i++) accum[i] = iteratee(i); 1318 | return accum; 1319 | }; 1320 | 1321 | // Return a random integer between min and max (inclusive). 1322 | _.random = function(min, max) { 1323 | if (max == null) { 1324 | max = min; 1325 | min = 0; 1326 | } 1327 | return min + Math.floor(Math.random() * (max - min + 1)); 1328 | }; 1329 | 1330 | // A (possibly faster) way to get the current timestamp as an integer. 1331 | _.now = Date.now || function() { 1332 | return new Date().getTime(); 1333 | }; 1334 | 1335 | // List of HTML entities for escaping. 1336 | var escapeMap = { 1337 | '&': '&', 1338 | '<': '<', 1339 | '>': '>', 1340 | '"': '"', 1341 | "'": ''', 1342 | '`': '`' 1343 | }; 1344 | var unescapeMap = _.invert(escapeMap); 1345 | 1346 | // Functions for escaping and unescaping strings to/from HTML interpolation. 1347 | var createEscaper = function(map) { 1348 | var escaper = function(match) { 1349 | return map[match]; 1350 | }; 1351 | // Regexes for identifying a key that needs to be escaped 1352 | var source = '(?:' + _.keys(map).join('|') + ')'; 1353 | var testRegexp = RegExp(source); 1354 | var replaceRegexp = RegExp(source, 'g'); 1355 | return function(string) { 1356 | string = string == null ? '' : '' + string; 1357 | return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; 1358 | }; 1359 | }; 1360 | _.escape = createEscaper(escapeMap); 1361 | _.unescape = createEscaper(unescapeMap); 1362 | 1363 | // If the value of the named `property` is a function then invoke it with the 1364 | // `object` as context; otherwise, return it. 1365 | _.result = function(object, property, fallback) { 1366 | var value = object == null ? void 0 : object[property]; 1367 | if (value === void 0) { 1368 | value = fallback; 1369 | } 1370 | return _.isFunction(value) ? value.call(object) : value; 1371 | }; 1372 | 1373 | // Generate a unique integer id (unique within the entire client session). 1374 | // Useful for temporary DOM ids. 1375 | var idCounter = 0; 1376 | _.uniqueId = function(prefix) { 1377 | var id = ++idCounter + ''; 1378 | return prefix ? prefix + id : id; 1379 | }; 1380 | 1381 | // By default, Underscore uses ERB-style template delimiters, change the 1382 | // following template settings to use alternative delimiters. 1383 | _.templateSettings = { 1384 | evaluate : /<%([\s\S]+?)%>/g, 1385 | interpolate : /<%=([\s\S]+?)%>/g, 1386 | escape : /<%-([\s\S]+?)%>/g 1387 | }; 1388 | 1389 | // When customizing `templateSettings`, if you don't want to define an 1390 | // interpolation, evaluation or escaping regex, we need one that is 1391 | // guaranteed not to match. 1392 | var noMatch = /(.)^/; 1393 | 1394 | // Certain characters need to be escaped so that they can be put into a 1395 | // string literal. 1396 | var escapes = { 1397 | "'": "'", 1398 | '\\': '\\', 1399 | '\r': 'r', 1400 | '\n': 'n', 1401 | '\u2028': 'u2028', 1402 | '\u2029': 'u2029' 1403 | }; 1404 | 1405 | var escaper = /\\|'|\r|\n|\u2028|\u2029/g; 1406 | 1407 | var escapeChar = function(match) { 1408 | return '\\' + escapes[match]; 1409 | }; 1410 | 1411 | // JavaScript micro-templating, similar to John Resig's implementation. 1412 | // Underscore templating handles arbitrary delimiters, preserves whitespace, 1413 | // and correctly escapes quotes within interpolated code. 1414 | // NB: `oldSettings` only exists for backwards compatibility. 1415 | _.template = function(text, settings, oldSettings) { 1416 | if (!settings && oldSettings) settings = oldSettings; 1417 | settings = _.defaults({}, settings, _.templateSettings); 1418 | 1419 | // Combine delimiters into one regular expression via alternation. 1420 | var matcher = RegExp([ 1421 | (settings.escape || noMatch).source, 1422 | (settings.interpolate || noMatch).source, 1423 | (settings.evaluate || noMatch).source 1424 | ].join('|') + '|$', 'g'); 1425 | 1426 | // Compile the template source, escaping string literals appropriately. 1427 | var index = 0; 1428 | var source = "__p+='"; 1429 | text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 1430 | source += text.slice(index, offset).replace(escaper, escapeChar); 1431 | index = offset + match.length; 1432 | 1433 | if (escape) { 1434 | source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 1435 | } else if (interpolate) { 1436 | source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 1437 | } else if (evaluate) { 1438 | source += "';\n" + evaluate + "\n__p+='"; 1439 | } 1440 | 1441 | // Adobe VMs need the match returned to produce the correct offest. 1442 | return match; 1443 | }); 1444 | source += "';\n"; 1445 | 1446 | // If a variable is not specified, place data values in local scope. 1447 | if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 1448 | 1449 | source = "var __t,__p='',__j=Array.prototype.join," + 1450 | "print=function(){__p+=__j.call(arguments,'');};\n" + 1451 | source + 'return __p;\n'; 1452 | 1453 | try { 1454 | var render = new Function(settings.variable || 'obj', '_', source); 1455 | } catch (e) { 1456 | e.source = source; 1457 | throw e; 1458 | } 1459 | 1460 | var template = function(data) { 1461 | return render.call(this, data, _); 1462 | }; 1463 | 1464 | // Provide the compiled source as a convenience for precompilation. 1465 | var argument = settings.variable || 'obj'; 1466 | template.source = 'function(' + argument + '){\n' + source + '}'; 1467 | 1468 | return template; 1469 | }; 1470 | 1471 | // Add a "chain" function. Start chaining a wrapped Underscore object. 1472 | _.chain = function(obj) { 1473 | var instance = _(obj); 1474 | instance._chain = true; 1475 | return instance; 1476 | }; 1477 | 1478 | // OOP 1479 | // --------------- 1480 | // If Underscore is called as a function, it returns a wrapped object that 1481 | // can be used OO-style. This wrapper holds altered versions of all the 1482 | // underscore functions. Wrapped objects may be chained. 1483 | 1484 | // Helper function to continue chaining intermediate results. 1485 | var result = function(instance, obj) { 1486 | return instance._chain ? _(obj).chain() : obj; 1487 | }; 1488 | 1489 | // Add your own custom functions to the Underscore object. 1490 | _.mixin = function(obj) { 1491 | _.each(_.functions(obj), function(name) { 1492 | var func = _[name] = obj[name]; 1493 | _.prototype[name] = function() { 1494 | var args = [this._wrapped]; 1495 | push.apply(args, arguments); 1496 | return result(this, func.apply(_, args)); 1497 | }; 1498 | }); 1499 | }; 1500 | 1501 | // Add all of the Underscore functions to the wrapper object. 1502 | _.mixin(_); 1503 | 1504 | // Add all mutator Array functions to the wrapper. 1505 | _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { 1506 | var method = ArrayProto[name]; 1507 | _.prototype[name] = function() { 1508 | var obj = this._wrapped; 1509 | method.apply(obj, arguments); 1510 | if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; 1511 | return result(this, obj); 1512 | }; 1513 | }); 1514 | 1515 | // Add all accessor Array functions to the wrapper. 1516 | _.each(['concat', 'join', 'slice'], function(name) { 1517 | var method = ArrayProto[name]; 1518 | _.prototype[name] = function() { 1519 | return result(this, method.apply(this._wrapped, arguments)); 1520 | }; 1521 | }); 1522 | 1523 | // Extracts the result from a wrapped and chained object. 1524 | _.prototype.value = function() { 1525 | return this._wrapped; 1526 | }; 1527 | 1528 | // Provide unwrapping proxy for some methods used in engine operations 1529 | // such as arithmetic and JSON stringification. 1530 | _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; 1531 | 1532 | _.prototype.toString = function() { 1533 | return '' + this._wrapped; 1534 | }; 1535 | 1536 | // AMD registration happens at the end for compatibility with AMD loaders 1537 | // that may not enforce next-turn semantics on modules. Even though general 1538 | // practice for AMD registration is to be anonymous, underscore registers 1539 | // as a named module because, like jQuery, it is a base library that is 1540 | // popular enough to be bundled in a third party lib, but not be part of 1541 | // an AMD load request. Those cases could generate an error when an 1542 | // anonymous define() is called outside of a loader request. 1543 | if (typeof define === 'function' && define.amd) { 1544 | define('underscore', [], function() { 1545 | return _; 1546 | }); 1547 | } 1548 | }.call(this)); --------------------------------------------------------------------------------