├── web ├── static │ ├── js │ │ └── lib │ │ │ ├── angular │ │ │ ├── version.txt │ │ │ ├── version.json │ │ │ ├── angular-csp.css │ │ │ ├── angular-cookies.min.js │ │ │ ├── angular-loader.min.js │ │ │ ├── angular-cookies.min.js.map │ │ │ ├── angular-loader.min.js.map │ │ │ ├── angular-touch.min.js │ │ │ ├── angular-resource.min.js │ │ │ ├── angular-route.min.js │ │ │ ├── angular-sanitize.min.js │ │ │ ├── errors.json │ │ │ ├── angular-cookies.js │ │ │ ├── angular-resource.min.js.map │ │ │ ├── angular-touch.min.js.map │ │ │ ├── angular-route.min.js.map │ │ │ ├── angular-sanitize.min.js.map │ │ │ ├── angular-animate.min.js │ │ │ ├── angular-loader.js │ │ │ ├── angular-touch.js │ │ │ └── angular-sanitize.js │ │ │ ├── md5 │ │ │ ├── md5.min.js │ │ │ └── md5.js │ │ │ ├── cookie │ │ │ └── cookie.js │ │ │ └── zepto │ │ │ └── zepto.min.js │ └── image │ │ └── empty.png ├── handler │ ├── sign_handler.js │ ├── base_handler.js │ └── user_handler.js ├── helper │ └── status_code.js ├── main.js └── template │ └── signup.ejs ├── .gitignore ├── script ├── create_all_tables.js └── init.sql ├── config ├── env.js └── config.js ├── model ├── base.js └── user.js ├── LICENSE ├── package.json └── README.md /web/static/js/lib/angular/version.txt: -------------------------------------------------------------------------------- 1 | 1.2.28 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | node_modules/* -------------------------------------------------------------------------------- /web/static/image/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icarusion/nodejs-express-mysql/HEAD/web/static/image/empty.png -------------------------------------------------------------------------------- /script/create_all_tables.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by aresn on 16/5/11. 3 | */ 4 | var User = require('.././model/user'); 5 | 6 | // 创建表 7 | User.sync(); -------------------------------------------------------------------------------- /config/env.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by aresn on 16/5/11. 3 | */ 4 | 5 | var env = 'development'; // development production 6 | 7 | module.exports = env; -------------------------------------------------------------------------------- /script/init.sql: -------------------------------------------------------------------------------- 1 | # 创建用户 2 | CREATE USER 'demotable'@'%' IDENTIFIED BY 'demotable'; 3 | 4 | # 删除匿名用户 5 | DELETE FROM mysql.user WHERE user=''; 6 | 7 | # 创建数据库 8 | CREATE DATABASE demotable DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 9 | 10 | # 为用户赋予操作数据库的权限 11 | GRANT ALL ON demotable.* TO 'demotable'@'%'; -------------------------------------------------------------------------------- /web/static/js/lib/angular/version.json: -------------------------------------------------------------------------------- 1 | {"raw":"v1.2.28","major":1,"minor":2,"patch":28,"prerelease":[],"build":[],"version":"1.2.28","codeName":"finnish-disembarkation","full":"1.2.28","branch":"v1.2.x","cdn":{"raw":"v1.2.27","major":1,"minor":2,"patch":27,"prerelease":[],"build":[],"version":"1.2.27","docsUrl":"http://code.angularjs.org/1.2.27/docs"}} -------------------------------------------------------------------------------- /web/handler/sign_handler.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by aresn on 16/5/10. 3 | */ 4 | var express = require('express'); 5 | var router = express.Router(); 6 | 7 | var SignUpHandler = function(req, res) { 8 | var context = { 9 | 10 | }; 11 | res.html_response('signup', true, context); 12 | }; 13 | 14 | router.get('/signup', SignUpHandler); 15 | 16 | exports.routes = router; -------------------------------------------------------------------------------- /web/helper/status_code.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by aresn on 16/5/11. 3 | */ 4 | 5 | module.exports = { 6 | SUCCESS: '0', 7 | SUCCESS_MSG: 'success', 8 | 9 | ERROR_PARAM: 'error_param', 10 | ERROR_PARAM_MSG: '参数错误', 11 | 12 | ERROR_USER_SIGNUP_ACCOUNT: 'error_signup_account_exist', 13 | ERROR_USER_SIGNUP_ACCOUNT_MSG: '用户已存在', 14 | 15 | ERROR_USER_SIGNIN_ACCOUNT: 'error_signin_account_password_incrrect', 16 | ERROR_USER_SIGNIN_ACCOUNT_MSG: '用户名或密码错误' 17 | }; -------------------------------------------------------------------------------- /model/base.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by aresn on 16/5/11. 3 | */ 4 | var moment = require('moment'); 5 | 6 | var BaseModel = { 7 | inc: moment().valueOf(), 8 | // id生成 9 | uid: function() { 10 | var new_id = 0; 11 | // 毫秒时间戳 12 | new_id += moment().valueOf(); 13 | 14 | // 自增 15 | this.inc += 1; 16 | new_id += this.inc; 17 | 18 | return new_id; 19 | }, 20 | timestamp: function() { 21 | 22 | } 23 | }; 24 | 25 | module.exports = BaseModel; -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | @charset "UTF-8"; 4 | 5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], 6 | .ng-cloak, .x-ng-cloak, 7 | .ng-hide { 8 | display: none !important; 9 | } 10 | 11 | ng\:form { 12 | display: block; 13 | } 14 | 15 | .ng-animate-block-transitions { 16 | transition:0s all!important; 17 | -webkit-transition:0s all!important; 18 | } 19 | 20 | /* show the element during a show/hide animation when the 21 | * animation is ongoing, but the .ng-hide class is active */ 22 | .ng-hide-add-active, .ng-hide-remove { 23 | display: block!important; 24 | } 25 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-cookies.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.28 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(e,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&e.$apply())})();k=!0;e.$watch(function(){var a,d,e;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)d=c[a],f.isString(d)||(d=""+d,c[a]=d),d!==g[a]&&(b.cookies(a,d),e=!0);if(e)for(a in d=b.cookies(),c)c[a]!==d[a]&&(m(d[a])?delete c[a]:c[a]=d[a])});return c}]).factory("$cookieStore", 7 | ["$cookies",function(e){return{get:function(b){return(b=e[b])?f.fromJson(b):b},put:function(b,c){e[b]=f.toJson(c)},remove:function(b){delete e[b]}}}])})(window,window.angular); 8 | //# sourceMappingURL=angular-cookies.min.js.map 9 | -------------------------------------------------------------------------------- /config/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by aresn on 16/5/11. 3 | */ 4 | 5 | var env = require('./env'); 6 | 7 | var config = { 8 | redis: { 9 | port: 6379 10 | }, 11 | // session 12 | session: { 13 | name: 'tdtoken', 14 | secret: '123456', 15 | cookie_time: 86400000 16 | } 17 | }; 18 | 19 | if (env == 'development') { 20 | // 端口 21 | config.web_port = 9800; 22 | 23 | // redis 24 | config.redis.host = '127.0.0.1'; 25 | config.redis.passwd = ''; 26 | 27 | // DB 28 | config.db = { 29 | name: 'demotable', 30 | host: 'localhost', 31 | user: 'root', 32 | passwd: 'root', 33 | port: 3306 34 | }; 35 | } else if (env == 'production') { 36 | config.web_port = 9800; 37 | 38 | config.redis.host = '127.0.0.1'; 39 | config.redis.passwd = ''; 40 | 41 | config.db = { 42 | name: 'demotable', 43 | host: 'localhost', 44 | user: 'root', 45 | passwd: 'root', 46 | port: 3306 47 | }; 48 | } 49 | 50 | module.exports = config; 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Aresn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-express-mysql", 3 | "version": "1.0.0", 4 | "description": "A base nodejs project with Express,using MySQL and ORM of sequelize.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node web/main.js", 9 | "tables": "node script/create_all_tables.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/icarusion/nodejs-express-mysql.git" 14 | }, 15 | "author": "Aresn", 16 | "license": "MIT", 17 | "dependencies": { 18 | "body-parser": "^1.15.1", 19 | "compression": "^1.6.2", 20 | "connect-redis": "^3.0.2", 21 | "cookie-parser": "^1.4.1", 22 | "ejs": "^2.4.1", 23 | "express": "^4.13.4", 24 | "express-session": "^1.13.0", 25 | "md5": "^2.1.0", 26 | "moment": "^2.13.0", 27 | "morgan": "^1.7.0", 28 | "mysql": "^2.10.2", 29 | "node-uuid": "^1.4.7", 30 | "parseurl": "^1.3.1", 31 | "q": "^1.4.1", 32 | "redis": "^2.6.0-2", 33 | "sequelize": "^3.23.0" 34 | }, 35 | "bugs": { 36 | "url": "https://github.com/icarusion/nodejs-express-mysql/issues" 37 | }, 38 | "homepage": "https://github.com/icarusion/nodejs-express-mysql#readme" 39 | } 40 | -------------------------------------------------------------------------------- /model/user.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by aresn on 16/5/11. 3 | */ 4 | var Sequelize = require('sequelize'); 5 | var config = require('.././config/config'); 6 | var BaseModel = require('./base'); 7 | 8 | var sequelize = new Sequelize( 9 | config.db.name, 10 | config.db.user, 11 | config.db.passwd, 12 | { 13 | 'dialect': 'mysql', 14 | 'host': config.db.host, 15 | 'port': config.db.port 16 | } 17 | ); 18 | 19 | var User = sequelize.define('user', { 20 | id: { 21 | type: Sequelize.BIGINT, 22 | primaryKey: true, 23 | defaultValue: BaseModel.uid() 24 | }, 25 | mail: { 26 | type: Sequelize.STRING(50), 27 | allowNull: false 28 | }, 29 | passwd: { 30 | type: Sequelize.STRING(20), 31 | allowNull: false 32 | }, 33 | name: { 34 | type: Sequelize.STRING(20), 35 | allowNull: true 36 | } 37 | }, { 38 | indexes: [ 39 | { 40 | name: 'index_user_1', 41 | fields: ['mail'], 42 | unique: true 43 | }, 44 | { 45 | name: 'index_user_2', 46 | fields: ['mail', 'passwd'] 47 | } 48 | ], 49 | getterMethods: { 50 | to_dict: function() { 51 | return { 52 | id: this.id.toString(), 53 | name: this.name 54 | } 55 | } 56 | } 57 | }); 58 | 59 | module.exports = User; -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-loader.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.28 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(){'use strict';function d(a){return function(){var c=arguments[0],b,c="["+(a?a+":":"")+c+"] http://errors.angularjs.org/1.2.28/"+(a?a+"/":"")+c;for(b=1;b 本项目可以帮你快速搭建一个基于Express的Nodejs后台web和api服务,本项目使用MySQL数据库以及ORM-sequelize,所以不必担心不会写sql 3 | 4 | ##目录结构 5 |
 6 | │  .gitignore          # 忽略文件,比如 node_modules
 7 | │  package.json        # 项目配置
 8 | │  README.md           # 项目说明
 9 | │
10 | ├─node_modules
11 | │
12 | │
13 | ├─config               # 相关配置
14 | │    │
15 | │    │  env.js         # 指定当前环境
16 | │    └─ config.js      # 配置文件,比如MySQL/redis等
17 | │
18 | ├─lib                  # 工具
19 | │
20 | ├─model                # 即Model层,用来定义数据库的表/字段/类型/索引
21 | │    │
22 | │    │  base.js        # model基类,这里粗略的用时间戳来生成数据库的id字段
23 | │    └─ user.js        # 一个用户数据表的demo
24 | │
25 | ├─script               # 一次性执行的一些脚本,比如建表/修复数据等
26 | │    │
27 | │    │  creat_all_tables.js              # 运行即创建数据表
28 | │    └─ init.sql                         # 创建数据库的sql语句,可用mysql指令执行
29 | │
30 | ├─web                                    # web文件和api,express入口文件等
31 | │  │
32 | │  ├─handler                             # 即Controller层,路由
33 | │  │    │
34 | │  │    ├─  base_handler.js              # 基类,权限验证,及接口JSON返回和html返回的封装
35 | │  │    │
36 | │  │    ├─  sign_handler.js              # 一个打开用户注册页面的demo
37 | │  │    │
38 | │  │    └─  user_handler.js              # 一个用户注册和登录接口的demo
39 | │  │
40 | │  ├─helper
41 | │  │    │
42 | │  │    └─  status_code.js               # 接口状态码
43 | │  │
44 | │  ├─static                              # 静态文件,这里主要是前端用的,可根据自己的技术栈选型
45 | │  │    │
46 | │  │    ├─css
47 | │  │    │
48 | │  │    ├─image
49 | │  │    │
50 | │  │    └─js
51 | │  │
52 | │  ├─template                            # 即View层
53 | │  │    │
54 | │  │    └─  signup.ejs                   # 使用ejs模板,即我们的后端需要渲染的html,如果是SPA应用,则一般不需要这个
55 | │  │
56 | │  └─ main.js                            # 服务入口文件
57 | │
58 | └─api                                    # 与web类似,如果需要可以将API单独从web分离,比如SPA
59 | 
60 | 61 | 62 | ##说明 63 | 64 | 本工程需要提前安装和配置MySQL,如果需要可以再加入Redis来存储用户登录凭证,目前只是普通的session存储,时间为1天 65 | 关于如何使用Express,可查看官网http://expressjs.com/ 66 | 关于如何使用sequelize,可查阅文档http://docs.sequelizejs.com/en/latest/ 67 | 68 | 69 | ##安装 70 | ``` 71 | npm install 72 | ``` 73 | 74 | ##运行 75 | ``` 76 | npm run start 77 | ``` 78 | 79 | ##建数据表 80 | ``` 81 | npm run tables 82 | ``` 83 | 84 | ####访问 85 | 在浏览器地址栏输入http://127.0.0.1:9800/signup -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-cookies.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-cookies.min.js", 4 | "lineCount":7, 5 | "mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAmBtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,QAAA,CA0BW,UA1BX,CA0BuB,CAAC,YAAD,CAAe,UAAf,CAA2B,QAAS,CAACC,CAAD,CAAaC,CAAb,CAAuB,CAAA,IACxEC,EAAU,EAD8D,CAExEC,EAAc,EAF0D,CAGxEC,CAHwE,CAIxEC,EAAU,CAAA,CAJ8D,CAKxEC,EAAOV,CAAAU,KALiE,CAMxEC,EAAcX,CAAAW,YAGlBN,EAAAO,UAAA,CAAmB,QAAQ,EAAG,CAC5B,IAAIC,EAAiBR,CAAAC,QAAA,EACjBE,EAAJ,EAA0BK,CAA1B,GACEL,CAGA,CAHqBK,CAGrB,CAFAH,CAAA,CAAKG,CAAL,CAAqBN,CAArB,CAEA,CADAG,CAAA,CAAKG,CAAL,CAAqBP,CAArB,CACA,CAAIG,CAAJ,EAAaL,CAAAU,OAAA,EAJf,CAF4B,CAA9B,CAAA,EAUAL,EAAA,CAAU,CAAA,CAKVL,EAAAW,OAAA,CASAC,QAAa,EAAG,CAAA,IACVC,CADU,CAEVC,CAFU,CAIVC,CAGJ,KAAKF,CAAL,GAAaV,EAAb,CACMI,CAAA,CAAYL,CAAA,CAAQW,CAAR,CAAZ,CAAJ,EACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBhB,CAAvB,CAKJ,KAAIgB,CAAJ,GAAYX,EAAZ,CACEY,CAKA,CALQZ,CAAA,CAAQW,CAAR,CAKR,CAJKjB,CAAAoB,SAAA,CAAiBF,CAAjB,CAIL,GAHEA,CACA,CADQ,EACR,CADaA,CACb,CAAAZ,CAAA,CAAQW,CAAR,CAAA,CAAgBC,CAElB,EAAIA,CAAJ,GAAcX,CAAA,CAAYU,CAAZ,CAAd,GACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBC,CAAvB,CACA,CAAAC,CAAA,CAAU,CAAA,CAFZ,CAOF,IAAIA,CAAJ,CAIE,IAAKF,CAAL,GAFAI,EAEaf,CAFID,CAAAC,QAAA,EAEJA,CAAAA,CAAb,CACMA,CAAA,CAAQW,CAAR,CAAJ,GAAsBI,CAAA,CAAeJ,CAAf,CAAtB,GAEMN,CAAA,CAAYU,CAAA,CAAeJ,CAAf,CAAZ,CAAJ,CACE,OAAOX,CAAA,CAAQW,CAAR,CADT,CAGEX,CAAA,CAAQW,CAAR,CAHF,CAGkBI,CAAA,CAAeJ,CAAf,CALpB,CAhCU,CAThB,CAEA,OAAOX,EA1BqE,CAA3D,CA1BvB,CAAAH,QAAA,CAoIW,cApIX;AAoI2B,CAAC,UAAD,CAAa,QAAQ,CAACmB,CAAD,CAAW,CAErD,MAAO,KAWAC,QAAQ,CAACC,CAAD,CAAM,CAEjB,MAAO,CADHN,CACG,CADKI,CAAA,CAASE,CAAT,CACL,EAAQxB,CAAAyB,SAAA,CAAiBP,CAAjB,CAAR,CAAkCA,CAFxB,CAXd,KA0BAQ,QAAQ,CAACF,CAAD,CAAMN,CAAN,CAAa,CACxBI,CAAA,CAASE,CAAT,CAAA,CAAgBxB,CAAA2B,OAAA,CAAeT,CAAf,CADQ,CA1BrB,QAuCGU,QAAQ,CAACJ,CAAD,CAAM,CACpB,OAAOF,CAAA,CAASE,CAAT,CADa,CAvCjB,CAF8C,CAAhC,CApI3B,CAnBsC,CAArC,CAAA,CAwMEzB,MAxMF,CAwMUA,MAAAC,QAxMV;", 6 | "sources":["angular-cookies.js"], 7 | "names":["window","angular","undefined","module","factory","$rootScope","$browser","cookies","lastCookies","lastBrowserCookies","runEval","copy","isUndefined","addPollFn","currentCookies","$apply","$watch","push","name","value","updated","isString","browserCookies","$cookies","get","key","fromJson","put","toJson","remove"] 8 | } 9 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-loader.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-loader.min.js", 4 | "lineCount":8, 5 | "mappings":"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", 6 | "sources":["angular-loader.js"], 7 | "names":["minErr","setupModuleLoader","window","$injectorMinErr","ngMinErr","angular","$$minErr","factory","modules","module","name","requires","configFn","context","hasOwnProperty","invokeLater","provider","method","insertMethod","invokeQueue","arguments","moduleInstance","runBlocks","config","run","block","push"] 8 | } 9 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-touch.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.28 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(y,w,z){'use strict';function u(f,a,c){r.directive(f,["$parse","$swipe",function(m,p){var q=75,g=0.3,e=30;return function(h,n,l){function k(d){if(!b)return!1;var s=Math.abs(d.y-b.y);d=(d.x-b.x)*a;return v&&se&&s/dm&&10>p|| 8 | (p>m?(e=!1,c.cancel&&c.cancel(a)):(a.preventDefault(),c.move&&c.move(n,a)))}});a.on("touchend mouseup",function(a){e&&(e=!1,c.end&&c.end(f(a),a))})}}}]);r.config(["$provide",function(f){f.decorator("ngClickDirective",["$delegate",function(a){a.shift();return a}])}]);r.directive("ngClick",["$parse","$timeout","$rootElement",function(f,a,c){function m(a,b,c){for(var d=0;dg)){var b= 9 | a.touches&&a.touches.length?a.touches:[a],c=b[0].clientX,b=b[0].clientY;1>c&&1>b||k&&k[0]===c&&k[1]===b||(k&&(k=null),"label"===a.target.tagName.toLowerCase()&&(k=[c,b]),m(l,c,b)||(a.stopPropagation(),a.preventDefault(),a.target&&a.target.blur()))}}function q(c){c=c.touches&&c.touches.length?c.touches:[c];var b=c[0].clientX,e=c[0].clientY;l.push(b,e);a(function(){for(var a=0;ag&&12>s)&&(l||(c[0].addEventListener("click",p,!0),c[0].addEventListener("touchstart",q,!0),l=[]),n=Date.now(),m(l,f,h),t&&t.blur(),w.isDefined(e.disabled)&&!1!==e.disabled||b.triggerHandler("click",[a]));d()});b.onclick=function(a){};b.on("click",function(b,c){a.$apply(function(){g(a,{$event:c||b})})});b.on("mousedown",function(a){b.addClass(h)});b.on("mousemove mouseup",function(a){b.removeClass(h)})}}]); 12 | u("ngSwipeLeft",-1,"swipeleft");u("ngSwipeRight",1,"swiperight")})(window,window.angular); 13 | //# sourceMappingURL=angular-touch.min.js.map 14 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-resource.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.28 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(H,a,A){'use strict';function D(p,g){g=g||{};a.forEach(g,function(a,c){delete g[c]});for(var c in p)!p.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(g[c]=p[c]);return g}var v=a.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;a.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(p,g){function c(a,c){this.template=a;this.defaults=c||{};this.urlParams={}}function t(n,w,l){function r(h,d){var e={};d=x({},w,d);s(d,function(b,d){u(b)&&(b=b());var k;if(b&& 7 | b.charAt&&"@"==b.charAt(0)){k=h;var a=b.substr(1);if(null==a||""===a||"hasOwnProperty"===a||!C.test("."+a))throw v("badmember",a);for(var a=a.split("."),f=0,c=a.length;f 2 | 3 | 4 | 5 | 注册 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /web/static/js/lib/md5/md5.min.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";function b(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c}function c(a,b){return a<>>32-b}function d(a,d,e,f,g,h){return b(c(b(b(d,a),b(f,h)),g),e)}function e(a,b,c,e,f,g,h){return d(b&c|~b&e,a,b,f,g,h)}function f(a,b,c,e,f,g,h){return d(b&e|c&~e,a,b,f,g,h)}function g(a,b,c,e,f,g,h){return d(b^c^e,a,b,f,g,h)}function h(a,b,c,e,f,g,h){return d(c^(b|~e),a,b,f,g,h)}function i(a,c){a[c>>5]|=128<>>9<<4)+14]=c;var d,i,j,k,l,m=1732584193,n=-271733879,o=-1732584194,p=271733878;for(d=0;d>5]>>>b%32&255);return c}function k(a){var b,c=[];for(c[(a.length>>2)-1]=void 0,b=0;b>5]|=(255&a.charCodeAt(b/8))<16&&(e=i(e,8*a.length)),c=0;16>c;c+=1)f[c]=909522486^e[c],g[c]=1549556828^e[c];return d=i(f.concat(k(b)),512+8*b.length),j(i(g.concat(d),640))}function n(a){var b,c,d="0123456789abcdef",e="";for(c=0;c>>4&15)+d.charAt(15&b);return e}function o(a){return unescape(encodeURIComponent(a))}function p(a){return l(o(a))}function q(a){return n(p(a))}function r(a,b){return m(o(a),o(b))}function s(a,b){return n(r(a,b))}function t(a,b,c){return b?c?r(b,a):s(b,a):c?p(a):q(a)}"function"==typeof define&&define.amd?define(function(){return t}):a.md5=t}(this); -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-route.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.28 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(n,e,A){'use strict';function x(s,g,h){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,w){function y(){p&&(p.remove(),p=null);k&&(k.$destroy(),k=null);l&&(h.leave(l,function(){p=null}),p=l,l=null)}function v(){var b=s.current&&s.current.locals;if(e.isDefined(b&&b.$template)){var b=a.$new(),d=s.current;l=w(b,function(d){h.enter(d,null,l||c,function(){!e.isDefined(t)||t&&!a.$eval(t)||g()});y()});k=d.scope=b;k.$emit("$viewContentLoaded");k.$eval(u)}else y()} 7 | var k,l,p,t=b.autoscroll,u=b.onload||"";a.$on("$routeChangeSuccess",v);v()}}}function z(e,g,h){return{restrict:"ECA",priority:-400,link:function(a,c){var b=h.current,f=b.locals;c.html(f.$template);var w=e(c.contents());b.controller&&(f.$scope=a,f=g(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));w(a)}}}n=e.module("ngRoute",["ng"]).provider("$route",function(){function s(a,c){return e.extend(new (e.extend(function(){}, 8 | {prototype:a})),c)}function g(a,e){var b=e.caseInsensitiveMatch,f={originalPath:a,regexp:a},h=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,e,b,c){a="?"===c?c:null;c="*"===c?c:null;h.push({name:b,optional:!!a});e=e||"";return""+(a?"":e)+"(?:"+(a?e:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=RegExp("^"+a+"$",b?"i":"");return f}var h={};this.when=function(a,c){h[a]=e.extend({reloadOnSearch:!0},c,a&&g(a,c));if(a){var b= 9 | "/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";h[b]=e.extend({redirectTo:a},g(b,c))}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,c,b,f,g,n,v,k){function l(){var d=p(),m=r.current;if(d&&m&&d.$$route===m.$$route&&e.equals(d.pathParams,m.pathParams)&&!d.reloadOnSearch&&!u)m.params=d.params,e.copy(m.params,b),a.$broadcast("$routeUpdate",m);else if(d||m)u=!1,a.$broadcast("$routeChangeStart", 10 | d,m),(r.current=d)&&d.redirectTo&&(e.isString(d.redirectTo)?c.path(t(d.redirectTo,d.params)).search(d.params).replace():c.url(d.redirectTo(d.pathParams,c.path(),c.search())).replace()),f.when(d).then(function(){if(d){var a=e.extend({},d.resolve),c,b;e.forEach(a,function(d,c){a[c]=e.isString(d)?g.get(d):g.invoke(d)});e.isDefined(c=d.template)?e.isFunction(c)&&(c=c(d.params)):e.isDefined(b=d.templateUrl)&&(e.isFunction(b)&&(b=b(d.params)),b=k.getTrustedResourceUrl(b),e.isDefined(b)&&(d.loadedTemplateUrl= 11 | b,c=n.get(b,{cache:v}).then(function(a){return a.data})));e.isDefined(c)&&(a.$template=c);return f.all(a)}}).then(function(c){d==r.current&&(d&&(d.locals=c,e.copy(d.params,b)),a.$broadcast("$routeChangeSuccess",d,m))},function(c){d==r.current&&a.$broadcast("$routeChangeError",d,m,c)})}function p(){var a,b;e.forEach(h,function(f,h){var q;if(q=!b){var g=c.path();q=f.keys;var l={};if(f.regexp)if(g=f.regexp.exec(g)){for(var k=1,p=g.length;k 1) { 41 | attributes = extend({ 42 | path: '/' 43 | }, api.defaults, attributes); 44 | 45 | if (typeof attributes.expires === 'number') { 46 | var expires = new Date(); 47 | expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); 48 | attributes.expires = expires; 49 | } 50 | 51 | try { 52 | result = JSON.stringify(value); 53 | if (/^[\{\[]/.test(result)) { 54 | value = result; 55 | } 56 | } catch (e) {} 57 | 58 | if (!converter.write) { 59 | value = encodeURIComponent(String(value)) 60 | .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); 61 | } else { 62 | value = converter.write(value, key); 63 | } 64 | 65 | key = encodeURIComponent(String(key)); 66 | key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); 67 | key = key.replace(/[\(\)]/g, escape); 68 | 69 | return (document.cookie = [ 70 | key, '=', value, 71 | attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE 72 | attributes.path && '; path=' + attributes.path, 73 | attributes.domain && '; domain=' + attributes.domain, 74 | attributes.secure ? '; secure' : '' 75 | ].join('')); 76 | } 77 | 78 | // Read 79 | 80 | if (!key) { 81 | result = {}; 82 | } 83 | 84 | // To prevent the for loop in the first place assign an empty array 85 | // in case there are no cookies at all. Also prevents odd result when 86 | // calling "get()" 87 | var cookies = document.cookie ? document.cookie.split('; ') : []; 88 | var rdecode = /(%[0-9A-Z]{2})+/g; 89 | var i = 0; 90 | 91 | for (; i < cookies.length; i++) { 92 | var parts = cookies[i].split('='); 93 | var name = parts[0].replace(rdecode, decodeURIComponent); 94 | var cookie = parts.slice(1).join('='); 95 | 96 | if (cookie.charAt(0) === '"') { 97 | cookie = cookie.slice(1, -1); 98 | } 99 | 100 | try { 101 | cookie = converter.read ? 102 | converter.read(cookie, name) : converter(cookie, name) || 103 | cookie.replace(rdecode, decodeURIComponent); 104 | 105 | if (this.json) { 106 | try { 107 | cookie = JSON.parse(cookie); 108 | } catch (e) {} 109 | } 110 | 111 | if (key === name) { 112 | result = cookie; 113 | break; 114 | } 115 | 116 | if (!key) { 117 | result[name] = cookie; 118 | } 119 | } catch (e) {} 120 | } 121 | 122 | return result; 123 | } 124 | 125 | api.get = api.set = api; 126 | api.getJSON = function () { 127 | return api.apply({ 128 | json: true 129 | }, [].slice.call(arguments)); 130 | }; 131 | api.defaults = {}; 132 | 133 | api.remove = function (key, attributes) { 134 | api(key, '', extend(attributes, { 135 | expires: -1 136 | })); 137 | }; 138 | 139 | api.withConverter = init; 140 | 141 | return api; 142 | } 143 | 144 | return init(function () {}); 145 | })); 146 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-sanitize.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.28 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(q,g,r){'use strict';function F(a){var d=[];t(d,g.noop).chars(a);return d.join("")}function l(a){var d={};a=a.split(",");var c;for(c=0;c=c;e--)d.end&&d.end(f[e]);f.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,f=[],n=a,h;for(f.last=function(){return f[f.length-1]};a;){h="";k=!0;if(f.last()&&y[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(I,"$1").replace(J,"$1");d.chars&&d.chars(s(b));return""}),e("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(d.comment&&d.comment(a.substring(4, 8 | b)),a=a.substring(b+3),k=!1);else if(z.test(a)){if(b=a.match(z))a=a.replace(b[0],""),k=!1}else if(K.test(a)){if(b=a.match(A))a=a.substring(b[0].length),b[0].replace(A,e),k=!1}else L.test(a)&&((b=a.match(B))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(B,c)),k=!1):(h+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),h+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),d.chars&&d.chars(s(h)))}if(a==n)throw M("badparse",a);n=a}e()}function s(a){if(!a)return"";var d=N.exec(a);a=d[1];var c=d[3];if(d=d[2])p.innerHTML= 9 | d.replace(//g,">")}function t(a,d){var c=!1,e=g.bind(a,a.push);return{start:function(a,k,f){a=g.lowercase(a);!c&&y[a]&&(c=a);c||!0!==D[a]||(e("<"),e(a),g.forEach(k,function(c,f){var m= 10 | g.lowercase(f),k="img"===a&&"src"===m||"background"===m;!0!==Q[m]||!0===E[m]&&!d(c,k)||(e(" "),e(f),e('="'),e(C(c)),e('"'))}),e(f?"/>":">"))},end:function(a){a=g.lowercase(a);c||!0!==D[a]||(e(""));a==c&&(c=!1)},chars:function(a){c||e(C(a))}}}var M=g.$$minErr("$sanitize"),B=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,A=/^<\/\s*([\w:-]+)[^>]*>/,H=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,L=/^]*?)>/i,J=/"]/,c=/^mailto:/;return function(e,b){function k(a){a&&m.push(F(a))}function f(a,c){m.push("');k(c);m.push("")} 14 | if(!e)return e;for(var n,h=e,m=[],l,p;n=h.match(d);)l=n[0],n[2]==n[3]&&(l="mailto:"+l),p=n.index,k(h.substr(0,p)),f(l,n[0].replace(c,"")),h=h.substring(p+n[0].length);k(h);return a(m.join(""))}}])})(window,window.angular); 15 | //# sourceMappingURL=angular-sanitize.min.js.map 16 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/errors.json: -------------------------------------------------------------------------------- 1 | {"id":"ng","generated":"Mon Dec 15 2014 14:29:51 GMT-0800 (PST)","errors":{"ngRepeat":{"iexp":"Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.","dupes":"Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}","iidexp":"'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'."},"$sce":{"imatcher":"Matchers may only be \"self\", string patterns or RegExp objects","icontext":"Attempted to trust a value in invalid context. Context: {0}; Value: {1}","iwcard":"Illegal sequence *** in string matcher. String: {0}","insecurl":"Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}","iequirks":"Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks mode. You can fix this by adding the text to the top of your HTML document. See http://docs.angularjs.org/api/ng.$sce for more information.","unsafe":"Attempting to use an unsafe value in a safe context.","itype":"Attempted to trust a non-string value in a content requiring a string: Context: {0}"},"ngPattern":{"noregexp":"Expected {0} to be a RegExp but was {1}. Element: {2}"},"$controller":{"noscp":"Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`."},"$parse":{"isecfn":"Referencing Function in Angular expressions is disallowed! Expression: {0}","isecwindow":"Referencing the Window in Angular expressions is disallowed! Expression: {0}","ueoe":"Unexpected end of expression: {0}","isecdom":"Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}","lexerr":"Lexer Error: {0} at column{1} in expression [{2}].","isecobj":"Referencing Object in Angular expressions is disallowed! Expression: {0}","isecff":"Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}","syntax":"Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}].","isecfld":"Attempting to access a disallowed field in Angular expressions! Expression: {0}"},"jqLite":{"offargs":"jqLite#off() does not support the `selector` argument","onargs":"jqLite#on() does not support the `selector` or `eventData` parameters","nosel":"Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element"},"$animate":{"notcsel":"Expecting class selector starting with '.' got '{0}'."},"$injector":{"pget":"Provider '{0}' must define $get factory method.","cdep":"Circular dependency found: {0}","nomod":"Module '{0}' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.","modulerr":"Failed to instantiate module {0} due to:\n{1}","unpr":"Unknown provider: {0}","itkn":"Incorrect injection token! Expected service name as string, got {0}"},"ngTransclude":{"orphan":"Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: {0}"},"ngModel":{"nonassign":"Expression '{0}' is non-assignable. Element: {1}"},"$location":{"ihshprfx":"Invalid url \"{0}\", missing hash prefix \"{1}\".","ipthprfx":"Invalid url \"{0}\", missing path prefix \"{1}\".","isrcharg":"The first argument of the `$location#search()` call must be a string or an object."},"ng":{"areq":"Argument '{0}' is {1}","cpws":"Can't copy! Making copies of Window or Scope instances is not supported.","btstrpd":"App Already Bootstrapped with this Element '{0}'","cpi":"Can't copy! Source and destination are identical.","badname":"hasOwnProperty is not a valid {0} name"},"$cacheFactory":{"iid":"CacheId '{0}' is already taken!"},"$interpolate":{"noconcat":"Error while interpolating: {0}\nStrict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required. See http://docs.angularjs.org/api/ng.$sce","interr":"Can't interpolate: {0}\n{1}"},"ngOptions":{"iexp":"Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}"},"$rootScope":{"inprog":"{0} already in progress","infdig":"{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}"},"$compile":{"selmulti":"Binding to the 'multiple' attribute is not supported. Element: {0}","nodomevents":"Interpolations for HTML DOM event attributes are disallowed. Please use the ng- versions (such as ng-click instead of onclick) instead.","ctreq":"Controller '{0}', required by directive '{1}', can't be found!","nonassign":"Expression '{0}' used with directive '{1}' is non-assignable!","tplrt":"Template for directive '{0}' must have exactly one root element. {1}","iscp":"Invalid isolate scope definition for directive '{0}'. Definition: {... {1}: '{2}' ...}","multidir":"Multiple directives [{0}, {1}] asking for {2} on: {3}","tpload":"Failed to load template: {0}","uterdir":"Unterminated attribute, found '{0}' but no matching '{1}' found."},"$httpBackend":{"noxhr":"This browser does not support XMLHttpRequest."},"$resource":{"badargs":"Expected up to 4 arguments [params, data, success, error], got {0} arguments","badmember":"Dotted member path \"@{0}\" is invalid.","badname":"hasOwnProperty is not a valid parameter name.","badcfg":"Error in resource configuration. Expected response to contain an {0} but got an {1}"},"$sanitize":{"badparse":"The sanitizer was unable to parse the following block of html: {0}"}}} -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-cookies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.2.28 3 | * (c) 2010-2014 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) {'use strict'; 7 | 8 | /** 9 | * @ngdoc module 10 | * @name ngCookies 11 | * @description 12 | * 13 | * # ngCookies 14 | * 15 | * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies. 16 | * 17 | * 18 | *
19 | * 20 | * See {@link ngCookies.$cookies `$cookies`} and 21 | * {@link ngCookies.$cookieStore `$cookieStore`} for usage. 22 | */ 23 | 24 | 25 | angular.module('ngCookies', ['ng']). 26 | /** 27 | * @ngdoc service 28 | * @name $cookies 29 | * 30 | * @description 31 | * Provides read/write access to browser's cookies. 32 | * 33 | * Only a simple Object is exposed and by adding or removing properties to/from this object, new 34 | * cookies are created/deleted at the end of current $eval. 35 | * The object's properties can only be strings. 36 | * 37 | * Requires the {@link ngCookies `ngCookies`} module to be installed. 38 | * 39 | * @example 40 | * 41 | * ```js 42 | * angular.module('cookiesExample', ['ngCookies']) 43 | * .controller('ExampleController', ['$cookies', function($cookies) { 44 | * // Retrieving a cookie 45 | * var favoriteCookie = $cookies.myFavorite; 46 | * // Setting a cookie 47 | * $cookies.myFavorite = 'oatmeal'; 48 | * }]); 49 | * ``` 50 | */ 51 | factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) { 52 | var cookies = {}, 53 | lastCookies = {}, 54 | lastBrowserCookies, 55 | runEval = false, 56 | copy = angular.copy, 57 | isUndefined = angular.isUndefined; 58 | 59 | //creates a poller fn that copies all cookies from the $browser to service & inits the service 60 | $browser.addPollFn(function() { 61 | var currentCookies = $browser.cookies(); 62 | if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl 63 | lastBrowserCookies = currentCookies; 64 | copy(currentCookies, lastCookies); 65 | copy(currentCookies, cookies); 66 | if (runEval) $rootScope.$apply(); 67 | } 68 | })(); 69 | 70 | runEval = true; 71 | 72 | //at the end of each eval, push cookies 73 | //TODO: this should happen before the "delayed" watches fire, because if some cookies are not 74 | // strings or browser refuses to store some cookies, we update the model in the push fn. 75 | $rootScope.$watch(push); 76 | 77 | return cookies; 78 | 79 | 80 | /** 81 | * Pushes all the cookies from the service to the browser and verifies if all cookies were 82 | * stored. 83 | */ 84 | function push() { 85 | var name, 86 | value, 87 | browserCookies, 88 | updated; 89 | 90 | //delete any cookies deleted in $cookies 91 | for (name in lastCookies) { 92 | if (isUndefined(cookies[name])) { 93 | $browser.cookies(name, undefined); 94 | } 95 | } 96 | 97 | //update all cookies updated in $cookies 98 | for(name in cookies) { 99 | value = cookies[name]; 100 | if (!angular.isString(value)) { 101 | value = '' + value; 102 | cookies[name] = value; 103 | } 104 | if (value !== lastCookies[name]) { 105 | $browser.cookies(name, value); 106 | updated = true; 107 | } 108 | } 109 | 110 | //verify what was actually stored 111 | if (updated){ 112 | updated = false; 113 | browserCookies = $browser.cookies(); 114 | 115 | for (name in cookies) { 116 | if (cookies[name] !== browserCookies[name]) { 117 | //delete or reset all cookies that the browser dropped from $cookies 118 | if (isUndefined(browserCookies[name])) { 119 | delete cookies[name]; 120 | } else { 121 | cookies[name] = browserCookies[name]; 122 | } 123 | updated = true; 124 | } 125 | } 126 | } 127 | } 128 | }]). 129 | 130 | 131 | /** 132 | * @ngdoc service 133 | * @name $cookieStore 134 | * @requires $cookies 135 | * 136 | * @description 137 | * Provides a key-value (string-object) storage, that is backed by session cookies. 138 | * Objects put or retrieved from this storage are automatically serialized or 139 | * deserialized by angular's toJson/fromJson. 140 | * 141 | * Requires the {@link ngCookies `ngCookies`} module to be installed. 142 | * 143 | * @example 144 | * 145 | * ```js 146 | * angular.module('cookieStoreExample', ['ngCookies']) 147 | * .controller('ExampleController', ['$cookieStore', function($cookieStore) { 148 | * // Put cookie 149 | * $cookieStore.put('myFavorite','oatmeal'); 150 | * // Get cookie 151 | * var favoriteCookie = $cookieStore.get('myFavorite'); 152 | * // Removing a cookie 153 | * $cookieStore.remove('myFavorite'); 154 | * }]); 155 | * ``` 156 | */ 157 | factory('$cookieStore', ['$cookies', function($cookies) { 158 | 159 | return { 160 | /** 161 | * @ngdoc method 162 | * @name $cookieStore#get 163 | * 164 | * @description 165 | * Returns the value of given cookie key 166 | * 167 | * @param {string} key Id to use for lookup. 168 | * @returns {Object} Deserialized cookie value. 169 | */ 170 | get: function(key) { 171 | var value = $cookies[key]; 172 | return value ? angular.fromJson(value) : value; 173 | }, 174 | 175 | /** 176 | * @ngdoc method 177 | * @name $cookieStore#put 178 | * 179 | * @description 180 | * Sets a value for given cookie key 181 | * 182 | * @param {string} key Id for the `value`. 183 | * @param {Object} value Value to be stored. 184 | */ 185 | put: function(key, value) { 186 | $cookies[key] = angular.toJson(value); 187 | }, 188 | 189 | /** 190 | * @ngdoc method 191 | * @name $cookieStore#remove 192 | * 193 | * @description 194 | * Remove given cookie 195 | * 196 | * @param {string} key Id of the key-value pair to delete. 197 | */ 198 | remove: function(key) { 199 | delete $cookies[key]; 200 | } 201 | }; 202 | 203 | }]); 204 | 205 | 206 | })(window, window.angular); 207 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-resource.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-resource.min.js", 4 | "lineCount":12, 5 | "mappings":"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", 6 | "sources":["angular-resource.js"], 7 | "names":["window","angular","undefined","shallowClearAndCopy","src","dst","forEach","value","key","hasOwnProperty","charAt","$resourceMinErr","$$minErr","MEMBER_NAME_REGEX","module","factory","$http","$q","Route","template","defaults","urlParams","resourceFactory","url","paramDefaults","actions","extractParams","data","actionParams","ids","extend","isFunction","path","test","keys","split","i","ii","length","obj","defaultResponseInterceptor","response","resource","Resource","route","DEFAULT_ACTIONS","action","name","hasBody","method","a1","a2","a3","a4","params","success","error","arguments","isInstanceCall","isArray","httpConfig","responseInterceptor","interceptor","responseErrorInterceptor","responseError","copy","setUrlParams","promise","then","$promise","item","push","$resolved","noop","reject","headers","prototype","result","call","bind","Resource.bind","additionalParamDefaults","config","actionUrl","self","val","encodedVal","param","RegExp","replace","_","urlParam","isDefined","encodeURIComponent","match","p1","leadingSlashes","tail"] 8 | } 9 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-touch.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-touch.min.js", 4 | "lineCount":12, 5 | "mappings":"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", 6 | "sources":["angular-touch.js"], 7 | "names":["window","angular","undefined","makeSwipeDirective","directiveName","direction","eventName","ngTouch","directive","$parse","$swipe","MAX_VERTICAL_DISTANCE","MAX_VERTICAL_RATIO","MIN_HORIZONTAL_DISTANCE","scope","element","attr","validSwipe","coords","startCoords","deltaY","Math","abs","y","deltaX","x","valid","swipeHandler","bind","start","event","cancel","end","$apply","triggerHandler","module","factory","getCoordinates","touches","length","e","changedTouches","originalEvent","clientX","clientY","eventHandlers","totalX","totalY","lastPos","active","on","MOVE_BUFFER_RADIUS","preventDefault","config","$provide","decorator","$delegate","shift","$timeout","$rootElement","checkAllowableRegions","touchCoordinates","i","x1","CLICKBUSTER_THRESHOLD","y1","splice","onClick","Date","now","lastPreventedTime","PREVENT_DURATION","lastLabelClickCoordinates","target","tagName","toLowerCase","stopPropagation","blur","onTouchStart","push","ACTIVE_CLASS_NAME","resetState","tapping","removeClass","clickHandler","ngClick","tapElement","startTime","touchStartX","touchStartY","srcElement","nodeType","parentNode","addClass","diff","dist","sqrt","pow","TAP_DURATION","MOVE_TOLERANCE","addEventListener","isDefined","disabled","onclick","element.onclick","touchend"] 8 | } 9 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-route.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-route.min.js", 4 | "lineCount":13, 5 | "mappings":"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", 6 | "sources":["angular-route.js"], 7 | "names":["window","angular","undefined","ngViewFactory","$route","$anchorScroll","$animate","link","scope","$element","attr","ctrl","$transclude","cleanupLastView","previousElement","remove","currentScope","$destroy","currentElement","leave","update","locals","current","isDefined","$template","newScope","$new","clone","enter","onNgViewEnter","autoScrollExp","$eval","$emit","onloadExp","autoscroll","onload","$on","ngViewFillContentFactory","$compile","$controller","html","contents","controller","$scope","controllerAs","data","children","ngRouteModule","module","provider","$RouteProvider","inherit","parent","extra","extend","pathRegExp","path","opts","insensitive","caseInsensitiveMatch","ret","keys","replace","_","slash","key","option","optional","star","push","regexp","RegExp","routes","when","this.when","route","redirectPath","length","substr","otherwise","this.otherwise","params","$get","$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce","updateRoute","next","parseRoute","last","$$route","equals","pathParams","reloadOnSearch","forceReload","copy","$broadcast","redirectTo","isString","interpolate","search","url","then","resolve","template","templateUrl","forEach","value","get","invoke","isFunction","getTrustedResourceUrl","loadedTemplateUrl","response","all","error","match","m","exec","on","i","len","val","name","string","result","split","segment","segmentMatch","join","reload","$evalAsync","$RouteParamsProvider","this.$get","directive","$inject"] 8 | } 9 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-sanitize.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-sanitize.min.js", 4 | "lineCount":14, 5 | "mappings":"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", 6 | "sources":["angular-sanitize.js"], 7 | "names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","obj","items","split","i","length","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","lowercase","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","text","stack.last","specialElements","RegExp","all","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","parts","spaceRe","exec","spaceBefore","spaceAfter","content","hiddenPre","innerHTML","textContent","innerText","encodeEntities","SURROGATE_PAIR_REGEXP","hi","charCodeAt","low","NON_ALPHANUMERIC_REGEXP","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"] 8 | } 9 | -------------------------------------------------------------------------------- /web/static/js/lib/md5/md5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * JavaScript MD5 1.0.1 3 | * https://github.com/blueimp/JavaScript-MD5 4 | * 5 | * Copyright 2011, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | * 11 | * Based on 12 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 13 | * Digest Algorithm, as defined in RFC 1321. 14 | * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 15 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 16 | * Distributed under the BSD License 17 | * See http://pajhome.org.uk/crypt/md5 for more info. 18 | */ 19 | 20 | /*jslint bitwise: true */ 21 | /*global unescape, define */ 22 | 23 | (function ($) { 24 | 'use strict'; 25 | 26 | /* 27 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 28 | * to work around bugs in some JS interpreters. 29 | */ 30 | function safe_add(x, y) { 31 | var lsw = (x & 0xFFFF) + (y & 0xFFFF), 32 | msw = (x >> 16) + (y >> 16) + (lsw >> 16); 33 | return (msw << 16) | (lsw & 0xFFFF); 34 | } 35 | 36 | /* 37 | * Bitwise rotate a 32-bit number to the left. 38 | */ 39 | function bit_rol(num, cnt) { 40 | return (num << cnt) | (num >>> (32 - cnt)); 41 | } 42 | 43 | /* 44 | * These functions implement the four basic operations the algorithm uses. 45 | */ 46 | function md5_cmn(q, a, b, x, s, t) { 47 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); 48 | } 49 | function md5_ff(a, b, c, d, x, s, t) { 50 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); 51 | } 52 | function md5_gg(a, b, c, d, x, s, t) { 53 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); 54 | } 55 | function md5_hh(a, b, c, d, x, s, t) { 56 | return md5_cmn(b ^ c ^ d, a, b, x, s, t); 57 | } 58 | function md5_ii(a, b, c, d, x, s, t) { 59 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); 60 | } 61 | 62 | /* 63 | * Calculate the MD5 of an array of little-endian words, and a bit length. 64 | */ 65 | function binl_md5(x, len) { 66 | /* append padding */ 67 | x[len >> 5] |= 0x80 << (len % 32); 68 | x[(((len + 64) >>> 9) << 4) + 14] = len; 69 | 70 | var i, olda, oldb, oldc, oldd, 71 | a = 1732584193, 72 | b = -271733879, 73 | c = -1732584194, 74 | d = 271733878; 75 | 76 | for (i = 0; i < x.length; i += 16) { 77 | olda = a; 78 | oldb = b; 79 | oldc = c; 80 | oldd = d; 81 | 82 | a = md5_ff(a, b, c, d, x[i], 7, -680876936); 83 | d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); 84 | c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); 85 | b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); 86 | a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); 87 | d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); 88 | c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); 89 | b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); 90 | a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); 91 | d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); 92 | c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); 93 | b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); 94 | a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); 95 | d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); 96 | c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); 97 | b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); 98 | 99 | a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); 100 | d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); 101 | c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); 102 | b = md5_gg(b, c, d, a, x[i], 20, -373897302); 103 | a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); 104 | d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); 105 | c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); 106 | b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); 107 | a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); 108 | d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); 109 | c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); 110 | b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); 111 | a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); 112 | d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); 113 | c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); 114 | b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); 115 | 116 | a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); 117 | d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); 118 | c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); 119 | b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); 120 | a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); 121 | d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); 122 | c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); 123 | b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); 124 | a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); 125 | d = md5_hh(d, a, b, c, x[i], 11, -358537222); 126 | c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); 127 | b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); 128 | a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); 129 | d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); 130 | c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); 131 | b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); 132 | 133 | a = md5_ii(a, b, c, d, x[i], 6, -198630844); 134 | d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); 135 | c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); 136 | b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); 137 | a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); 138 | d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); 139 | c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); 140 | b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); 141 | a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); 142 | d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); 143 | c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); 144 | b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); 145 | a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); 146 | d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); 147 | c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); 148 | b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); 149 | 150 | a = safe_add(a, olda); 151 | b = safe_add(b, oldb); 152 | c = safe_add(c, oldc); 153 | d = safe_add(d, oldd); 154 | } 155 | return [a, b, c, d]; 156 | } 157 | 158 | /* 159 | * Convert an array of little-endian words to a string 160 | */ 161 | function binl2rstr(input) { 162 | var i, 163 | output = ''; 164 | for (i = 0; i < input.length * 32; i += 8) { 165 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); 166 | } 167 | return output; 168 | } 169 | 170 | /* 171 | * Convert a raw string to an array of little-endian words 172 | * Characters >255 have their high-byte silently ignored. 173 | */ 174 | function rstr2binl(input) { 175 | var i, 176 | output = []; 177 | output[(input.length >> 2) - 1] = undefined; 178 | for (i = 0; i < output.length; i += 1) { 179 | output[i] = 0; 180 | } 181 | for (i = 0; i < input.length * 8; i += 8) { 182 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); 183 | } 184 | return output; 185 | } 186 | 187 | /* 188 | * Calculate the MD5 of a raw string 189 | */ 190 | function rstr_md5(s) { 191 | return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); 192 | } 193 | 194 | /* 195 | * Calculate the HMAC-MD5, of a key and some data (raw strings) 196 | */ 197 | function rstr_hmac_md5(key, data) { 198 | var i, 199 | bkey = rstr2binl(key), 200 | ipad = [], 201 | opad = [], 202 | hash; 203 | ipad[15] = opad[15] = undefined; 204 | if (bkey.length > 16) { 205 | bkey = binl_md5(bkey, key.length * 8); 206 | } 207 | for (i = 0; i < 16; i += 1) { 208 | ipad[i] = bkey[i] ^ 0x36363636; 209 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 210 | } 211 | hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); 212 | return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); 213 | } 214 | 215 | /* 216 | * Convert a raw string to a hex string 217 | */ 218 | function rstr2hex(input) { 219 | var hex_tab = '0123456789abcdef', 220 | output = '', 221 | x, 222 | i; 223 | for (i = 0; i < input.length; i += 1) { 224 | x = input.charCodeAt(i); 225 | output += hex_tab.charAt((x >>> 4) & 0x0F) + 226 | hex_tab.charAt(x & 0x0F); 227 | } 228 | return output; 229 | } 230 | 231 | /* 232 | * Encode a string as utf-8 233 | */ 234 | function str2rstr_utf8(input) { 235 | return unescape(encodeURIComponent(input)); 236 | } 237 | 238 | /* 239 | * Take string arguments and return either raw or hex encoded strings 240 | */ 241 | function raw_md5(s) { 242 | return rstr_md5(str2rstr_utf8(s)); 243 | } 244 | function hex_md5(s) { 245 | return rstr2hex(raw_md5(s)); 246 | } 247 | function raw_hmac_md5(k, d) { 248 | return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)); 249 | } 250 | function hex_hmac_md5(k, d) { 251 | return rstr2hex(raw_hmac_md5(k, d)); 252 | } 253 | 254 | function md5(string, key, raw) { 255 | if (!key) { 256 | if (!raw) { 257 | return hex_md5(string); 258 | } 259 | return raw_md5(string); 260 | } 261 | if (!raw) { 262 | return hex_hmac_md5(key, string); 263 | } 264 | return raw_hmac_md5(key, string); 265 | } 266 | 267 | if (typeof define === 'function' && define.amd) { 268 | define(function () { 269 | return md5; 270 | }); 271 | } else { 272 | $.md5 = md5; 273 | } 274 | }(this)); 275 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-animate.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.28 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(G,d,P){'use strict';d.module("ngAnimate",["ng"]).directive("ngAnimateChildren",function(){return function(H,z,e){e=e.ngAnimateChildren;d.isString(e)&&0===e.length?z.data("$$ngAnimateChildren",!0):H.$watch(e,function(d){z.data("$$ngAnimateChildren",!!d)})}}).factory("$$animateReflow",["$$rAF","$document",function(d,z){return function(e){return d(function(){e()})}}]).config(["$provide","$animateProvider",function(H,z){function e(d){for(var e=0;e=x&&b>=t&&d()}var k=e(b);a=b.data(u);if(-1!=k.getAttribute("class").indexOf(c)&&a){var n="";w(c.split(" "),function(a,b){n+=(0} */ 108 | var modules = {}; 109 | 110 | /** 111 | * @ngdoc function 112 | * @name angular.module 113 | * @module ng 114 | * @description 115 | * 116 | * The `angular.module` is a global place for creating, registering and retrieving Angular 117 | * modules. 118 | * All modules (angular core or 3rd party) that should be available to an application must be 119 | * registered using this mechanism. 120 | * 121 | * When passed two or more arguments, a new module is created. If passed only one argument, an 122 | * existing module (the name passed as the first argument to `module`) is retrieved. 123 | * 124 | * 125 | * # Module 126 | * 127 | * A module is a collection of services, directives, controllers, filters, and configuration information. 128 | * `angular.module` is used to configure the {@link auto.$injector $injector}. 129 | * 130 | * ```js 131 | * // Create a new module 132 | * var myModule = angular.module('myModule', []); 133 | * 134 | * // register a new service 135 | * myModule.value('appName', 'MyCoolApp'); 136 | * 137 | * // configure existing services inside initialization blocks. 138 | * myModule.config(['$locationProvider', function($locationProvider) { 139 | * // Configure existing providers 140 | * $locationProvider.hashPrefix('!'); 141 | * }]); 142 | * ``` 143 | * 144 | * Then you can create an injector and load your modules like this: 145 | * 146 | * ```js 147 | * var injector = angular.injector(['ng', 'myModule']) 148 | * ``` 149 | * 150 | * However it's more likely that you'll just use 151 | * {@link ng.directive:ngApp ngApp} or 152 | * {@link angular.bootstrap} to simplify this process for you. 153 | * 154 | * @param {!string} name The name of the module to create or retrieve. 155 | * @param {!Array.=} requires If specified then new module is being created. If 156 | * unspecified then the module is being retrieved for further configuration. 157 | * @param {Function=} configFn Optional configuration function for the module. Same as 158 | * {@link angular.Module#config Module#config()}. 159 | * @returns {module} new module with the {@link angular.Module} api. 160 | */ 161 | return function module(name, requires, configFn) { 162 | var assertNotHasOwnProperty = function(name, context) { 163 | if (name === 'hasOwnProperty') { 164 | throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); 165 | } 166 | }; 167 | 168 | assertNotHasOwnProperty(name, 'module'); 169 | if (requires && modules.hasOwnProperty(name)) { 170 | modules[name] = null; 171 | } 172 | return ensure(modules, name, function() { 173 | if (!requires) { 174 | throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + 175 | "the module name or forgot to load it. If registering a module ensure that you " + 176 | "specify the dependencies as the second argument.", name); 177 | } 178 | 179 | /** @type {!Array.>} */ 180 | var invokeQueue = []; 181 | 182 | /** @type {!Array.} */ 183 | var runBlocks = []; 184 | 185 | var config = invokeLater('$injector', 'invoke'); 186 | 187 | /** @type {angular.Module} */ 188 | var moduleInstance = { 189 | // Private state 190 | _invokeQueue: invokeQueue, 191 | _runBlocks: runBlocks, 192 | 193 | /** 194 | * @ngdoc property 195 | * @name angular.Module#requires 196 | * @module ng 197 | * 198 | * @description 199 | * Holds the list of modules which the injector will load before the current module is 200 | * loaded. 201 | */ 202 | requires: requires, 203 | 204 | /** 205 | * @ngdoc property 206 | * @name angular.Module#name 207 | * @module ng 208 | * 209 | * @description 210 | * Name of the module. 211 | */ 212 | name: name, 213 | 214 | 215 | /** 216 | * @ngdoc method 217 | * @name angular.Module#provider 218 | * @module ng 219 | * @param {string} name service name 220 | * @param {Function} providerType Construction function for creating new instance of the 221 | * service. 222 | * @description 223 | * See {@link auto.$provide#provider $provide.provider()}. 224 | */ 225 | provider: invokeLater('$provide', 'provider'), 226 | 227 | /** 228 | * @ngdoc method 229 | * @name angular.Module#factory 230 | * @module ng 231 | * @param {string} name service name 232 | * @param {Function} providerFunction Function for creating new instance of the service. 233 | * @description 234 | * See {@link auto.$provide#factory $provide.factory()}. 235 | */ 236 | factory: invokeLater('$provide', 'factory'), 237 | 238 | /** 239 | * @ngdoc method 240 | * @name angular.Module#service 241 | * @module ng 242 | * @param {string} name service name 243 | * @param {Function} constructor A constructor function that will be instantiated. 244 | * @description 245 | * See {@link auto.$provide#service $provide.service()}. 246 | */ 247 | service: invokeLater('$provide', 'service'), 248 | 249 | /** 250 | * @ngdoc method 251 | * @name angular.Module#value 252 | * @module ng 253 | * @param {string} name service name 254 | * @param {*} object Service instance object. 255 | * @description 256 | * See {@link auto.$provide#value $provide.value()}. 257 | */ 258 | value: invokeLater('$provide', 'value'), 259 | 260 | /** 261 | * @ngdoc method 262 | * @name angular.Module#constant 263 | * @module ng 264 | * @param {string} name constant name 265 | * @param {*} object Constant value. 266 | * @description 267 | * Because the constant are fixed, they get applied before other provide methods. 268 | * See {@link auto.$provide#constant $provide.constant()}. 269 | */ 270 | constant: invokeLater('$provide', 'constant', 'unshift'), 271 | 272 | /** 273 | * @ngdoc method 274 | * @name angular.Module#animation 275 | * @module ng 276 | * @param {string} name animation name 277 | * @param {Function} animationFactory Factory function for creating new instance of an 278 | * animation. 279 | * @description 280 | * 281 | * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. 282 | * 283 | * 284 | * Defines an animation hook that can be later used with 285 | * {@link ngAnimate.$animate $animate} service and directives that use this service. 286 | * 287 | * ```js 288 | * module.animation('.animation-name', function($inject1, $inject2) { 289 | * return { 290 | * eventName : function(element, done) { 291 | * //code to run the animation 292 | * //once complete, then run done() 293 | * return function cancellationFunction(element) { 294 | * //code to cancel the animation 295 | * } 296 | * } 297 | * } 298 | * }) 299 | * ``` 300 | * 301 | * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and 302 | * {@link ngAnimate ngAnimate module} for more information. 303 | */ 304 | animation: invokeLater('$animateProvider', 'register'), 305 | 306 | /** 307 | * @ngdoc method 308 | * @name angular.Module#filter 309 | * @module ng 310 | * @param {string} name Filter name. 311 | * @param {Function} filterFactory Factory function for creating new instance of filter. 312 | * @description 313 | * See {@link ng.$filterProvider#register $filterProvider.register()}. 314 | */ 315 | filter: invokeLater('$filterProvider', 'register'), 316 | 317 | /** 318 | * @ngdoc method 319 | * @name angular.Module#controller 320 | * @module ng 321 | * @param {string|Object} name Controller name, or an object map of controllers where the 322 | * keys are the names and the values are the constructors. 323 | * @param {Function} constructor Controller constructor function. 324 | * @description 325 | * See {@link ng.$controllerProvider#register $controllerProvider.register()}. 326 | */ 327 | controller: invokeLater('$controllerProvider', 'register'), 328 | 329 | /** 330 | * @ngdoc method 331 | * @name angular.Module#directive 332 | * @module ng 333 | * @param {string|Object} name Directive name, or an object map of directives where the 334 | * keys are the names and the values are the factories. 335 | * @param {Function} directiveFactory Factory function for creating new instance of 336 | * directives. 337 | * @description 338 | * See {@link ng.$compileProvider#directive $compileProvider.directive()}. 339 | */ 340 | directive: invokeLater('$compileProvider', 'directive'), 341 | 342 | /** 343 | * @ngdoc method 344 | * @name angular.Module#config 345 | * @module ng 346 | * @param {Function} configFn Execute this function on module load. Useful for service 347 | * configuration. 348 | * @description 349 | * Use this method to register work which needs to be performed on module loading. 350 | * For more about how to configure services, see 351 | * {@link providers#providers_provider-recipe Provider Recipe}. 352 | */ 353 | config: config, 354 | 355 | /** 356 | * @ngdoc method 357 | * @name angular.Module#run 358 | * @module ng 359 | * @param {Function} initializationFn Execute this function after injector creation. 360 | * Useful for application initialization. 361 | * @description 362 | * Use this method to register work which should be performed when the injector is done 363 | * loading all modules. 364 | */ 365 | run: function(block) { 366 | runBlocks.push(block); 367 | return this; 368 | } 369 | }; 370 | 371 | if (configFn) { 372 | config(configFn); 373 | } 374 | 375 | return moduleInstance; 376 | 377 | /** 378 | * @param {string} provider 379 | * @param {string} method 380 | * @param {String=} insertMethod 381 | * @returns {angular.Module} 382 | */ 383 | function invokeLater(provider, method, insertMethod) { 384 | return function() { 385 | invokeQueue[insertMethod || 'push']([provider, method, arguments]); 386 | return moduleInstance; 387 | }; 388 | } 389 | }); 390 | }; 391 | }); 392 | 393 | } 394 | 395 | setupModuleLoader(window); 396 | })(window); 397 | 398 | /** 399 | * Closure compiler type information 400 | * 401 | * @typedef { { 402 | * requires: !Array., 403 | * invokeQueue: !Array.>, 404 | * 405 | * service: function(string, Function):angular.Module, 406 | * factory: function(string, Function):angular.Module, 407 | * value: function(string, *):angular.Module, 408 | * 409 | * filter: function(string, Function):angular.Module, 410 | * 411 | * init: function(Function):angular.Module 412 | * } } 413 | */ 414 | angular.Module; 415 | 416 | -------------------------------------------------------------------------------- /web/static/js/lib/zepto/zepto.min.js: -------------------------------------------------------------------------------- 1 | /* Zepto v1.0rc1 - polyfill zepto event detect fx ajax form touch - zeptojs.com/license */ 2 | (function(a){String.prototype.trim===a&&(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),Array.prototype.reduce===a&&(Array.prototype.reduce=function(b){if(this===void 0||this===null)throw new TypeError;var c=Object(this),d=c.length>>>0,e=0,f;if(typeof b!="function")throw new TypeError;if(d==0&&arguments.length==1)throw new TypeError;if(arguments.length>=2)f=arguments[1];else do{if(e in c){f=c[e++];break}if(++e>=d)throw new TypeError}while(!0);while(e0?[].concat.apply([],a):a}function H(a){return a.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 I(a){return a in i?i[a]:i[a]=new RegExp("(^|\\s)"+a+"(\\s|$)")}function J(a,b){return typeof b=="number"&&!k[H(a)]?b+"px":b}function K(a){var b,c;return h[a]||(b=g.createElement(a),g.body.appendChild(b),c=j(b,"").getPropertyValue("display"),b.parentNode.removeChild(b),c=="none"&&(c="block"),h[a]=c),h[a]}function L(b,d){return d===a?c(b):c(b).filter(d)}function M(a,b,c,d){return A(b)?b.call(a,c,d):b}function N(a,b,d){var e=a%2?b:b.parentNode;e?e.insertBefore(d,a?a==1?e.firstChild:a==2?b:null:b.nextSibling):c(d).remove()}function O(a,b){b(a);for(var c in a.childNodes)O(a.childNodes[c],b)}var a,b,c,d,e=[],f=e.slice,g=window.document,h={},i={},j=g.defaultView.getComputedStyle,k={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},l=/^\s*<(\w+|!)[^>]*>/,m=[1,3,8,9,11],n=["after","prepend","before","append"],o=g.createElement("table"),p=g.createElement("tr"),q={tr:g.createElement("tbody"),tbody:o,thead:o,tfoot:o,td:p,th:p,"*":g.createElement("div")},r=/complete|loaded|interactive/,s=/^\.([\w-]+)$/,t=/^#([\w-]+)$/,u=/^[\w-]+$/,v={}.toString,w={},x,y,z=g.createElement("div");return w.matches=function(a,b){if(!a||a.nodeType!==1)return!1;var c=a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.matchesSelector;if(c)return c.call(a,b);var d,e=a.parentNode,f=!e;return f&&(e=z).appendChild(a),d=~w.qsa(e,b).indexOf(a),f&&z.removeChild(a),d},x=function(a){return a.replace(/-+(.)?/g,function(a,b){return b?b.toUpperCase():""})},y=function(a){return a.filter(function(b,c){return a.indexOf(b)==c})},w.fragment=function(b,d){d===a&&(d=l.test(b)&&RegExp.$1),d in q||(d="*");var e=q[d];return e.innerHTML=""+b,c.each(f.call(e.childNodes),function(){e.removeChild(this)})},w.Z=function(a,b){return a=a||[],a.__proto__=arguments.callee.prototype,a.selector=b||"",a},w.isZ=function(a){return a instanceof w.Z},w.init=function(b,d){if(!b)return w.Z();if(A(b))return c(g).ready(b);if(w.isZ(b))return b;var e;if(D(b))e=F(b);else if(C(b))e=[c.extend({},b)],b=null;else if(m.indexOf(b.nodeType)>=0||b===window)e=[b],b=null;else if(l.test(b))e=w.fragment(b.trim(),RegExp.$1),b=null;else{if(d!==a)return c(d).find(b);e=w.qsa(g,b)}return w.Z(e,b)},c=function(a,b){return w.init(a,b)},c.extend=function(c){return f.call(arguments,1).forEach(function(d){for(b in d)d[b]!==a&&(c[b]=d[b])}),c},w.qsa=function(a,b){var c;return a===g&&t.test(b)?(c=a.getElementById(RegExp.$1))?[c]:e:a.nodeType!==1&&a.nodeType!==9?e:f.call(s.test(b)?a.getElementsByClassName(RegExp.$1):u.test(b)?a.getElementsByTagName(b):a.querySelectorAll(b))},c.isFunction=A,c.isObject=B,c.isArray=D,c.isPlainObject=C,c.inArray=function(a,b,c){return e.indexOf.call(b,a,c)},c.trim=function(a){return a.trim()},c.uuid=0,c.map=function(a,b){var c,d=[],e,f;if(E(a))for(e=0;e0&&w.matches(this[0],a)},not:function(b){var d=[];if(A(b)&&b.call!==a)this.each(function(a){b.call(this,a)||d.push(this)});else{var e=typeof b=="string"?this.filter(b):E(b)&&A(b.item)?f.call(b):c(b);this.forEach(function(a){e.indexOf(a)<0&&d.push(a)})}return c(d)},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){var a=this[0];return a&&!B(a)?a:c(a)},last:function(){var a=this[this.length-1];return a&&!B(a)?a:c(a)},find:function(a){var b;return this.length==1?b=w.qsa(this[0],a):b=this.map(function(){return w.qsa(this,a)}),c(b)},closest:function(a,b){var d=this[0];while(d&&!w.matches(d,a))d=d!==b&&d!==g&&d.parentNode;return c(d)},parents:function(a){var b=[],d=this;while(d.length>0)d=c.map(d,function(a){if((a=a.parentNode)&&a!==g&&b.indexOf(a)<0)return b.push(a),a});return L(b,a)},parent:function(a){return L(y(this.pluck("parentNode")),a)},children:function(a){return L(this.map(function(){return f.call(this.children)}),a)},siblings:function(a){return L(this.map(function(a,b){return f.call(b.parentNode.children).filter(function(a){return a!==b})}),a)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(a){return this.map(function(){return this[a]})},show:function(){return this.each(function(){this.style.display=="none"&&(this.style.display=null),j(this,"").getPropertyValue("display")=="none"&&(this.style.display=K(this.nodeName))})},replaceWith:function(a){return this.before(a).remove()},wrap:function(a){return this.each(function(){c(this).wrapAll(c(a)[0].cloneNode(!1))})},wrapAll:function(a){return this[0]&&(c(this[0]).before(a=c(a)),a.append(this)),this},unwrap:function(){return this.parent().each(function(){c(this).replaceWith(c(this).children())}),this},clone:function(){return c(this.map(function(){return this.cloneNode(!0)}))},hide:function(){return this.css("display","none")},toggle:function(b){return(b===a?this.css("display")=="none":b)?this.show():this.hide()},prev:function(){return c(this.pluck("previousElementSibling"))},next:function(){return c(this.pluck("nextElementSibling"))},html:function(b){return b===a?this.length>0?this[0].innerHTML:null:this.each(function(a){var d=this.innerHTML;c(this).empty().append(M(this,b,a,d))})},text:function(b){return b===a?this.length>0?this[0].textContent:null:this.each(function(){this.textContent=b})},attr:function(c,d){var e;return typeof c=="string"&&d===a?this.length==0||this[0].nodeType!==1?a:c=="value"&&this[0].nodeName=="INPUT"?this.val():!(e=this[0].getAttribute(c))&&c in this[0]?this[0][c]:e:this.each(function(a){if(this.nodeType!==1)return;if(B(c))for(b in c)this.setAttribute(b,c[b]);else this.setAttribute(c,M(this,d,a,this.getAttribute(c)))})},removeAttr:function(a){return this.each(function(){this.nodeType===1&&this.removeAttribute(a)})},prop:function(b,c){return c===a?this[0]?this[0][b]:a:this.each(function(a){this[b]=M(this,c,a,this[b])})},data:function(b,c){var d=this.attr("data-"+H(b),c);return d!==null?d:a},val:function(b){return b===a?this.length>0?this[0].value:a:this.each(function(a){this.value=M(this,b,a,this.value)})},offset:function(){if(this.length==0)return null;var a=this[0].getBoundingClientRect();return{left:a.left+window.pageXOffset,top:a.top+window.pageYOffset,width:a.width,height:a.height}},css:function(c,d){if(d===a&&typeof c=="string")return this.length==0?a:this[0].style[x(c)]||j(this[0],"").getPropertyValue(c);var e="";for(b in c)typeof c[b]=="string"&&c[b]==""?this.each(function(){this.style.removeProperty(H(b))}):e+=H(b)+":"+J(b,c[b])+";";return typeof c=="string"&&(d==""?this.each(function(){this.style.removeProperty(H(c))}):e=H(c)+":"+J(c,d)),this.each(function(){this.style.cssText+=";"+e})},index:function(a){return a?this.indexOf(c(a)[0]):this.parent().children().indexOf(this[0])},hasClass:function(a){return this.length<1?!1:I(a).test(this[0].className)},addClass:function(a){return this.each(function(b){d=[];var e=this.className,f=M(this,a,b,e);f.split(/\s+/g).forEach(function(a){c(this).hasClass(a)||d.push(a)},this),d.length&&(this.className+=(e?" ":"")+d.join(" "))})},removeClass:function(b){return this.each(function(c){if(b===a)return this.className="";d=this.className,M(this,b,c,d).split(/\s+/g).forEach(function(a){d=d.replace(I(a)," ")}),this.className=d.trim()})},toggleClass:function(b,d){return this.each(function(e){var f=M(this,b,e,this.className);(d===a?!c(this).hasClass(f):d)?c(this).addClass(f):c(this).removeClass(f)})}},["width","height"].forEach(function(b){c.fn[b]=function(d){var e,f=b.replace(/./,function(a){return a[0].toUpperCase()});return d===a?this[0]==window?window["inner"+f]:this[0]==g?g.documentElement["offset"+f]:(e=this.offset())&&e[b]:this.each(function(a){var e=c(this);e.css(b,M(this,d,a,e[b]()))})}}),n.forEach(function(a,b){c.fn[a]=function(){var a=c.map(arguments,function(a){return B(a)?a:w.fragment(a)});if(a.length<1)return this;var d=this.length,e=d>1,f=b<2;return this.each(function(c,g){for(var h=0;h0&&this.bind(o,n),setTimeout(function(){m.css(i),e<=0&&setTimeout(function(){m.each(function(){n.call(this)})},0)},0),this},i=null}(Zepto),function($){function triggerAndReturn(a,b,c){var d=$.Event(b);return $(a).trigger(d,c),!d.defaultPrevented}function triggerGlobal(a,b,c,d){if(a.global)return triggerAndReturn(b||document,c,d)}function ajaxStart(a){a.global&&$.active++===0&&triggerGlobal(a,null,"ajaxStart")}function ajaxStop(a){a.global&&!--$.active&&triggerGlobal(a,null,"ajaxStop")}function ajaxBeforeSend(a,b){var c=b.context;if(b.beforeSend.call(c,a,b)===!1||triggerGlobal(b,c,"ajaxBeforeSend",[a,b])===!1)return!1;triggerGlobal(b,c,"ajaxSend",[a,b])}function ajaxSuccess(a,b,c){var d=c.context,e="success";c.success.call(d,a,e,b),triggerGlobal(c,d,"ajaxSuccess",[b,c,a]),ajaxComplete(e,b,c)}function ajaxError(a,b,c,d){var e=d.context;d.error.call(e,c,b,a),triggerGlobal(d,e,"ajaxError",[c,d,a]),ajaxComplete(b,c,d)}function ajaxComplete(a,b,c){var d=c.context;c.complete.call(d,b,a),triggerGlobal(c,d,"ajaxComplete",[b,c]),ajaxStop(c)}function empty(){}function mimeToDataType(a){return a&&(a==htmlType?"html":a==jsonType?"json":scriptTypeRE.test(a)?"script":xmlTypeRE.test(a)&&"xml")||"text"}function appendQuery(a,b){return(a+"&"+b).replace(/[&?]{1,2}/,"?")}function serializeData(a){isObject(a.data)&&(a.data=$.param(a.data)),a.data&&(!a.type||a.type.toUpperCase()=="GET")&&(a.url=appendQuery(a.url,a.data))}function serialize(a,b,c,d){var e=$.isArray(b);$.each(b,function(b,f){d&&(b=c?d:d+"["+(e?"":b)+"]"),!d&&e?a.add(f.name,f.value):(c?$.isArray(f):isObject(f))?serialize(a,f,c,b):a.add(b,f)})}var jsonpID=0,isObject=$.isObject,document=window.document,key,name,rscript=/)<[^<]*)*<\/script>/gi,scriptTypeRE=/^(?:text|application)\/javascript/i,xmlTypeRE=/^(?:text|application)\/xml/i,jsonType="application/json",htmlType="text/html",blankRE=/^\s*$/;$.active=0,$.ajaxJSONP=function(a){var b="jsonp"+ ++jsonpID,c=document.createElement("script"),d=function(){$(c).remove(),b in window&&(window[b]=empty),ajaxComplete("abort",e,a)},e={abort:d},f;return a.error&&(c.onerror=function(){e.abort(),a.error()}),window[b]=function(d){clearTimeout(f),$(c).remove(),delete window[b],ajaxSuccess(d,e,a)},serializeData(a),c.src=a.url.replace(/=\?/,"="+b),$("head").append(c),a.timeout>0&&(f=setTimeout(function(){e.abort(),ajaxComplete("timeout",e,a)},a.timeout)),e},$.ajaxSettings={type:"GET",beforeSend:empty,success:empty,error:empty,complete:empty,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript",json:jsonType,xml:"application/xml, text/xml",html:htmlType,text:"text/plain"},crossDomain:!1,timeout:0},$.ajax=function(options){var settings=$.extend({},options||{});for(key in $.ajaxSettings)settings[key]===undefined&&(settings[key]=$.ajaxSettings[key]);ajaxStart(settings),settings.crossDomain||(settings.crossDomain=/^([\w-]+:)?\/\/([^\/]+)/.test(settings.url)&&RegExp.$2!=window.location.host);var dataType=settings.dataType,hasPlaceholder=/=\?/.test(settings.url);if(dataType=="jsonp"||hasPlaceholder)return hasPlaceholder||(settings.url=appendQuery(settings.url,"callback=?")),$.ajaxJSONP(settings);settings.url||(settings.url=window.location.toString()),serializeData(settings);var mime=settings.accepts[dataType],baseHeaders={},protocol=/^([\w-]+:)\/\//.test(settings.url)?RegExp.$1:window.location.protocol,xhr=$.ajaxSettings.xhr(),abortTimeout;settings.crossDomain||(baseHeaders["X-Requested-With"]="XMLHttpRequest"),mime&&(baseHeaders.Accept=mime,mime.indexOf(",")>-1&&(mime=mime.split(",",2)[0]),xhr.overrideMimeType&&xhr.overrideMimeType(mime));if(settings.contentType||settings.data&&settings.type.toUpperCase()!="GET")baseHeaders["Content-Type"]=settings.contentType||"application/x-www-form-urlencoded";settings.headers=$.extend(baseHeaders,settings.headers||{}),xhr.onreadystatechange=function(){if(xhr.readyState==4){clearTimeout(abortTimeout);var result,error=!1;if(xhr.status>=200&&xhr.status<300||xhr.status==304||xhr.status==0&&protocol=="file:"){dataType=dataType||mimeToDataType(xhr.getResponseHeader("content-type")),result=xhr.responseText;try{dataType=="script"?(1,eval)(result):dataType=="xml"?result=xhr.responseXML:dataType=="json"&&(result=blankRE.test(result)?null:JSON.parse(result))}catch(e){error=e}error?ajaxError(error,"parsererror",xhr,settings):ajaxSuccess(result,xhr,settings)}else ajaxError(null,"error",xhr,settings)}};var async="async"in settings?settings.async:!0;xhr.open(settings.type,settings.url,async);for(name in settings.headers)xhr.setRequestHeader(name,settings.headers[name]);return ajaxBeforeSend(xhr,settings)===!1?(xhr.abort(),!1):(settings.timeout>0&&(abortTimeout=setTimeout(function(){xhr.onreadystatechange=empty,xhr.abort(),ajaxError(null,"timeout",xhr,settings)},settings.timeout)),xhr.send(settings.data?settings.data:null),xhr)},$.get=function(a,b){return $.ajax({url:a,success:b})},$.post=function(a,b,c,d){return $.isFunction(b)&&(d=d||c,c=b,b=null),$.ajax({type:"POST",url:a,data:b,success:c,dataType:d})},$.getJSON=function(a,b){return $.ajax({url:a,success:b,dataType:"json"})},$.fn.load=function(a,b){if(!this.length)return this;var c=this,d=a.split(/\s/),e;return d.length>1&&(a=d[0],e=d[1]),$.get(a,function(a){c.html(e?$(document.createElement("div")).html(a.replace(rscript,"")).find(e).html():a),b&&b.call(c)}),this};var escape=encodeURIComponent;$.param=function(a,b){var c=[];return c.add=function(a,b){this.push(escape(a)+"="+escape(b))},serialize(c,a,b),c.join("&").replace("%20","+")}}(Zepto),function(a){a.fn.serializeArray=function(){var b=[],c;return a(Array.prototype.slice.call(this.get(0).elements)).each(function(){c=a(this);var d=c.attr("type");this.nodeName.toLowerCase()!="fieldset"&&!this.disabled&&d!="submit"&&d!="reset"&&d!="button"&&(d!="radio"&&d!="checkbox"||this.checked)&&b.push({name:c.attr("name"),value:c.val()})}),b},a.fn.serialize=function(){var a=[];return this.serializeArray().forEach(function(b){a.push(encodeURIComponent(b.name)+"="+encodeURIComponent(b.value))}),a.join("&")},a.fn.submit=function(b){if(b)this.bind("submit",b);else if(this.length){var c=a.Event("submit");this.eq(0).trigger(c),c.defaultPrevented||this.get(0).submit()}return this}}(Zepto),function(a){function d(a){return"tagName"in a?a:a.parentNode}function e(a,b,c,d){var e=Math.abs(a-b),f=Math.abs(c-d);return e>=f?a-b>0?"Left":"Right":c-d>0?"Up":"Down"}function h(){g=null,b.last&&(b.el.trigger("longTap"),b={})}function i(){g&&clearTimeout(g),g=null}var b={},c,f=750,g;a(document).ready(function(){var j,k;a(document.body).bind("touchstart",function(e){j=Date.now(),k=j-(b.last||j),b.el=a(d(e.touches[0].target)),c&&clearTimeout(c),b.x1=e.touches[0].pageX,b.y1=e.touches[0].pageY,k>0&&k<=250&&(b.isDoubleTap=!0),b.last=j,g=setTimeout(h,f)}).bind("touchmove",function(a){i(),b.x2=a.touches[0].pageX,b.y2=a.touches[0].pageY}).bind("touchend",function(a){i(),b.isDoubleTap?(b.el.trigger("doubleTap"),b={}):b.x2&&Math.abs(b.x1-b.x2)>30||b.y2&&Math.abs(b.y1-b.y2)>30?(b.el.trigger("swipe")&&b.el.trigger("swipe"+e(b.x1,b.x2,b.y1,b.y2)),b={}):"last"in b&&(b.el.trigger("tap"),c=setTimeout(function(){c=null,b.el.trigger("singleTap"),b={}},250))}).bind("touchcancel",function(){c&&clearTimeout(c),g&&clearTimeout(g),g=c=null,b={}})}),["swipe","swipeLeft","swipeRight","swipeUp","swipeDown","doubleTap","tap","singleTap","longTap"].forEach(function(b){a.fn[b]=function(a){return this.bind(b,a)}})}(Zepto); -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-touch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.2.28 3 | * (c) 2010-2014 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) {'use strict'; 7 | 8 | /** 9 | * @ngdoc module 10 | * @name ngTouch 11 | * @description 12 | * 13 | * # ngTouch 14 | * 15 | * The `ngTouch` module provides touch events and other helpers for touch-enabled devices. 16 | * The implementation is based on jQuery Mobile touch event handling 17 | * ([jquerymobile.com](http://jquerymobile.com/)). 18 | * 19 | * 20 | * See {@link ngTouch.$swipe `$swipe`} for usage. 21 | * 22 | *
23 | * 24 | */ 25 | 26 | // define ngTouch module 27 | /* global -ngTouch */ 28 | var ngTouch = angular.module('ngTouch', []); 29 | 30 | /* global ngTouch: false */ 31 | 32 | /** 33 | * @ngdoc service 34 | * @name $swipe 35 | * 36 | * @description 37 | * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe 38 | * behavior, to make implementing swipe-related directives more convenient. 39 | * 40 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 41 | * 42 | * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by 43 | * `ngCarousel` in a separate component. 44 | * 45 | * # Usage 46 | * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element 47 | * which is to be watched for swipes, and an object with four handler functions. See the 48 | * documentation for `bind` below. 49 | */ 50 | 51 | ngTouch.factory('$swipe', [function() { 52 | // The total distance in any direction before we make the call on swipe vs. scroll. 53 | var MOVE_BUFFER_RADIUS = 10; 54 | 55 | function getCoordinates(event) { 56 | var touches = event.touches && event.touches.length ? event.touches : [event]; 57 | var e = (event.changedTouches && event.changedTouches[0]) || 58 | (event.originalEvent && event.originalEvent.changedTouches && 59 | event.originalEvent.changedTouches[0]) || 60 | touches[0].originalEvent || touches[0]; 61 | 62 | return { 63 | x: e.clientX, 64 | y: e.clientY 65 | }; 66 | } 67 | 68 | return { 69 | /** 70 | * @ngdoc method 71 | * @name $swipe#bind 72 | * 73 | * @description 74 | * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an 75 | * object containing event handlers. 76 | * 77 | * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end` 78 | * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`. 79 | * 80 | * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is 81 | * watching for `touchmove` or `mousemove` events. These events are ignored until the total 82 | * distance moved in either dimension exceeds a small threshold. 83 | * 84 | * Once this threshold is exceeded, either the horizontal or vertical delta is greater. 85 | * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow. 86 | * - If the vertical distance is greater, this is a scroll, and we let the browser take over. 87 | * A `cancel` event is sent. 88 | * 89 | * `move` is called on `mousemove` and `touchmove` after the above logic has determined that 90 | * a swipe is in progress. 91 | * 92 | * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`. 93 | * 94 | * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling 95 | * as described above. 96 | * 97 | */ 98 | bind: function(element, eventHandlers) { 99 | // Absolute total movement, used to control swipe vs. scroll. 100 | var totalX, totalY; 101 | // Coordinates of the start position. 102 | var startCoords; 103 | // Last event's position. 104 | var lastPos; 105 | // Whether a swipe is active. 106 | var active = false; 107 | 108 | element.on('touchstart mousedown', function(event) { 109 | startCoords = getCoordinates(event); 110 | active = true; 111 | totalX = 0; 112 | totalY = 0; 113 | lastPos = startCoords; 114 | eventHandlers['start'] && eventHandlers['start'](startCoords, event); 115 | }); 116 | 117 | element.on('touchcancel', function(event) { 118 | active = false; 119 | eventHandlers['cancel'] && eventHandlers['cancel'](event); 120 | }); 121 | 122 | element.on('touchmove mousemove', function(event) { 123 | if (!active) return; 124 | 125 | // Android will send a touchcancel if it thinks we're starting to scroll. 126 | // So when the total distance (+ or - or both) exceeds 10px in either direction, 127 | // we either: 128 | // - On totalX > totalY, we send preventDefault() and treat this as a swipe. 129 | // - On totalY > totalX, we let the browser handle it as a scroll. 130 | 131 | if (!startCoords) return; 132 | var coords = getCoordinates(event); 133 | 134 | totalX += Math.abs(coords.x - lastPos.x); 135 | totalY += Math.abs(coords.y - lastPos.y); 136 | 137 | lastPos = coords; 138 | 139 | if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) { 140 | return; 141 | } 142 | 143 | // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll. 144 | if (totalY > totalX) { 145 | // Allow native scrolling to take over. 146 | active = false; 147 | eventHandlers['cancel'] && eventHandlers['cancel'](event); 148 | return; 149 | } else { 150 | // Prevent the browser from scrolling. 151 | event.preventDefault(); 152 | eventHandlers['move'] && eventHandlers['move'](coords, event); 153 | } 154 | }); 155 | 156 | element.on('touchend mouseup', function(event) { 157 | if (!active) return; 158 | active = false; 159 | eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event); 160 | }); 161 | } 162 | }; 163 | }]); 164 | 165 | /* global ngTouch: false */ 166 | 167 | /** 168 | * @ngdoc directive 169 | * @name ngClick 170 | * 171 | * @description 172 | * A more powerful replacement for the default ngClick designed to be used on touchscreen 173 | * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending 174 | * the click event. This version handles them immediately, and then prevents the 175 | * following click event from propagating. 176 | * 177 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 178 | * 179 | * This directive can fall back to using an ordinary click event, and so works on desktop 180 | * browsers as well as mobile. 181 | * 182 | * This directive also sets the CSS class `ng-click-active` while the element is being held 183 | * down (by a mouse click or touch) so you can restyle the depressed element if you wish. 184 | * 185 | * @element ANY 186 | * @param {expression} ngClick {@link guide/expression Expression} to evaluate 187 | * upon tap. (Event object is available as `$event`) 188 | * 189 | * @example 190 | 191 | 192 | 195 | count: {{ count }} 196 | 197 | 198 | angular.module('ngClickExample', ['ngTouch']); 199 | 200 | 201 | */ 202 | 203 | ngTouch.config(['$provide', function($provide) { 204 | $provide.decorator('ngClickDirective', ['$delegate', function($delegate) { 205 | // drop the default ngClick directive 206 | $delegate.shift(); 207 | return $delegate; 208 | }]); 209 | }]); 210 | 211 | ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement', 212 | function($parse, $timeout, $rootElement) { 213 | var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag. 214 | var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers. 215 | var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click 216 | var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks. 217 | 218 | var ACTIVE_CLASS_NAME = 'ng-click-active'; 219 | var lastPreventedTime; 220 | var touchCoordinates; 221 | var lastLabelClickCoordinates; 222 | 223 | 224 | // TAP EVENTS AND GHOST CLICKS 225 | // 226 | // Why tap events? 227 | // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're 228 | // double-tapping, and then fire a click event. 229 | // 230 | // This delay sucks and makes mobile apps feel unresponsive. 231 | // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when 232 | // the user has tapped on something. 233 | // 234 | // What happens when the browser then generates a click event? 235 | // The browser, of course, also detects the tap and fires a click after a delay. This results in 236 | // tapping/clicking twice. We do "clickbusting" to prevent it. 237 | // 238 | // How does it work? 239 | // We attach global touchstart and click handlers, that run during the capture (early) phase. 240 | // So the sequence for a tap is: 241 | // - global touchstart: Sets an "allowable region" at the point touched. 242 | // - element's touchstart: Starts a touch 243 | // (- touchmove or touchcancel ends the touch, no click follows) 244 | // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold 245 | // too long) and fires the user's tap handler. The touchend also calls preventGhostClick(). 246 | // - preventGhostClick() removes the allowable region the global touchstart created. 247 | // - The browser generates a click event. 248 | // - The global click handler catches the click, and checks whether it was in an allowable region. 249 | // - If preventGhostClick was called, the region will have been removed, the click is busted. 250 | // - If the region is still there, the click proceeds normally. Therefore clicks on links and 251 | // other elements without ngTap on them work normally. 252 | // 253 | // This is an ugly, terrible hack! 254 | // Yeah, tell me about it. The alternatives are using the slow click events, or making our users 255 | // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular 256 | // encapsulates this ugly logic away from the user. 257 | // 258 | // Why not just put click handlers on the element? 259 | // We do that too, just to be sure. If the tap event caused the DOM to change, 260 | // it is possible another element is now in that position. To take account for these possibly 261 | // distinct elements, the handlers are global and care only about coordinates. 262 | 263 | // Checks if the coordinates are close enough to be within the region. 264 | function hit(x1, y1, x2, y2) { 265 | return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD; 266 | } 267 | 268 | // Checks a list of allowable regions against a click location. 269 | // Returns true if the click should be allowed. 270 | // Splices out the allowable region from the list after it has been used. 271 | function checkAllowableRegions(touchCoordinates, x, y) { 272 | for (var i = 0; i < touchCoordinates.length; i += 2) { 273 | if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) { 274 | touchCoordinates.splice(i, i + 2); 275 | return true; // allowable region 276 | } 277 | } 278 | return false; // No allowable region; bust it. 279 | } 280 | 281 | // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick 282 | // was called recently. 283 | function onClick(event) { 284 | if (Date.now() - lastPreventedTime > PREVENT_DURATION) { 285 | return; // Too old. 286 | } 287 | 288 | var touches = event.touches && event.touches.length ? event.touches : [event]; 289 | var x = touches[0].clientX; 290 | var y = touches[0].clientY; 291 | // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label 292 | // and on the input element). Depending on the exact browser, this second click we don't want 293 | // to bust has either (0,0), negative coordinates, or coordinates equal to triggering label 294 | // click event 295 | if (x < 1 && y < 1) { 296 | return; // offscreen 297 | } 298 | if (lastLabelClickCoordinates && 299 | lastLabelClickCoordinates[0] === x && lastLabelClickCoordinates[1] === y) { 300 | return; // input click triggered by label click 301 | } 302 | // reset label click coordinates on first subsequent click 303 | if (lastLabelClickCoordinates) { 304 | lastLabelClickCoordinates = null; 305 | } 306 | // remember label click coordinates to prevent click busting of trigger click event on input 307 | if (event.target.tagName.toLowerCase() === 'label') { 308 | lastLabelClickCoordinates = [x, y]; 309 | } 310 | 311 | // Look for an allowable region containing this click. 312 | // If we find one, that means it was created by touchstart and not removed by 313 | // preventGhostClick, so we don't bust it. 314 | if (checkAllowableRegions(touchCoordinates, x, y)) { 315 | return; 316 | } 317 | 318 | // If we didn't find an allowable region, bust the click. 319 | event.stopPropagation(); 320 | event.preventDefault(); 321 | 322 | // Blur focused form elements 323 | event.target && event.target.blur(); 324 | } 325 | 326 | 327 | // Global touchstart handler that creates an allowable region for a click event. 328 | // This allowable region can be removed by preventGhostClick if we want to bust it. 329 | function onTouchStart(event) { 330 | var touches = event.touches && event.touches.length ? event.touches : [event]; 331 | var x = touches[0].clientX; 332 | var y = touches[0].clientY; 333 | touchCoordinates.push(x, y); 334 | 335 | $timeout(function() { 336 | // Remove the allowable region. 337 | for (var i = 0; i < touchCoordinates.length; i += 2) { 338 | if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) { 339 | touchCoordinates.splice(i, i + 2); 340 | return; 341 | } 342 | } 343 | }, PREVENT_DURATION, false); 344 | } 345 | 346 | // On the first call, attaches some event handlers. Then whenever it gets called, it creates a 347 | // zone around the touchstart where clicks will get busted. 348 | function preventGhostClick(x, y) { 349 | if (!touchCoordinates) { 350 | $rootElement[0].addEventListener('click', onClick, true); 351 | $rootElement[0].addEventListener('touchstart', onTouchStart, true); 352 | touchCoordinates = []; 353 | } 354 | 355 | lastPreventedTime = Date.now(); 356 | 357 | checkAllowableRegions(touchCoordinates, x, y); 358 | } 359 | 360 | // Actual linking function. 361 | return function(scope, element, attr) { 362 | var clickHandler = $parse(attr.ngClick), 363 | tapping = false, 364 | tapElement, // Used to blur the element after a tap. 365 | startTime, // Used to check if the tap was held too long. 366 | touchStartX, 367 | touchStartY; 368 | 369 | function resetState() { 370 | tapping = false; 371 | element.removeClass(ACTIVE_CLASS_NAME); 372 | } 373 | 374 | element.on('touchstart', function(event) { 375 | tapping = true; 376 | tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement. 377 | // Hack for Safari, which can target text nodes instead of containers. 378 | if(tapElement.nodeType == 3) { 379 | tapElement = tapElement.parentNode; 380 | } 381 | 382 | element.addClass(ACTIVE_CLASS_NAME); 383 | 384 | startTime = Date.now(); 385 | 386 | var touches = event.touches && event.touches.length ? event.touches : [event]; 387 | var e = touches[0].originalEvent || touches[0]; 388 | touchStartX = e.clientX; 389 | touchStartY = e.clientY; 390 | }); 391 | 392 | element.on('touchmove', function(event) { 393 | resetState(); 394 | }); 395 | 396 | element.on('touchcancel', function(event) { 397 | resetState(); 398 | }); 399 | 400 | element.on('touchend', function(event) { 401 | var diff = Date.now() - startTime; 402 | 403 | var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches : 404 | ((event.touches && event.touches.length) ? event.touches : [event]); 405 | var e = touches[0].originalEvent || touches[0]; 406 | var x = e.clientX; 407 | var y = e.clientY; 408 | var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) ); 409 | 410 | if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) { 411 | // Call preventGhostClick so the clickbuster will catch the corresponding click. 412 | preventGhostClick(x, y); 413 | 414 | // Blur the focused element (the button, probably) before firing the callback. 415 | // This doesn't work perfectly on Android Chrome, but seems to work elsewhere. 416 | // I couldn't get anything to work reliably on Android Chrome. 417 | if (tapElement) { 418 | tapElement.blur(); 419 | } 420 | 421 | if (!angular.isDefined(attr.disabled) || attr.disabled === false) { 422 | element.triggerHandler('click', [event]); 423 | } 424 | } 425 | 426 | resetState(); 427 | }); 428 | 429 | // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click 430 | // something else nearby. 431 | element.onclick = function(event) { }; 432 | 433 | // Actual click handler. 434 | // There are three different kinds of clicks, only two of which reach this point. 435 | // - On desktop browsers without touch events, their clicks will always come here. 436 | // - On mobile browsers, the simulated "fast" click will call this. 437 | // - But the browser's follow-up slow click will be "busted" before it reaches this handler. 438 | // Therefore it's safe to use this directive on both mobile and desktop. 439 | element.on('click', function(event, touchend) { 440 | scope.$apply(function() { 441 | clickHandler(scope, {$event: (touchend || event)}); 442 | }); 443 | }); 444 | 445 | element.on('mousedown', function(event) { 446 | element.addClass(ACTIVE_CLASS_NAME); 447 | }); 448 | 449 | element.on('mousemove mouseup', function(event) { 450 | element.removeClass(ACTIVE_CLASS_NAME); 451 | }); 452 | 453 | }; 454 | }]); 455 | 456 | /* global ngTouch: false */ 457 | 458 | /** 459 | * @ngdoc directive 460 | * @name ngSwipeLeft 461 | * 462 | * @description 463 | * Specify custom behavior when an element is swiped to the left on a touchscreen device. 464 | * A leftward swipe is a quick, right-to-left slide of the finger. 465 | * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag 466 | * too. 467 | * 468 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 469 | * 470 | * @element ANY 471 | * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate 472 | * upon left swipe. (Event object is available as `$event`) 473 | * 474 | * @example 475 | 476 | 477 |
478 | Some list content, like an email in the inbox 479 |
480 |
481 | 482 | 483 |
484 |
485 | 486 | angular.module('ngSwipeLeftExample', ['ngTouch']); 487 | 488 |
489 | */ 490 | 491 | /** 492 | * @ngdoc directive 493 | * @name ngSwipeRight 494 | * 495 | * @description 496 | * Specify custom behavior when an element is swiped to the right on a touchscreen device. 497 | * A rightward swipe is a quick, left-to-right slide of the finger. 498 | * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag 499 | * too. 500 | * 501 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 502 | * 503 | * @element ANY 504 | * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate 505 | * upon right swipe. (Event object is available as `$event`) 506 | * 507 | * @example 508 | 509 | 510 |
511 | Some list content, like an email in the inbox 512 |
513 |
514 | 515 | 516 |
517 |
518 | 519 | angular.module('ngSwipeRightExample', ['ngTouch']); 520 | 521 |
522 | */ 523 | 524 | function makeSwipeDirective(directiveName, direction, eventName) { 525 | ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) { 526 | // The maximum vertical delta for a swipe should be less than 75px. 527 | var MAX_VERTICAL_DISTANCE = 75; 528 | // Vertical distance should not be more than a fraction of the horizontal distance. 529 | var MAX_VERTICAL_RATIO = 0.3; 530 | // At least a 30px lateral motion is necessary for a swipe. 531 | var MIN_HORIZONTAL_DISTANCE = 30; 532 | 533 | return function(scope, element, attr) { 534 | var swipeHandler = $parse(attr[directiveName]); 535 | 536 | var startCoords, valid; 537 | 538 | function validSwipe(coords) { 539 | // Check that it's within the coordinates. 540 | // Absolute vertical distance must be within tolerances. 541 | // Horizontal distance, we take the current X - the starting X. 542 | // This is negative for leftward swipes and positive for rightward swipes. 543 | // After multiplying by the direction (-1 for left, +1 for right), legal swipes 544 | // (ie. same direction as the directive wants) will have a positive delta and 545 | // illegal ones a negative delta. 546 | // Therefore this delta must be positive, and larger than the minimum. 547 | if (!startCoords) return false; 548 | var deltaY = Math.abs(coords.y - startCoords.y); 549 | var deltaX = (coords.x - startCoords.x) * direction; 550 | return valid && // Short circuit for already-invalidated swipes. 551 | deltaY < MAX_VERTICAL_DISTANCE && 552 | deltaX > 0 && 553 | deltaX > MIN_HORIZONTAL_DISTANCE && 554 | deltaY / deltaX < MAX_VERTICAL_RATIO; 555 | } 556 | 557 | $swipe.bind(element, { 558 | 'start': function(coords, event) { 559 | startCoords = coords; 560 | valid = true; 561 | }, 562 | 'cancel': function(event) { 563 | valid = false; 564 | }, 565 | 'end': function(coords, event) { 566 | if (validSwipe(coords)) { 567 | scope.$apply(function() { 568 | element.triggerHandler(eventName); 569 | swipeHandler(scope, {$event: event}); 570 | }); 571 | } 572 | } 573 | }); 574 | }; 575 | }]); 576 | } 577 | 578 | // Left is negative X-coordinate, right is positive. 579 | makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft'); 580 | makeSwipeDirective('ngSwipeRight', 1, 'swiperight'); 581 | 582 | 583 | 584 | })(window, window.angular); 585 | -------------------------------------------------------------------------------- /web/static/js/lib/angular/angular-sanitize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.2.28 3 | * (c) 2010-2014 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) {'use strict'; 7 | 8 | var $sanitizeMinErr = angular.$$minErr('$sanitize'); 9 | 10 | /** 11 | * @ngdoc module 12 | * @name ngSanitize 13 | * @description 14 | * 15 | * # ngSanitize 16 | * 17 | * The `ngSanitize` module provides functionality to sanitize HTML. 18 | * 19 | * 20 | *
21 | * 22 | * See {@link ngSanitize.$sanitize `$sanitize`} for usage. 23 | */ 24 | 25 | /* 26 | * HTML Parser By Misko Hevery (misko@hevery.com) 27 | * based on: HTML Parser By John Resig (ejohn.org) 28 | * Original code by Erik Arvidsson, Mozilla Public License 29 | * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js 30 | * 31 | * // Use like so: 32 | * htmlParser(htmlString, { 33 | * start: function(tag, attrs, unary) {}, 34 | * end: function(tag) {}, 35 | * chars: function(text) {}, 36 | * comment: function(text) {} 37 | * }); 38 | * 39 | */ 40 | 41 | 42 | /** 43 | * @ngdoc service 44 | * @name $sanitize 45 | * @kind function 46 | * 47 | * @description 48 | * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are 49 | * then serialized back to properly escaped html string. This means that no unsafe input can make 50 | * it into the returned string, however, since our parser is more strict than a typical browser 51 | * parser, it's possible that some obscure input, which would be recognized as valid HTML by a 52 | * browser, won't make it through the sanitizer. 53 | * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and 54 | * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}. 55 | * 56 | * @param {string} html Html input. 57 | * @returns {string} Sanitized html. 58 | * 59 | * @example 60 | 61 | 62 | 74 |
75 | Snippet: 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 |
DirectiveHowSourceRendered
ng-bind-htmlAutomatically uses $sanitize
<div ng-bind-html="snippet">
</div>
ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value 93 |
<div ng-bind-html="deliberatelyTrustDangerousSnippet()">
 94 | </div>
95 |
ng-bindAutomatically escapes
<div ng-bind="snippet">
</div>
105 |
106 |
107 | 108 | it('should sanitize the html snippet by default', function() { 109 | expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). 110 | toBe('

an html\nclick here\nsnippet

'); 111 | }); 112 | 113 | it('should inline raw snippet if bound to a trusted value', function() { 114 | expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()). 115 | toBe("

an html\n" + 116 | "click here\n" + 117 | "snippet

"); 118 | }); 119 | 120 | it('should escape snippet without any filter', function() { 121 | expect(element(by.css('#bind-default div')).getInnerHtml()). 122 | toBe("<p style=\"color:blue\">an html\n" + 123 | "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + 124 | "snippet</p>"); 125 | }); 126 | 127 | it('should update', function() { 128 | element(by.model('snippet')).clear(); 129 | element(by.model('snippet')).sendKeys('new text'); 130 | expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). 131 | toBe('new text'); 132 | expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe( 133 | 'new text'); 134 | expect(element(by.css('#bind-default div')).getInnerHtml()).toBe( 135 | "new <b onclick=\"alert(1)\">text</b>"); 136 | }); 137 |
138 |
139 | */ 140 | function $SanitizeProvider() { 141 | this.$get = ['$$sanitizeUri', function($$sanitizeUri) { 142 | return function(html) { 143 | var buf = []; 144 | htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { 145 | return !/^unsafe/.test($$sanitizeUri(uri, isImage)); 146 | })); 147 | return buf.join(''); 148 | }; 149 | }]; 150 | } 151 | 152 | function sanitizeText(chars) { 153 | var buf = []; 154 | var writer = htmlSanitizeWriter(buf, angular.noop); 155 | writer.chars(chars); 156 | return buf.join(''); 157 | } 158 | 159 | 160 | // Regular Expressions for parsing tags and attributes 161 | var START_TAG_REGEXP = 162 | /^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/, 163 | END_TAG_REGEXP = /^<\/\s*([\w:-]+)[^>]*>/, 164 | ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, 165 | BEGIN_TAG_REGEXP = /^/g, 168 | DOCTYPE_REGEXP = /]*?)>/i, 169 | CDATA_REGEXP = //g, 170 | SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 171 | // Match everything outside of normal chars and " (quote character) 172 | NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; 173 | 174 | 175 | // Good source of info about elements and attributes 176 | // http://dev.w3.org/html5/spec/Overview.html#semantics 177 | // http://simon.html5.org/html-elements 178 | 179 | // Safe Void Elements - HTML5 180 | // http://dev.w3.org/html5/spec/Overview.html#void-elements 181 | var voidElements = makeMap("area,br,col,hr,img,wbr"); 182 | 183 | // Elements that you can, intentionally, leave open (and which close themselves) 184 | // http://dev.w3.org/html5/spec/Overview.html#optional-tags 185 | var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"), 186 | optionalEndTagInlineElements = makeMap("rp,rt"), 187 | optionalEndTagElements = angular.extend({}, 188 | optionalEndTagInlineElements, 189 | optionalEndTagBlockElements); 190 | 191 | // Safe Block Elements - HTML5 192 | var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," + 193 | "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," + 194 | "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")); 195 | 196 | // Inline Elements - HTML5 197 | var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," + 198 | "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," + 199 | "samp,small,span,strike,strong,sub,sup,time,tt,u,var")); 200 | 201 | 202 | // Special Elements (can contain anything) 203 | var specialElements = makeMap("script,style"); 204 | 205 | var validElements = angular.extend({}, 206 | voidElements, 207 | blockElements, 208 | inlineElements, 209 | optionalEndTagElements); 210 | 211 | //Attributes that have href and hence need to be sanitized 212 | var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap"); 213 | var validAttrs = angular.extend({}, uriAttrs, makeMap( 214 | 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+ 215 | 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+ 216 | 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+ 217 | 'scope,scrolling,shape,size,span,start,summary,target,title,type,'+ 218 | 'valign,value,vspace,width')); 219 | 220 | function makeMap(str) { 221 | var obj = {}, items = str.split(','), i; 222 | for (i = 0; i < items.length; i++) obj[items[i]] = true; 223 | return obj; 224 | } 225 | 226 | 227 | /** 228 | * @example 229 | * htmlParser(htmlString, { 230 | * start: function(tag, attrs, unary) {}, 231 | * end: function(tag) {}, 232 | * chars: function(text) {}, 233 | * comment: function(text) {} 234 | * }); 235 | * 236 | * @param {string} html string 237 | * @param {object} handler 238 | */ 239 | function htmlParser( html, handler ) { 240 | if (typeof html !== 'string') { 241 | if (html === null || typeof html === 'undefined') { 242 | html = ''; 243 | } else { 244 | html = '' + html; 245 | } 246 | } 247 | var index, chars, match, stack = [], last = html, text; 248 | stack.last = function() { return stack[ stack.length - 1 ]; }; 249 | 250 | while ( html ) { 251 | text = ''; 252 | chars = true; 253 | 254 | // Make sure we're not in a script or style element 255 | if ( !stack.last() || !specialElements[ stack.last() ] ) { 256 | 257 | // Comment 258 | if ( html.indexOf("", index) === index) { 263 | if (handler.comment) handler.comment( html.substring( 4, index ) ); 264 | html = html.substring( index + 3 ); 265 | chars = false; 266 | } 267 | // DOCTYPE 268 | } else if ( DOCTYPE_REGEXP.test(html) ) { 269 | match = html.match( DOCTYPE_REGEXP ); 270 | 271 | if ( match ) { 272 | html = html.replace( match[0], ''); 273 | chars = false; 274 | } 275 | // end tag 276 | } else if ( BEGING_END_TAGE_REGEXP.test(html) ) { 277 | match = html.match( END_TAG_REGEXP ); 278 | 279 | if ( match ) { 280 | html = html.substring( match[0].length ); 281 | match[0].replace( END_TAG_REGEXP, parseEndTag ); 282 | chars = false; 283 | } 284 | 285 | // start tag 286 | } else if ( BEGIN_TAG_REGEXP.test(html) ) { 287 | match = html.match( START_TAG_REGEXP ); 288 | 289 | if ( match ) { 290 | // We only have a valid start-tag if there is a '>'. 291 | if ( match[4] ) { 292 | html = html.substring( match[0].length ); 293 | match[0].replace( START_TAG_REGEXP, parseStartTag ); 294 | } 295 | chars = false; 296 | } else { 297 | // no ending tag found --- this piece should be encoded as an entity. 298 | text += '<'; 299 | html = html.substring(1); 300 | } 301 | } 302 | 303 | if ( chars ) { 304 | index = html.indexOf("<"); 305 | 306 | text += index < 0 ? html : html.substring( 0, index ); 307 | html = index < 0 ? "" : html.substring( index ); 308 | 309 | if (handler.chars) handler.chars( decodeEntities(text) ); 310 | } 311 | 312 | } else { 313 | html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'), 314 | function(all, text){ 315 | text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1"); 316 | 317 | if (handler.chars) handler.chars( decodeEntities(text) ); 318 | 319 | return ""; 320 | }); 321 | 322 | parseEndTag( "", stack.last() ); 323 | } 324 | 325 | if ( html == last ) { 326 | throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " + 327 | "of html: {0}", html); 328 | } 329 | last = html; 330 | } 331 | 332 | // Clean up any remaining tags 333 | parseEndTag(); 334 | 335 | function parseStartTag( tag, tagName, rest, unary ) { 336 | tagName = angular.lowercase(tagName); 337 | if ( blockElements[ tagName ] ) { 338 | while ( stack.last() && inlineElements[ stack.last() ] ) { 339 | parseEndTag( "", stack.last() ); 340 | } 341 | } 342 | 343 | if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) { 344 | parseEndTag( "", tagName ); 345 | } 346 | 347 | unary = voidElements[ tagName ] || !!unary; 348 | 349 | if ( !unary ) 350 | stack.push( tagName ); 351 | 352 | var attrs = {}; 353 | 354 | rest.replace(ATTR_REGEXP, 355 | function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) { 356 | var value = doubleQuotedValue 357 | || singleQuotedValue 358 | || unquotedValue 359 | || ''; 360 | 361 | attrs[name] = decodeEntities(value); 362 | }); 363 | if (handler.start) handler.start( tagName, attrs, unary ); 364 | } 365 | 366 | function parseEndTag( tag, tagName ) { 367 | var pos = 0, i; 368 | tagName = angular.lowercase(tagName); 369 | if ( tagName ) 370 | // Find the closest opened tag of the same type 371 | for ( pos = stack.length - 1; pos >= 0; pos-- ) 372 | if ( stack[ pos ] == tagName ) 373 | break; 374 | 375 | if ( pos >= 0 ) { 376 | // Close all the open elements, up the stack 377 | for ( i = stack.length - 1; i >= pos; i-- ) 378 | if (handler.end) handler.end( stack[ i ] ); 379 | 380 | // Remove the open elements from the stack 381 | stack.length = pos; 382 | } 383 | } 384 | } 385 | 386 | var hiddenPre=document.createElement("pre"); 387 | var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/; 388 | /** 389 | * decodes all entities into regular string 390 | * @param value 391 | * @returns {string} A string with decoded entities. 392 | */ 393 | function decodeEntities(value) { 394 | if (!value) { return ''; } 395 | 396 | // Note: IE8 does not preserve spaces at the start/end of innerHTML 397 | // so we must capture them and reattach them afterward 398 | var parts = spaceRe.exec(value); 399 | var spaceBefore = parts[1]; 400 | var spaceAfter = parts[3]; 401 | var content = parts[2]; 402 | if (content) { 403 | hiddenPre.innerHTML=content.replace(//g, '>'); 434 | } 435 | 436 | /** 437 | * create an HTML/XML writer which writes to buffer 438 | * @param {Array} buf use buf.jain('') to get out sanitized html string 439 | * @returns {object} in the form of { 440 | * start: function(tag, attrs, unary) {}, 441 | * end: function(tag) {}, 442 | * chars: function(text) {}, 443 | * comment: function(text) {} 444 | * } 445 | */ 446 | function htmlSanitizeWriter(buf, uriValidator){ 447 | var ignore = false; 448 | var out = angular.bind(buf, buf.push); 449 | return { 450 | start: function(tag, attrs, unary){ 451 | tag = angular.lowercase(tag); 452 | if (!ignore && specialElements[tag]) { 453 | ignore = tag; 454 | } 455 | if (!ignore && validElements[tag] === true) { 456 | out('<'); 457 | out(tag); 458 | angular.forEach(attrs, function(value, key){ 459 | var lkey=angular.lowercase(key); 460 | var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); 461 | if (validAttrs[lkey] === true && 462 | (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { 463 | out(' '); 464 | out(key); 465 | out('="'); 466 | out(encodeEntities(value)); 467 | out('"'); 468 | } 469 | }); 470 | out(unary ? '/>' : '>'); 471 | } 472 | }, 473 | end: function(tag){ 474 | tag = angular.lowercase(tag); 475 | if (!ignore && validElements[tag] === true) { 476 | out(''); 479 | } 480 | if (tag == ignore) { 481 | ignore = false; 482 | } 483 | }, 484 | chars: function(chars){ 485 | if (!ignore) { 486 | out(encodeEntities(chars)); 487 | } 488 | } 489 | }; 490 | } 491 | 492 | 493 | // define ngSanitize module and register $sanitize service 494 | angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); 495 | 496 | /* global sanitizeText: false */ 497 | 498 | /** 499 | * @ngdoc filter 500 | * @name linky 501 | * @kind function 502 | * 503 | * @description 504 | * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and 505 | * plain email address links. 506 | * 507 | * Requires the {@link ngSanitize `ngSanitize`} module to be installed. 508 | * 509 | * @param {string} text Input text. 510 | * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in. 511 | * @returns {string} Html-linkified text. 512 | * 513 | * @usage 514 | 515 | * 516 | * @example 517 | 518 | 519 | 531 |
532 | Snippet: 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 544 | 547 | 548 | 549 | 550 | 553 | 556 | 557 | 558 | 559 | 560 | 561 | 562 |
FilterSourceRendered
linky filter 542 |
<div ng-bind-html="snippet | linky">
</div>
543 |
545 |
546 |
linky target 551 |
<div ng-bind-html="snippetWithTarget | linky:'_blank'">
</div>
552 |
554 |
555 |
no filter
<div ng-bind="snippet">
</div>
563 | 564 | 565 | it('should linkify the snippet with urls', function() { 566 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). 567 | toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + 568 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); 569 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); 570 | }); 571 | 572 | it('should not linkify snippet without the linky filter', function() { 573 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). 574 | toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + 575 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); 576 | expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); 577 | }); 578 | 579 | it('should update', function() { 580 | element(by.model('snippet')).clear(); 581 | element(by.model('snippet')).sendKeys('new http://link.'); 582 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). 583 | toBe('new http://link.'); 584 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); 585 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) 586 | .toBe('new http://link.'); 587 | }); 588 | 589 | it('should work with the target property', function() { 590 | expect(element(by.id('linky-target')). 591 | element(by.binding("snippetWithTarget | linky:'_blank'")).getText()). 592 | toBe('http://angularjs.org/'); 593 | expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); 594 | }); 595 | 596 | 597 | */ 598 | angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { 599 | var LINKY_URL_REGEXP = 600 | /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"]/, 601 | MAILTO_REGEXP = /^mailto:/; 602 | 603 | return function(text, target) { 604 | if (!text) return text; 605 | var match; 606 | var raw = text; 607 | var html = []; 608 | var url; 609 | var i; 610 | while ((match = raw.match(LINKY_URL_REGEXP))) { 611 | // We can not end in these as they are sometimes found at the end of the sentence 612 | url = match[0]; 613 | // if we did not match ftp/http/mailto then assume mailto 614 | if (match[2] == match[3]) url = 'mailto:' + url; 615 | i = match.index; 616 | addText(raw.substr(0, i)); 617 | addLink(url, match[0].replace(MAILTO_REGEXP, '')); 618 | raw = raw.substring(i + match[0].length); 619 | } 620 | addText(raw); 621 | return $sanitize(html.join('')); 622 | 623 | function addText(text) { 624 | if (!text) { 625 | return; 626 | } 627 | html.push(sanitizeText(text)); 628 | } 629 | 630 | function addLink(url, text) { 631 | html.push(''); 640 | addText(text); 641 | html.push(''); 642 | } 643 | }; 644 | }]); 645 | 646 | 647 | })(window, window.angular); 648 | --------------------------------------------------------------------------------